logo

class

compiler::DefaultCtor

sys::Obj
  compiler::CompilerSupport
    compiler::CompilerStep
      compiler::DefaultCtor
  1  //
  2  // Copyright (c) 2006, Brian Frank and Andy Frank
  3  // Licensed under the Academic Free License version 3.0
  4  //
  5  // History:
  6  //    9 Mar 06  Brian Frank  Creation
  7  //   19 Sep 06  Brian Frank  Ported from Java to Fan
  8  //
  9  
 10  **
 11  ** DefaultCtor adds a default public constructor called make()
 12  ** if no constructor was explicitly specified.
 13  **
 14  class DefaultCtor : CompilerStep
 15  {
 16  
 17    new make(Compiler compiler)
 18      : super(compiler)
 19    {
 20    }
 21  
 22    override Void run()
 23    {
 24      log.debug("DefaultCtor")
 25      walk(types, VisitDepth.typeDef)
 26    }
 27  
 28    override Void visitTypeDef(TypeDef t)
 29    {
 30      if (t.isMixin || t.isEnum) return
 31  
 32      hasCtor := t.methodDefs.any |MethodDef m->Bool| { return m.isCtor }
 33      if (hasCtor) return
 34  
 35      // ensure there isn't already a slot called make
 36      dup := t.slots["make"]
 37      if (dup != null)
 38      {
 39        if (dup.parent === t)
 40          err("Default constructor 'make' conflicts with slot at " + dup->location->toLocationStr, t.location)
 41        else
 42          err("Default constructor 'make' conflicts with inherited slot '$dup.qname'", t.location)
 43        return
 44      }
 45  
 46      addDefaultCtor(t, FConst.Public)
 47    }
 48  
 49    static MethodDef addDefaultCtor(TypeDef parent, Int flags)
 50    {
 51      loc := parent.location
 52  
 53      block := Block.make(loc)
 54      block.stmts.add(ReturnStmt.make(loc))
 55  
 56      m := MethodDef.make(loc, parent)
 57      m.flags = flags | FConst.Ctor | FConst.Synthetic
 58      m.name  = "make"
 59      m.ret   = parent.ns.voidType
 60      m.code  = block
 61  
 62      parent.addSlot(m)
 63      return m
 64    }
 65  
 66  }