Changeset 1591

Show
Ignore:
Timestamp:
08/28/08 04:00:40 (3 months ago)
Author:
Chuck.Esterbrook
Message:

Added support for "extended initializers" which allow you to set properties of the object in the same call being used to create the object.

Location:
cobra/trunk
Files:
1 added
5 modified

Legend:

Unmodified
Added
Removed
  • cobra/trunk/Developer/IntermediateReleaseNotes.text

    r1589 r1591  
    11Post 0.8 
     2 
     3* Added support for "extended initializers" which allow you to set properties of the object in the same call being used to create the object: 
     4.code 
     5        r = Rectangle(p1=Point(x=0, y=1), p2=Point(x=2, y=3)) 
     6        c = Customer('Acme, Inc.', region=Regions.South) 
    27 
    38* Added partial classes, a la C# and VB. This enables class (and struct) declarations to be split across files. This can be useful for organizing generated code or even manually written code based on purpose. ticket:10 
  • cobra/trunk/Source/Attributes.cobra

    r1583 r1591  
    1818                        expr = PostCallExpr(expr.token, IdentifierExpr(expr.token, expr.name), List<of Expr>()) 
    1919                _expr = expr to PostCallExpr 
     20                _expr.isForAttribute = true 
    2021 
    2122        get expr from var 
     
    3536                        if .compiler.symbolForName(name+'Attribute', true, false) 
    3637                                _expr = PostCallExpr(_expr.token, IdentifierExpr(_expr.token, name+'Attribute'), _expr.args) 
     38                                _expr.isForAttribute = true  # CC: use property set in initializer 
    3739                _expr.bindImp 
    38                 # TODO: check that the properties exist when using x=... 
    3940 
    4041        get typeForIdentifier as IType is override 
  • cobra/trunk/Source/Boxes.cobra

    r1584 r1591  
    632632                        for invari in _invariants 
    633633                                invari.bindImp 
    634                         for decl in _declsInOrder 
     634                        for decl in List<of IBoxMember>(_declsInOrder) 
    635635                                assert not decl is this 
    636636                                .compiler.boxMemberStack.push(decl) 
  • cobra/trunk/Source/Expr.cobra

    r1590 r1591  
    13531353        var _expr as Expr 
    13541354        var _args as List<of Expr> 
     1355        var _hasKeywordArg as bool  # such as Foo(1, a=2) 
     1356        var _isForAttribute as bool  # see Attributes.cobra 
     1357        var _helperMethod as Method? 
    13551358 
    13561359        def init(token as IToken, expr as Expr, args as List<of Expr>) 
     
    13641367                .addField('expr', _expr) 
    13651368                .addField('args', _args) 
     1369                .addField('hasKeywordArg', .hasKeywordArg) 
     1370                .addField('isForAttribute', .isForAttribute) 
    13661371 
    13671372        get expr from var 
     
    13691374        get args from var 
    13701375                has Subnodes 
     1376 
     1377        get hasKeywordArg from var 
     1378 
     1379        pro isForAttribute from var 
    13711380 
    13721381        get hasError as bool is override 
     
    14121421                                return                                   
    14131422 
    1414                 for arg in _args 
     1423                for arg in .args 
    14151424                        try 
    14161425                                if arg inherits AssignExpr 
     1426                                        _hasKeywordArg = true # uu 
     1427                                        # TODO: check that left side is an IdentfierExpr 
     1428                                        # TODO: check property name 
    14171429                                        arg.right.bindImp  # 'x=y' has special treatment in arguments 
    14181430                                else 
     1431                                        if _hasKeywordArg 
     1432                                                .throwError('Cannot have a non-keyword argument ("[arg.toCobraSource]") after a keyword argument. All positional arguments must come before all keyword arguments.') 
    14191433                                        arg.bindImp 
    14201434                        catch ne as NodeException 
     
    14481462                                assert false, expr 
    14491463 
     1464                if .hasKeywordArg and not .isForAttribute  # uu 
     1465                        _makeHelperMethod 
     1466                         
     1467        def _makeHelperMethod 
     1468                """ 
     1469                Add a private helper method to the current box to support extended initializer. 
     1470 
     1471                Foo(expr0, expr1, bar=expr2) --> 
     1472                        call: 
     1473                                _ch_ext_init_1207(expr0, expr1, expr2) 
     1474                        def: 
     1475                                def _ch_ext_init_1207(arg0 as int, arg1 as int, /#bar=#/arg2 as int) 
     1476                                        obj = Foo(arg0, arg1) 
     1477                                        obj.bar = arg2 
     1478                                        return obj 
     1479                """ 
     1480                box = .compiler.curBox 
     1481                paramsForDecl = List<of Param>() 
     1482                argsForInitCall = List<of Expr>()  # args to pass to `Foo(arg0, arg1)` 
     1483                propsToSet = List<of AssignExpr>()  # props to set as `obj.bar = arg2` etc. 
     1484                firstPropArg = -1 
     1485                i = 0 
     1486                for arg in .args 
     1487                        if arg inherits AssignExpr 
     1488                                propsToSet.add(arg) 
     1489                                if firstPropArg == -1, firstPropArg = i 
     1490                                arg = arg.right 
     1491                        else 
     1492                                argsForInitCall.add(arg) 
     1493                        paramsForDecl.add(Param(box.token.copy('ID', 'arg[i]'), arg.type)) 
     1494                        i += 1 
     1495                name = '_ch_ext_init_[.serialNum]'  # ch = class helper, ext = extended, init = initializer 
     1496                token = box.token.copy 
     1497                m = Method(token.copy('ID', name), box, name, paramsForDecl, _type, nil, ['shared'], AttributeList(), '') 
     1498                m.locals.add(LocalVar(token.copy('ID', 'obj'), .type)) 
     1499 
     1500                objId = IdentifierExpr(token.copy('ID', 'obj'), 'obj') 
     1501                callExpr = PostCallExpr(token.copy('ID', .type.name), IdentifierExpr(token.copy('ID', .type.name), .type), argsForInitCall) 
     1502                assign = AssignExpr(token.copy('ASSIGN', '='), 'ASSIGN', objId, callExpr) 
     1503                m.addStmt(assign) 
     1504 
     1505                i = firstPropArg 
     1506                for propSetExpr in propsToSet 
     1507                        propName = (propSetExpr.left to IdentifierExpr).name 
     1508                        memberExpr = DotExpr(token.copy('DOT', '.'), 'DOT', IdentifierExpr(token.copy('ID', 'obj')), MemberExpr(token.copy('ID', propName))) 
     1509                        assign = AssignExpr(token.copy('ASSIGN', '='), 'ASSIGN', memberExpr, IdentifierExpr(token.copy('ID', 'arg[i]'))) 
     1510                        m.addStmt(assign) 
     1511                        i += 1 
     1512 
     1513                retStmt = ReturnStmt(token.copy('RETURN', 'return'), IdentifierExpr(token.copy('ID', 'obj'), 'obj')) 
     1514                m.addStmt(retStmt) 
     1515 
     1516                m.bindAll 
     1517                box.addDecl(m) 
     1518                _helperMethod = m 
     1519 
    14501520        def toCobraSource as String is override 
    14511521                sb = StringBuilder() 
     
    14531523                sb.append('(') 
    14541524                sep = '' 
    1455                 for arg in _args 
     1525                for arg in .args 
    14561526                        sb.append(sep) 
    14571527                        sb.append(arg.toCobraSource) 
  • cobra/trunk/Source/SharpGenerator.cobra

    r1590 r1591  
    427427        def writeSharpDef(sw as SharpWriter, parens as bool) is override 
    428428                if parens, sw.write('(') 
    429                 expr = _expr 
    430                 isMethodSig = false 
    431                 isDynamic = false 
    432                 if expr inherits TypeExpr 
    433                         if expr.containedType inherits ArrayType 
    434                                 # arrays 
    435                                 sw.write('new ') 
    436                                 sw.write((expr.containedType to ArrayType).theWrappedType.sharpRef) 
    437                                 sw.write(r'[') 
    438                                 .writeSharpArgs(sw) 
    439                                 sw.write(r']') 
     429                if _helperMethod 
     430                        sw.write(_helperMethod.name + '(') 
     431                        sep = '' 
     432                        for arg in _args 
     433                                sw.write(sep) 
     434                                if arg inherits AssignExpr 
     435                                        arg = arg.right 
     436                                arg.writeSharpDefInContext(sw, false) 
     437                                sep = ',' 
     438                        sw.write(')') 
     439                else 
     440                        expr = _expr 
     441                        isMethodSig = false 
     442                        isDynamic = false 
     443                        if expr inherits TypeExpr 
     444                                if expr.containedType inherits ArrayType 
     445                                        # arrays 
     446                                        sw.write('new ') 
     447                                        sw.write((expr.containedType to ArrayType).theWrappedType.sharpRef) 
     448                                        sw.write(r'[') 
     449                                        .writeSharpArgs(sw) 
     450                                        sw.write(r']') 
     451                                else 
     452                                        sw.write('new ') 
     453                                        expr.writeSharpDef(sw) 
     454                                        sw.write('(') 
     455                                        .writeSharpArgs(sw) 
     456                                        sw.write(')') 
     457                        else if expr inherits IdentifierExpr 
     458                                if expr.isTypeReference 
     459                                        sw.write('new ') 
     460                                        expr.writeSharpDef(sw) 
     461                                        sw.write('(') 
     462                                        .writeSharpArgs(sw) 
     463                                        sw.write(')') 
     464                                else if expr.receiverType inherits GenericParam # TODO: shouldn't expr.isTypeReference above have caught this? 
     465                                        sw.write('new [expr.receiverType.sharpRef](') 
     466                                        .writeSharpArgs(sw) 
     467                                        sw.write(')') 
     468                                else if expr.type inherits MethodSig 
     469                                        isMethodSig = true 
     470                                else if expr.type.isSystemTypeClass or _type.isDynamic 
     471                                        isDynamic = true 
     472                                else 
     473                                        assert false, expr  # TODO: .throwError 
     474                        else if expr inherits IndexExpr 
     475                                if expr.type inherits MethodSig 
     476                                        isMethodSig = true 
     477                                else if expr.type.isSystemTypeClass or _type.isDynamic 
     478                                        isDynamic = true 
     479                                else 
     480                                        assert false, expr  # TODO: .throwError 
    440481                        else 
    441                                 sw.write('new ') 
     482                                assert false, expr  # TODO: .throwError 
     483                        if isMethodSig 
    442484                                expr.writeSharpDef(sw) 
    443485                                sw.write('(') 
    444486                                .writeSharpArgs(sw) 
    445487                                sw.write(')') 
    446                 else if expr inherits IdentifierExpr 
    447                         if expr.isTypeReference 
    448                                 sw.write('new ') 
    449                                 expr.writeSharpDef(sw) 
    450                                 sw.write('(') 
    451                                 .writeSharpArgs(sw) 
     488                        else if isDynamic 
     489                                defi = (expr to dynamic).definition 
     490                                assert not defi inherits Box, expr  # TODO: just curious 
     491                                what = if(defi inherits IType, 'typeof([defi.sharpName])', defi.sharpName to String) 
     492                                if defi inherits IVar 
     493                                        if defi.type.isDynamic 
     494                                                what = '(System.Type)' + what 
     495                                sw.write('Activator.CreateInstance([what]') 
     496                                .writeSharpArgs(sw, ', ') 
    452497                                sw.write(')') 
    453                         else if expr.receiverType inherits GenericParam # TODO: shouldn't expr.isTypeReference above have caught this? 
    454                                 sw.write('new [expr.receiverType.sharpRef](') 
    455                                 .writeSharpArgs(sw) 
    456                                 sw.write(')') 
    457                         else if expr.type inherits MethodSig 
    458                                 isMethodSig = true 
    459                         else if expr.type.isSystemTypeClass or _type.isDynamic 
    460                                 isDynamic = true 
    461                         else 
    462                                 assert false, expr  # TODO: .throwError 
    463                 else if expr inherits IndexExpr 
    464                         if expr.type inherits MethodSig 
    465                                 isMethodSig = true 
    466                         else if expr.type.isSystemTypeClass or _type.isDynamic 
    467                                 isDynamic = true 
    468                         else 
    469                                 assert false, expr  # TODO: .throwError 
    470                 else 
    471                         assert false, expr  # TODO: .throwError 
    472                 if isMethodSig 
    473                         expr.writeSharpDef(sw) 
    474                         sw.write('(') 
    475                         .writeSharpArgs(sw) 
    476                         sw.write(')') 
    477                 else if isDynamic 
    478                         defi = (expr to dynamic).definition 
    479                         assert not defi inherits Box, expr  # TODO: just curious 
    480                         what = if(defi inherits IType, 'typeof([defi.sharpName])', defi.sharpName to String) 
    481                         if defi inherits IVar 
    482                                 if defi.type.isDynamic 
    483                                         what = '(System.Type)' + what 
    484                         sw.write('Activator.CreateInstance([what]') 
    485                         .writeSharpArgs(sw, ', ') 
    486                         sw.write(')') 
    487498                if parens, sw.write(')') 
    488499