logo
class

compiler::MethodDef

sys::Obj
  compiler::Node
    compiler::DefNode
      compiler::SlotDef
        compiler::MethodDef

Mixin: compiler::CMethod
   1  //
   2  // Copyright (c) 2006, Brian Frank and Andy Frank
   3  // Licensed under the Academic Free License version 3.0
   4  //
   5  // History:
   6  //   15 Sep 05  Brian Frank  Creation
   7  //   19 Jul 06  Brian Frank  Ported from Java to Fan
   8  //
   9  
  10  **
  11  ** MethodDef models a method definition - it's signature and body.
  12  **
  13  class MethodDef : SlotDef, CMethod
  14  {
  15  
  16  //////////////////////////////////////////////////////////////////////////
  17  // Construction
  18  //////////////////////////////////////////////////////////////////////////
  19  
  20    public static MethodDef makeStaticInit(Location location, TypeDef parent, Block block)
  21    {
  22      def := make(location, parent)
  23      def.name   = "static\$init"
  24      def.flags  = FConst.Public | FConst.Static | FConst.Synthetic
  25      def.ret    = parent.ns.voidType
  26      def.code   = block
  27      return def;
  28    }
  29  
  30    public static MethodDef makeInstanceInit(Location location, TypeDef parent, Block block)
  31    {
  32      def := make(location, parent)
  33      def.name   = "instance\$init";
  34      def.flags  = FConst.Public | FConst.Synthetic
  35      def.ret    = parent.ns.voidType
  36      def.code   = block
  37      return def;
  38    }
  39  
  40    new make(Location location, TypeDef parent)
  41       : super(location, parent)
  42    {
  43      paramDefs = ParamDef[,]
  44      vars = MethodVar[,]
  45      needsCvars = false
  46    }
  47  
  48  //////////////////////////////////////////////////////////////////////////
  49  // Methods
  50  //////////////////////////////////////////////////////////////////////////
  51  
  52    **
  53    ** Return if this a static initializer block.
  54    **
  55    Bool isStaticInit() { return name == "static\$init" }
  56    static Bool isNameStaticInit(Str name) { return name == "static\$init" }
  57  
  58    **
  59    ** Return if this a instance initializer block.
  60    **
  61    Bool isInstanceInit() { return name == "instance\$init" }
  62    static Bool isNameInstanceInit(Str name) { return name == "instance\$init" }
  63  
  64    **
  65    ** Return if getter/setter for FieldDef
  66    **
  67    Bool isFieldAccessor()
  68    {
  69      return accessorFor != null
  70    }
  71  
  72    **
  73    ** Make and add a MethodVar for a local variable.  If name is
  74    ** null then we auto-generate a temporary variable name
  75    **
  76    MethodVar addLocalVar(CType ctype, Str name, Block scope)
  77    {
  78      // allocate next register index, implicit this always register 0
  79      reg := vars.size
  80      if (!isStatic) reg++
  81  
  82      // auto-generate name
  83      if (name == null) name = "\$temp" + reg
  84  
  85      // create variable and add it variable list
  86      var := MethodVar.make(reg, ctype, name, 0, scope)
  87      vars.add(var)
  88      return var
  89    }
  90  
  91  //////////////////////////////////////////////////////////////////////////
  92  // CMethod
  93  //////////////////////////////////////////////////////////////////////////
  94  
  95    override Str signature()
  96    {
  97      return qname + "(" + params.join(",") + ")"
  98    }
  99  
 100    override CType returnType()
 101    {
 102      return ret
 103    }
 104  
 105    override CType inheritedReturnType()
 106    {
 107      if (inheritedRet != null)
 108        return inheritedRet
 109      else
 110        return ret
 111    }
 112  
 113    override CParam[] params()
 114    {
 115      return paramDefs
 116    }
 117  
 118  //////////////////////////////////////////////////////////////////////////
 119  // Tree
 120  //////////////////////////////////////////////////////////////////////////
 121  
 122    override Void walk(Visitor v, VisitDepth depth)
 123    {
 124      v.enterMethodDef(this)
 125      walkFacets(v, depth)
 126      if (depth >= VisitDepth.stmt)
 127      {
 128        if (depth >= VisitDepth.expr)
 129        {
 130          if (ctorChain != null) ctorChain = (CallExpr)ctorChain.walk(v)
 131          paramDefs.each |ParamDef p| { if (p.def != null) p.def = p.def.walk(v) }
 132        }
 133        if (code != null) code.walk(v, depth)
 134      }
 135      v.visitMethodDef(this)
 136      v.exitMethodDef(this)
 137    }
 138  
 139  //////////////////////////////////////////////////////////////////////////
 140  // Debug
 141  //////////////////////////////////////////////////////////////////////////
 142  
 143    override Str toStr()
 144    {
 145      return "$ret $name(" + params.join(",") + ")"
 146    }
 147  
 148    override Void print(AstWriter out)
 149    {
 150      printFacets(out)
 151      out.flags(flags).w(ret).w(" ").w(name).w("(")
 152      paramDefs.each |ParamDef p, Int i|
 153      {
 154        if (i > 0) out.w(", ")
 155        p.print(out)
 156      }
 157      out.w(")").nl
 158  
 159      if (ctorChain != null) { out.w(" : "); ctorChain.print(out); out.nl }
 160  
 161      if (code != null) code.print(out)
 162      out.nl
 163    }
 164  
 165  //////////////////////////////////////////////////////////////////////////
 166  // Fields
 167  //////////////////////////////////////////////////////////////////////////
 168  
 169    CType ret              // return type
 170    CType inheritedRet     // used for original return if covariant
 171    ParamDef[] paramDefs   // parameter definitions
 172    Block code             // code block
 173    CallExpr ctorChain     // constructor chain for this/super ctor
 174    MethodVar[] vars       // all param/local variables in method
 175    FieldDef accessorFor   // if accessor method for field
 176    Bool needsCvars        // does this method have locals used inside closures
 177  
 178  }