Wiki

Ticket #275: main-wrapper-be.patch

File main-wrapper-be.patch, 11.6 KB (added by hopscc, 7 years ago)
  • Source/BackEndCommon/CurlyWriter.cobra

     
    6363    def _isNewLine(value as String) as bool 
    6464        return value == _innerWriter.newLine or value == .newLine2 
    6565 
     66    def bumpLineNum 
     67        _cobraLineNum += 1 
     68     
    6669    # CC: shouldn't need the following 
    6770    def write(value as String?) is override 
    6871        base.write(value) 
  • Source/Expr.cobra

     
    584584    var _args as List<of Expr> 
    585585    var _hasParens as bool 
    586586    var _definition as IMember? 
    587     var _hasMainArgs as bool = false 
    588587 
    589588    cue init(token as IToken, name as String, args as List<of Expr>, hasParens as bool) 
    590589        .init(token, name, nil, args, hasParens as bool) 
     
    614613 
    615614    get hasParens from var 
    616615     
    617     pro hasMainArgs from var 
    618         """Indicate if this call needs args passed into main method inserted by backend. For MainWrapper """ 
    619          
    620616    get willChangeVar as bool is override 
    621617        for arg in _args, if arg.willChangeVar, return true 
    622618        for arg in _args, if arg.direction <> Direction.In, return true 
  • Source/Boxes.cobra

     
    12261226        base.init(token, idToken, name, paramList, isNames, attribs, implementsNodes, addsProxies, docString) 
    12271227        _baseNode = baseNode 
    12281228 
     1229    cue init(name as String, paramList as List<of IType>) 
     1230        """ public skeleton class - init with given name and paramlist -  no baseclass, attributes, interfaces or mixins.""" 
     1231        .init(Token.empty, Token.empty, name, paramList, ['public'], AttributeList(), nil, List<of ITypeProxy>(), List<of ITypeProxy>(), '') 
     1232             
    12291233    cue init(nativeType as NativeType, backend as BackEnd) 
    12301234        # TODO: fix native 
    12311235        base.init(TokenFix.empty, TokenFix.empty, backend.cobraNameForNativeBoxName(nativeType.name), List<of IType>(), List<of String>(), AttributeList(), List<of ITypeProxy>(), List<of ITypeProxy>(), nil) 
  • Source/Module.cobra

     
    7070        Holds name, docString and the topLevelNamespace as the root of the parsed AST nodes. 
    7171        Also handles binding by passing bind invocation onto its namespace to action. 
    7272    """ 
    73  
     73     
     74    pro isMainWrapper from var = false 
     75        """ synthesized wrapper for main""" 
     76         
    7477    cue init(fileName as String, verbosity as int, docString as String, globalNS as NameSpace) 
    7578        base.init(fileName, verbosity, docString) 
    7679        _topNameSpace = NameSpace(globalNS, '(top namespace for module [fileName])') 
  • Source/Phases/IdentifyMainPhase.cobra

     
    5757        if not main.resultType.isDescendantOf(.compiler.voidType) 
    5858            main.recordError('The "main" method cannot have a return type. Use "CobraCore.exit(code)" instead.') 
    5959            didError = true 
     60        if  main.isProtected or main.isPrivate 
     61            access = if(main.isProtected, 'protected', 'private') 
     62            main.recordError('The "main" method cannot be "[access]" .') 
    6063        if not main.isShared 
    6164            init = main.parentBox.memberForName('cue.init') 
    6265            if init inherits MemberOverload 
     
    7780        name = 'MainWrapper' 
    7881        while c.symbolForName(name, false, false), name += 'X' 
    7982 
    80         if false 
    81             # can't use cobra source because the other 
    82             # phases like parsing have already taken place 
    83             src = 'class [name]\n\t\def main is static\n\t\t[mainMethod.parentBox.qualifiedName]().[mainMethod.name]\n' 
    84             .options.addExtraSource(src) 
    85  
    86         implements_ = List<of ITypeProxy>() 
    87         adds_ = List<of ITypeProxy>() 
    88         theClass = Class(Token.empty, Token.empty, name, List<of IType>(), ['public'], AttributeList(), nil, implements_, adds_, '') 
    89  
    90         instantiate = PostCallExpr(Token.empty, TypeExpr(mainMethod.parentBox), List<of Expr>()) 
    91         mainCall = CallExpr(Token.empty, 'main', List<of Expr>(), false) 
    92         mainCall.hasMainArgs = true # backend insert args passed to main 
    93         dot = DotExpr(Token.empty, 'DOT', instantiate, mainCall) 
    94  
    95         method = Method(Token.empty, Token.empty, theClass, 'main', List<of Param>(), .compiler.voidType, nil, ['shared'], mainMethod.attributes, '') 
    96         method.hasMainParams = true  # backend insert params on main method 
    97         method.addStmt(dot) 
    98  
    99         theClass.addDecl(method) 
    100  
    10183        mainModule = CobraModule(name+'.cobra', 0, '', .compiler.globalNS, isImplicit=true) 
    102         mainModule.topNameSpace.addDecl(theClass) 
    103  
    104         mainModule.bindUse 
    105         mainModule.bindInh 
    106         mainModule.bindInt 
    107         mainModule.bindImp 
     84        mainModule.isMainWrapper = true # mark us as special 
    10885         
     86        # placeholder class provided only to store user method referenced 
     87        theClass = Class(name, List<of IType>()) 
     88        theClass.addDecl(mainMethod) # store the  method to harvest contents later 
     89        mainModule.topNameSpace.addDecl(theClass) # data source for later harvest, not to generate a class+method 
     90 
    10991        c.modules.add(mainModule) 
    11092        c.mainMethodTypeName = name 
    11193 
  • Source/BackEndClr/SharpGenerator.cobra

     
    465465            # TODO: list op sys 
    466466            sw.write('\n') 
    467467 
    468             sw.write('using CobraLangInternal = Cobra.Lang[.compiler.embedRunTimeSuffix];\n') 
    469              
    470             .topNameSpace.writeSharpDef(sw) 
     468            if .isMainWrapper  
     469                .synthesizeSharpMainWrapper(sw) 
     470            else 
     471                sw.write('using CobraLangInternal = Cobra.Lang[.compiler.embedRunTimeSuffix];\n') 
     472                .topNameSpace.writeSharpDef(sw) 
    471473            d = sw.curlyToCobraLineNum 
    472474        if false 
    473475            bar = '----------------------------------------------' 
     
    479481    def writeSharpTestInvocation(sw as CurlyWriter) is override 
    480482        .topNameSpace.writeSharpTestInvocation(sw) 
    481483 
     484         
     485    def synthesizeSharpMainWrapper(sw as CurlyWriter) 
     486        """ 
     487        Generate a wrapper class with a valid main method for C#/Clr 
     488            The wrapper will instantiate and call the provided user main method. 
     489        """ 
     490             
     491        # Module top namespace is expected to have a first entry which is a dummy class holding 
     492        #  the method (+ class ref) for the mainwrapper to instantiate and invoke. 
     493        assert .topNameSpace.declsInOrder.count 
     494        assert .topNameSpace.declsInOrder[0] inherits Class 
     495        placeHolderClass = .topNameSpace.declsInOrder[0] to Class 
     496        assert placeHolderClass.declsInOrder.count 
     497        assert placeHolderClass.declsInOrder[0] inherits AbstractMethod  
     498        mainMethod = placeHolderClass.declsInOrder[0] to AbstractMethod  # method data 
    482499 
     500        sw.write('// Cobra synthesized program entrypoint wrapping call to user supplied main method\n\n') 
     501        sw.writeAndIndent('class MainWrapper : System.Object {\n') 
     502        sw.bumpLineNum 
     503        for attr in mainMethod.attributes  
     504            attr.writeSharpDef(sw, '', false) 
     505        if  mainMethod.attributes.count, sw.writeLine 
     506        sw.writeAndIndent('public static void Main() {\n')   
     507        sw.bumpLineNum 
     508        sw.writeLine('(new [mainMethod.parentBox.qualifiedName]()).Main();') 
     509        sw.bumpLineNum 
     510        sw.dedentAndWrite('} // end Main\n\n') 
     511        sw.bumpLineNum 
     512        sw.writeLine('public  MainWrapper()') 
     513        sw.indentAndWrite(': base() {\n') 
     514        sw.dedentAndWrite('}') 
     515        sw.write('\n') 
     516        sw.writeLine('} // class MainWrapper') 
     517         
    483518## 
    484519## Container and friends 
    485520## 
     
    17611796        sw.write('CobraLangInternal.CobraImp.PopFrame();\n') 
    17621797        sw.dedentAndWrite('}\n') 
    17631798 
    1764  
     1799             
    17651800class Initializer is partial 
    17661801 
    17671802    def innerWriteSharpDef(sw as CurlyWriter) 
  • Source/BackEndJvm/JavaGenerator.cobra

     
    336336            # TODO: list op sys 
    337337            sw.write('\n') 
    338338 
    339             .topNameSpace.writeJavaDef(sw) 
     339            if .isMainWrapper    
     340                .synthesizeJavaMainWrapper(sw) 
     341            else 
     342                .topNameSpace.writeJavaDef(sw) 
    340343            d = sw.curlyToCobraLineNum 
    341344        return d 
    342345 
    343346    def writeJavaTestInvocation(sw as CurlyWriter) is override 
    344347        # TODO: .topNameSpace.writeJavaTestInvocation(sw) 
    345348        pass 
     349         
     350    def synthesizeJavaMainWrapper(sw as CurlyWriter) 
     351        """ 
     352        Generate a wrapper class with a valid main method for java. 
     353            The wrapper will instantiate and call the provided user main method. 
     354        """ 
     355        # Module top namespace is expected to have a single entry which is a dummy class holding 
     356        #  the method (+ class) for the mainwrapper to instantiate and invoke. 
     357        assert .topNameSpace.declsInOrder.count 
     358        assert .topNameSpace.declsInOrder[0] inherits Class 
     359        placeHolderClass = .topNameSpace.declsInOrder[0] to Class 
     360        assert placeHolderClass.declsInOrder.count 
     361        assert placeHolderClass.declsInOrder[0] inherits AbstractMethod  
     362        mainMethod = placeHolderClass.declsInOrder[0] to AbstractMethod  # method data 
    346363 
     364        sw.write('// Cobra synthesized program entrypoint wrapping call to user supplied main method\n\n') 
     365        sw.writeAndIndent('class MainWrapper extends java.lang.Object {\n') 
     366        sw.bumpLineNum 
     367        for attr in mainMethod.attributes  
     368            attr.writeSharpDef(sw, '', false) 
     369        if  mainMethod.attributes.count, sw.writeLine 
     370        sw.writeAndIndent(r'static public void main(String[] args) {') 
     371        sw.writeLine 
     372        sw.bumpLineNum 
     373        sw.writeLine('//cobra.lang.CobraCore.setCommandLineArgs(args); ') 
     374        sw.writeLine('(new [mainMethod.parentBox.javaRef]()).main(args);') 
     375        sw.bumpLineNum 
     376        sw.dedentAndWrite('} // end MainWrapper.main\n\n') 
     377        sw.bumpLineNum 
     378        sw.writeLine('public  MainWrapper() {') 
     379        sw.indentAndWrite('//super(); \n') 
     380        sw.dedentAndWrite('}') 
     381        sw.writeLine 
     382        sw.dedentAndWrite('} // class MainWrapper') 
     383        sw.writeLine 
     384         
    347385 
    348386## 
    349387## Container and friends 
     
    15981636        .writeJavaIsNames(sw) 
    15991637        sw.write('[returnType.javaRef] [name][.javaGenericParams]') 
    16001638        if .hasMainParams   # insert args for main method for this backend 
    1601             sw.write(r'(String[] args)') 
     1639            sw.write(r'(String[] args)') # match to CobraModule.synthesizeJavaMainWrapper 
    16021640        else 
    16031641            .writeJavaParams(sw) 
    16041642        if .genericParams.count 
     
    24642502            sw.write(sep) 
    24652503            arg.writeJavaDefInContext(sw) 
    24662504            sep = ', ' 
    2467         if .hasMainArgs         # for MainWrapper - pass through args fm main method 
    2468             sw.write('args')    # same name(s) as inserted args on main method  
    24692505        sw.write(')') 
    24702506 
    24712507    def writeJavaBreakdownItems(sw as CurlyWriter) is override 
  • Tests/110-basics-two/170-main/260-main-is-private.cobra

     
     1class A 
     2 
     3    def main is private #  .error. the "main" method cannot be "private"  
     4        print 'hello' 
  • Tests/110-basics-two/170-main/265-main-is-protected.cobra

     
     1class A 
     2 
     3    def main is protected #  .error. the "main" method cannot be "protected"  
     4        print 'hello'