Ticket #31: implicitLineContInParens.patch
File implicitLineContInParens.patch, 10.0 KB (added by hopscc, 16 years ago) |
---|
-
Source/CobraParser.cobra
100 100 var _curCodePart as AbstractMethod? 101 101 102 102 var _spaceAgnosticIndentLevel as int 103 var _spaceAgnosticExprLevel as int 103 104 var _isContractOnSameLine as bool 104 105 105 106 var _isTraceOn as bool … … 1189 1190 hasIsNames = true 1190 1191 else 1191 1192 .endOfLine 1192 if not .optional('INDENT') 1193 # with no indent there can be no additional specs like attributes, contracts or body 1193 1194 if _noMoreSpecs() 1195 # No additional specs like attributes, contracts or body 1194 1196 nothingMore = true 1195 1197 if not hasIsNames 1196 1198 isNames = List<of String>(_isNamesStack) … … 1239 1241 else 1240 1242 return method 1241 1243 1244 def _noMoreSpecs as bool 1245 """ 1246 Return a bool indicating that there is no (correctly indented) additional specs 1247 like attributes, contracts or body following. 1248 """ 1249 noMoreSpecs = false 1250 if _spaceAgnosticIndentLevel == 0 # paramdecls all on same line 1251 noMoreSpecs = not .optional('INDENT') # Anything else must be indented 1252 else 1253 #print "[name] sail=[_spaceAgnosticIndentLevel] " 1254 sail = _spaceAgnosticIndentLevel 1255 if sail > 0 1256 _spaceAgnosticIndentLevel -= 1 # for missing indent 1257 _finishSpaceAgnostic 1258 if sail >= 1 1259 noMoreSpecs = .optional('DEDENT') <> nil 1260 else 1261 noMoreSpecs = not .optional('INDENT') 1262 1263 #print "noMoreSpex=[noMoreSpecs]" 1264 return noMoreSpecs 1265 1266 1242 1267 def declareMethodSig as MethodSig 1243 1268 require _typeProvider 1244 1269 token = .expect('SIG') … … 1530 1555 ## 1531 1556 1532 1557 def paramDecls(skipParen as bool) as List<of Param> 1533 return .paramDecls(skipParen, 'RPAREN' )1558 return .paramDecls(skipParen, 'RPAREN', true) 1534 1559 1535 1560 def paramDecls(skipParen as bool, rightParen as String) as List<of Param> 1561 return .paramDecls(skipParen, rightParen, false) 1562 1563 def paramDecls(skipParen as bool, rightParen as String, isSpaceAgnostic as bool) as List<of Param> 1536 1564 if not skipParen 1537 1565 .expect('LPAREN') 1538 1566 params = List<of Param>() 1539 1567 expectComma = false 1540 1568 while true 1569 if isSpaceAgnostic 1570 _spaceAgnostic 1541 1571 if .peek.which==rightParen 1542 1572 .grab 1543 1573 break 1544 1574 if expectComma 1545 1575 .expect('COMMA') 1576 if isSpaceAgnostic 1577 _spaceAgnostic 1546 1578 param = .paramDecl 1547 1579 params.add(param) 1548 1580 if params.count==1 and param.name=='self' and param.isMissingType … … 2363 2395 _inExpression += 1 2364 2396 try 2365 2397 expr = .expression(0, nil) 2366 if expr.isParened 2398 if expr.isParened and expr.token.lineNum == .last.lineNum 2367 2399 _warning(expr.token, 'Unnecessary parentheses around expression. You can remove them.') 2368 2400 return expr 2369 2401 finally … … 2398 2430 if not PostCallExpr.isTargetAcceptable(left to !) 2399 2431 .throwError('Unexpected call.') # example: t = x to List<of String>() 2400 2432 token = .grab 2433 #exprs = .commaSepExprs(['RPAREN'], true, false) 2401 2434 exprs = .commaSepExprs('RPAREN') 2402 2435 return .expression(precedence, PostCallExpr(token, left, exprs)) 2403 2436 else … … 2444 2477 return left to ! 2445 2478 2446 2479 def expression2 as Expr 2480 if _spaceAgnosticExprLevel > 0 #and .peek.which in ['EOL','INDENT','DEDENT'] 2481 _spaceAgnostic 2447 2482 peekToken = .peek 2448 2483 peek = peekToken.which 2449 2484 if _unaryOpPrec.containsKey(peek) … … 2460 2495 # TODO: make a branch statement 2461 2496 else if peek=='LPAREN' 2462 2497 .grab 2498 _spaceAgnosticExprLevel += 1 2463 2499 node = .expression(0, nil) 2464 2500 .expect('RPAREN') 2501 _spaceAgnosticExprLevel -= 1 2465 2502 node.isParened = true 2466 2503 return node 2467 2504 else if peek=='DOT' … … 2544 2581 return .typeExpr 2545 2582 catch pe as ParserException 2546 2583 if pe.message.contains('Unrecognized type') 2547 msg = 'Expecting an expression.' 2584 ofst = pe.message.indexOf('Unrecognized type') 2585 submsg = pe.message[ofst:] 2586 msg = '[submsg] Expecting an expression.' 2548 2587 if peekToken.isKeyword 2549 2588 msg += ' "[peekToken.text]" is a reserved keyword that is not expected here.' 2550 2589 .throwError(msg) … … 2562 2601 branch token.which 2563 2602 on 'OPEN_CALL' 2564 2603 assert not callName.endsWith('(') 2565 args = .commaSepExprs(['RPAREN'], false, true)2604 args = .commaSepExprs(['RPAREN'], true, true) # false, true) 2566 2605 return CallExpr(token, callName, args) 2567 2606 on 'OPEN_GENERIC' 2568 2607 assert not callName.endsWith('<of') and not callName.endsWith('<') … … 2575 2614 on 'GT', isDone = true 2576 2615 else, .throwError('Unexpected token [.last] in type arguments.') 2577 2616 .expect('LPAREN') 2578 args = .commaSepExprs(['RPAREN'], false, true)2617 args = .commaSepExprs(['RPAREN'], true, true) #false, true) 2579 2618 return CallExpr(token, callName, typeArgs, args) 2580 2619 else 2581 2620 throw FallThroughException(token) … … 3198 3237 _spaceAgnosticIndentLevel -= 1 3199 3238 continue 3200 3239 break 3240 if _verbosity>=5 3241 print '<> spaceAgnostic level=[_spaceAgnosticIndentLevel]' 3201 3242 3202 3243 def _finishSpaceAgnostic 3203 3244 """ -
Tests/110-basics-two/920-space-agnostic-expr.cobra
1 # Simple Test for implicit line continuation in paren delimited expressions 2 3 namespace Test 4 class SpaceAgnostic 5 6 def main is shared 7 i = (100 + 1 + 2 + 8 3 + 4) 9 #print i 10 assert i == 110 11 s = ('a very long line of text ' + 12 'another long line') 13 #print s 14 assert s == 'a very long line of text another long line' 15 16 i = (100 + 1 + 2 + 17 3 + 4) 18 assert i == 110 19 20 # TODO add more -
Tests/110-basics-two/910-space-agnostic-method.cobra
1 # Simple Test for implicit line continuation in method call arglists and 2 # method param declarations 3 # if this fails it probably wont compile 4 namespace Test 5 class SpaceAgnostic 6 7 def main is shared 8 CobraCore.tracer.isActive = false 9 .foo('foo argument Number 1', 10 'arg2', 11 'areg3' ) 12 13 .foo2('foo2 argument Number 1', 14 'argument Number 2', 15 'argument Number THree reg3' ) 16 17 .foo3('foo3 argument Number 1', 18 'argument Number 2', 19 'argument Number THree reg3' ) 20 21 .foo4('foo4 argument Number 1', 22 'argument Number 2', 23 'argument Number THree reg3' ) 24 25 .foo5('foo5 argument Number 1', 26 'argument Number 2', 27 'argument Number THree reg3' ) 28 29 .foo6('foo6 argument Number 1', 30 'argument Number 2', 31 'argument Number THree reg3' ) 32 33 .foo7('foo7 argument Number 1', 34 'argument Number 2', 35 'argument Number THree reg3' ) 36 # thats it for calls 37 38 def foo(arg1 as String, arg2 as String, arg3 as String) is shared 39 assert arg1.length 40 #print 'foo done' 41 42 def foo2(arg1 as String, 43 arg2 as String, 44 arg3 as String ) is shared 45 assert arg1.length 46 trace arg1 47 assert arg1.length 48 trace arg2 49 assert arg2.length 50 trace arg3 51 assert arg3.length 52 #print 'foo2 done' 53 54 def foo2a(arg1 as String, 55 arg2 as String, 56 arg3 as String ) is shared 57 assert arg1.length 58 trace arg1 59 assert arg1.length 60 trace arg2 61 assert arg2.length 62 trace arg3 63 assert arg3.length 64 #print 'foo2a done' 65 66 def foo3(arg1 as String, 67 arg2 as String, 68 arg3 as String ) is shared 69 assert arg1.length 70 trace arg1 71 assert arg1.length 72 trace arg2 73 assert arg2.length 74 trace arg3 75 assert arg3.length 76 #print 'foo3 done' 77 78 # pathological (0) 79 def foo4(arg1 as String, 80 arg2 as String, 81 arg3 as String ) is shared 82 assert arg1.length 83 #print "in foo4" 84 trace arg1 85 assert arg1.length 86 trace arg2 87 assert arg2.length 88 trace arg3 89 assert arg3.length 90 #print 'foo4 done' 91 92 # pathological (+1) 93 def foo5(arg1 as String, 94 arg2 as String, 95 arg3 as String ) is shared 96 #print "in foo5" 97 trace arg1 98 assert arg1.length 99 trace arg2 100 assert arg2.length 101 trace arg3 102 assert arg3.length 103 #print 'foo5 done' 104 105 # pathological (++1) 106 def foo6(arg1 as String, 107 arg2 as String, 108 arg3 as String ) is shared 109 trace arg1 110 assert arg1.length 111 trace arg2 112 assert arg2.length 113 trace arg3 114 assert arg3.length 115 #print 'foo6 done' 116 117 def foo7(arg1 as String, 118 arg2 as String, 119 arg3 as String ) is shared 120 trace arg1 121 assert arg1.length 122 trace arg2 123 assert arg2.length 124 trace arg3 125 assert arg3.length 126 #print 'foo7 done' 127 128 class AbX 129 is abstract 130 131 def aa(arg1 as String) is abstract 132 133 def ab(arg1 as String, 134 arg2 as String) is abstract 135 def ac(arg1 as String, 136 arg2 as String) is abstract 137 138 def ad(arg1 as String, 139 arg2 as String) is abstract 140 141 def ad1(arg1 as String, 142 arg2 as String) is abstract 143 144 def ae(arg1 as String, 145 arg2 as String) is abstract -
Developer/IntermediateReleaseNotes.text
1 1 Post 0.8 2 2 3 * Added support for implicit line continuation for items in parentheses. 4 i.e method call argument lists, method declaration parameters and 5 parenthesised expressions. 6 3 7 * Added a new built-in doc tool accessible via "cobra -doc ...". The documentation is generated to local HTML files using your declarations, doc strings, contracts, etc. 4 8 5 9 * Add support for specifying unsigned integers as Hex literals