//
// Copyright (c) 2006, Brian Frank and Andy Frank
// Licensed under the Academic Free License version 3.0
//
// History:
// 9 Mar 06 Brian Frank Creation
// 19 Sep 06 Brian Frank Ported from Java to Fan
//
**
** DefaultCtor adds a default public constructor called make()
** if no constructor was explicitly specified.
**
class DefaultCtor : CompilerStep
{
new make(Compiler compiler)
: super(compiler)
{
}
override Void run()
{
log.debug("DefaultCtor")
walk(compiler, VisitDepth.typeDef)
}
override Void visitTypeDef(TypeDef t)
{
if (t.isMixin || t.isEnum || t.isFacet) return
hasCtor := t.methodDefs.any |MethodDef m->Bool| { m.isInstanceCtor }
if (hasCtor) return
// ensure there isn't already a slot called make
dup := t.slots["make"]
if (dup != null)
{
if (dup.parent === t)
err("Default constructor 'make' conflicts with slot at " + dup->loc->toLocStr, t.loc)
else
err("Default constructor 'make' conflicts with inherited slot '$dup.qname'", t.loc)
return
}
addDefaultCtor(t, FConst.Public)
}
static MethodDef addDefaultCtor(TypeDef parent, Int flags)
{
loc := parent.loc
block := Block(loc)
block.stmts.add(ReturnStmt.makeSynthetic(loc))
m := MethodDef(loc, parent)
m.flags = flags.or(FConst.Ctor + FConst.Synthetic)
m.name = "make"
m.ret = parent.ns.voidType
m.code = block
parent.addSlot(m)
return m
}
}