Ticket #275: main-wrapper-be.patch
File main-wrapper-be.patch, 11.6 KB (added by hopscc, 13 years ago) |
---|
-
Source/BackEndCommon/CurlyWriter.cobra
63 63 def _isNewLine(value as String) as bool 64 64 return value == _innerWriter.newLine or value == .newLine2 65 65 66 def bumpLineNum 67 _cobraLineNum += 1 68 66 69 # CC: shouldn't need the following 67 70 def write(value as String?) is override 68 71 base.write(value) -
Source/Expr.cobra
584 584 var _args as List<of Expr> 585 585 var _hasParens as bool 586 586 var _definition as IMember? 587 var _hasMainArgs as bool = false588 587 589 588 cue init(token as IToken, name as String, args as List<of Expr>, hasParens as bool) 590 589 .init(token, name, nil, args, hasParens as bool) … … 614 613 615 614 get hasParens from var 616 615 617 pro hasMainArgs from var618 """Indicate if this call needs args passed into main method inserted by backend. For MainWrapper """619 620 616 get willChangeVar as bool is override 621 617 for arg in _args, if arg.willChangeVar, return true 622 618 for arg in _args, if arg.direction <> Direction.In, return true -
Source/Boxes.cobra
1226 1226 base.init(token, idToken, name, paramList, isNames, attribs, implementsNodes, addsProxies, docString) 1227 1227 _baseNode = baseNode 1228 1228 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 1229 1233 cue init(nativeType as NativeType, backend as BackEnd) 1230 1234 # TODO: fix native 1231 1235 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
70 70 Holds name, docString and the topLevelNamespace as the root of the parsed AST nodes. 71 71 Also handles binding by passing bind invocation onto its namespace to action. 72 72 """ 73 73 74 pro isMainWrapper from var = false 75 """ synthesized wrapper for main""" 76 74 77 cue init(fileName as String, verbosity as int, docString as String, globalNS as NameSpace) 75 78 base.init(fileName, verbosity, docString) 76 79 _topNameSpace = NameSpace(globalNS, '(top namespace for module [fileName])') -
Source/Phases/IdentifyMainPhase.cobra
57 57 if not main.resultType.isDescendantOf(.compiler.voidType) 58 58 main.recordError('The "main" method cannot have a return type. Use "CobraCore.exit(code)" instead.') 59 59 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]" .') 60 63 if not main.isShared 61 64 init = main.parentBox.memberForName('cue.init') 62 65 if init inherits MemberOverload … … 77 80 name = 'MainWrapper' 78 81 while c.symbolForName(name, false, false), name += 'X' 79 82 80 if false81 # can't use cobra source because the other82 # phases like parsing have already taken place83 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 main93 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 method97 method.addStmt(dot)98 99 theClass.addDecl(method)100 101 83 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 108 85 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 109 91 c.modules.add(mainModule) 110 92 c.mainMethodTypeName = name 111 93 -
Source/BackEndClr/SharpGenerator.cobra
465 465 # TODO: list op sys 466 466 sw.write('\n') 467 467 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) 471 473 d = sw.curlyToCobraLineNum 472 474 if false 473 475 bar = '----------------------------------------------' … … 479 481 def writeSharpTestInvocation(sw as CurlyWriter) is override 480 482 .topNameSpace.writeSharpTestInvocation(sw) 481 483 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 482 499 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 483 518 ## 484 519 ## Container and friends 485 520 ## … … 1761 1796 sw.write('CobraLangInternal.CobraImp.PopFrame();\n') 1762 1797 sw.dedentAndWrite('}\n') 1763 1798 1764 1799 1765 1800 class Initializer is partial 1766 1801 1767 1802 def innerWriteSharpDef(sw as CurlyWriter) -
Source/BackEndJvm/JavaGenerator.cobra
336 336 # TODO: list op sys 337 337 sw.write('\n') 338 338 339 .topNameSpace.writeJavaDef(sw) 339 if .isMainWrapper 340 .synthesizeJavaMainWrapper(sw) 341 else 342 .topNameSpace.writeJavaDef(sw) 340 343 d = sw.curlyToCobraLineNum 341 344 return d 342 345 343 346 def writeJavaTestInvocation(sw as CurlyWriter) is override 344 347 # TODO: .topNameSpace.writeJavaTestInvocation(sw) 345 348 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 346 363 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 347 385 348 386 ## 349 387 ## Container and friends … … 1598 1636 .writeJavaIsNames(sw) 1599 1637 sw.write('[returnType.javaRef] [name][.javaGenericParams]') 1600 1638 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 1602 1640 else 1603 1641 .writeJavaParams(sw) 1604 1642 if .genericParams.count … … 2464 2502 sw.write(sep) 2465 2503 arg.writeJavaDefInContext(sw) 2466 2504 sep = ', ' 2467 if .hasMainArgs # for MainWrapper - pass through args fm main method2468 sw.write('args') # same name(s) as inserted args on main method2469 2505 sw.write(')') 2470 2506 2471 2507 def writeJavaBreakdownItems(sw as CurlyWriter) is override -
Tests/110-basics-two/170-main/260-main-is-private.cobra
1 class 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
1 class A 2 3 def main is protected # .error. the "main" method cannot be "protected" 4 print 'hello'