Changeset 1763

Show
Ignore:
Timestamp:
11/14/08 05:24:55 (8 weeks ago)
Author:
Chuck.Esterbrook
Message:

Code cleanup.

  • Expr and IExpr have gained: get definition as dynamic?
  • Returns nil by default.
  • BinaryOpExpr?.definition simply returns .right.definition
  • Subclasses that have more strongly typed definitions add a property with the appropriate name such as .namedDefinition or .enumDefinition
  • Simplified some code.
Location:
cobra/trunk/Source
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • cobra/trunk/Source/BackEndClr/SharpGenerator.cobra

    r1754 r1763  
    31203120                        if not sharpName.startsWith('typeof') 
    31213121                                # maybe parentNameSpace could be moved up in the interface definitions 
    3122                                 pn = (.definition to dynamic).parentNameSpace 
     3122                                pn = .definition.parentNameSpace 
    31233123                                if pn, sharpName = pn.sharpQualifier + sharpName 
    31243124 
     
    31323132        get sharpName as String 
    31333133                assert .didBindImp 
    3134                 assert .definition 
     3134                assert .namedDefinition 
    31353135                assert not .type inherits UnspecifiedType 
    31363136                if .superNode inherits DotExpr 
    31373137                        assert this is not (.superNode to DotExpr).right  # should be a CallExpr or MemberExpr instead 
    3138                 defi = .definition 
     3138                defi = .namedDefinition 
    31393139                if .isTypeReference 
    31403140                        # C# often requires typeof(Foo) instead of just plain Foo 
     
    31513151                require 
    31523152                        .didBindImp 
    3153                         .definition 
     3153                        .namedDefinition 
    31543154                body 
    31553155                        if _definition inherits IVar 
     
    31603160        def writeSharpDefForBreakdown(sw as SharpWriter) 
    31613161                sharpName = .sharpName 
    3162                 if .isKindOf(.compiler.typeType) and .definition inherits IType and 'typeof(' not in sharpName 
     3162                if .isKindOf(.compiler.typeType) and .namedDefinition inherits IType and 'typeof(' not in sharpName 
    31633163                        sw.write('typeof([.sharpName])') 
    31643164                else 
     
    33923392                                sw.write(')') 
    33933393                        else if isDynamic 
    3394                                 defi = (expr to dynamic).definition 
     3394                                defi = expr.definition 
    33953395                                assert not defi inherits Box, expr  # TODO: just curious 
    33963396                                what = if(defi inherits IType, 'typeof([defi.sharpName])', defi.sharpName to String) 
     
    39743974                # handle the case where a type got backed up because of assignment inside of an if-inherits 
    39753975                if _backUpIfInheritsStack 
    3976                         assert (_left to dynamic).definition inherits IVar 
    3977                         (_left to dynamic).definition.ifInheritsStack = Stack<of IType>(_backUpIfInheritsStack) 
     3976                        assert _left.definition inherits IVar 
     3977                        _left.definition.ifInheritsStack = Stack<of IType>(_backUpIfInheritsStack) 
    39783978 
    39793979 
     
    43274327                        if _left inherits ThisLit 
    43284328                                if _right inherits CallExpr 
    4329                                         defi = _right.definition 
     4329                                        defi = _right.memberDefinition 
    43304330                                        if defi inherits IMember 
    43314331                                                writeThis = not defi.isShared 
     
    43354335                                                throw FallThroughException(defi) 
    43364336                                else if _right inherits MemberExpr 
    4337                                         writeThis = not _right.definition.isShared 
     4337                                        writeThis = not _right.memberDefinition.isShared 
    43384338                        else if .curCodeMember inherits Initializer and _right inherits IDotRightExpr and (_right to IDotRightExpr).name == 'init' and _left inherits ThisOrBaseLit 
    43394339                                # Well, in practice this doesn't really happen because Constructer.innerWriteSharpDef usurps the code gen for base calls 
     
    44164416                        t = right.containedType to ! 
    44174417                else if right inherits IdentifierExpr 
    4418                         t = right.definition to IType 
     4418                        t = right.namedDefinition to IType 
    44194419                else 
    44204420                        throw FallThroughException(t) 
  • cobra/trunk/Source/BinaryOpExpr.cobra

    r1762 r1763  
    7373        var _left as Expr 
    7474        var _right as Expr 
    75         var _definition as IMember? 
    7675 
    7776        def init(opToken as IToken, op as String, left as Expr, right as Expr) 
     
    8887 
    8988        get right from var 
    90  
    91         pro definition from var 
    9289 
    9390        get hasError as bool 
     
    161158                        .throwError('There is no type for the right hand side of "[.token.text]"[append] [sugg]') 
    162159 
    163         def addRefFields 
    164                 base.addRefFields 
    165                 .addField('definition', _definition) 
    166  
    167160        def addSubFields 
    168161                base.addSubFields 
     
    198191                        if _left inherits NameExpr 
    199192                                _trackLocal = _left.definition inherits AbstractLocalVar 
    200                                 if _trackLocal 
    201                                         _trackName  = _left.definition.name 
     193                                if _trackLocal, _trackName = _left.namedDefinition.name 
    202194 
    203195 
     
    232224                assert right.type 
    233225                if left inherits IdentifierExpr 
    234                         if left.definition is nil 
     226                        if left.namedDefinition is nil 
    235227                                # type inference 
    236228                                assert right.type 
     
    259251                        okay = false 
    260252                        if left inherits IdentifierExpr 
    261                                 if (defi = left.definition) inherits IVar 
     253                                if (defi = left.namedDefinition) inherits IVar 
    262254                                        if defi.attemptAssignmentOf(right.type to !) 
    263255                                                _backUpIfInheritsStack = List<of IType>(defi.ifInheritsStack)  # will need this later for code gen 
     
    270262        def checkAfterBindImp 
    271263                base.checkAfterBindImp 
    272                 if _left inherits IdentifierExpr 
    273                         assert _left.definition 
    274                         if _left.definition inherits Param 
    275                                 if _right inherits IdentifierExpr 
    276                                         if _right.definition inherits BoxVar 
    277                                                 # the exception to this warning is when the statement is guarded by an if which references the _left.definition, as in: if param is nil; param = _param 
    278                                                 # TODO: this has a test case that generates no warnings. so the cobra test cases should probably barf on unexpected warnings 
    279                                                 isException = false 
    280                                                 if .parent inherits BlockStmt and (.parent to BlockStmt).parent inherits IfStmt 
    281                                                         ifStmt = (.parent to BlockStmt).parent to IfStmt 
    282                                                         if (bop = ifStmt.cond) inherits BinaryOpExpr 
    283                                                                 if (bop.left inherits NameExpr) and (bop.left to NameExpr).definition is _left.definition 
    284                                                                         isException = true 
    285                                                                 if (bop.right inherits NameExpr) and (bop.right to NameExpr).definition is _right.definition 
    286                                                                         isException = true 
    287                                                 if not isException 
    288                                                         leftName = (_left.definition to Param).name 
    289                                                         rightName = (_right.definition to BoxVar).name 
    290                                                         .compiler.warning(this, 'Setting a parameter ("[leftName]") to a class variable ("[rightName]") is often a mistake. You may want to reverse the assignment.') 
     264                if not .hasError and _left.definition inherits Param 
     265                        if _right.definition inherits BoxVar 
     266                                # the exception to this warning is when the statement is guarded by an if which references the _left.definition, as in: if param is nil; param = _param 
     267                                # TODO: this has a test case that generates no warnings. so the cobra test cases should probably barf on unexpected warnings 
     268                                isException = false 
     269                                if .parent inherits BlockStmt and (.parent to BlockStmt).parent inherits IfStmt 
     270                                        ifStmt = (.parent to BlockStmt).parent to IfStmt 
     271                                        if (bop = ifStmt.cond) inherits BinaryOpExpr 
     272                                                if bop.left.definition is _left.definition, isException = true 
     273                                                else if bop.right.definition is _right.definition, isException = true 
     274                                if not isException 
     275                                        leftName = _left.definition.name 
     276                                        rightName = _right.definition.name 
     277                                        .compiler.warning(this, 'Setting a parameter ("[leftName]") to a class variable ("[rightName]") is often a mistake. You may want to reverse the assignment.') 
    291278 
    292279 
     
    592579                        _dotRightExpr = right to IDotRightExpr 
    593580 
     581        get definition is override 
     582                """ 
     583                The definition of a DotExpr is the definition of its .right which will be 
     584                a CallExpr or MemberExpr (via the interface IDotRightExpr). 
     585                """ 
     586                return .right.definition 
     587 
    594588        get dotRight as IDotRightExpr 
    595589                """ 
     
    618612                else if not _left.hasError and not _right.hasError 
    619613                        if _left inherits IdentifierExpr  # TODO: seems flawed. The error below should take place if left is a DotExpr 
    620                                 if _left.definition inherits Box # CC: combine with above if statement 
     614                                if _left.namedDefinition inherits Box # CC: combine with above if statement 
    621615                                        if _dotRightExpr.member is not nil and not _dotRightExpr.member.isShared  # when _dotRightExpr.member is nil, it's a nested type 
    622616                                                if _dotRightExpr.name == 'init' 
     
    634628                                _transformTo(TypeExpr(.token, .definition to IType).bindImp) 
    635629                        else if (right = .right) inherits CallExpr 
    636                                 if right.definition implements IType 
     630                                if right.memberDefinition implements IType 
    637631                                        # A.B.C() where C is a type such as a class or struct 
    638                                         te = TypeExpr(.token, right.definition to IType) 
     632                                        te = TypeExpr(.token, right.memberDefinition to IType) 
    639633                                        te.bindImp 
    640634                                        pc = PostCallExpr(right.token, te, right.args) 
     
    668662                # overridden to return the type this dotted expr represents in those cases when it does represent a type 
    669663                assert .didBindImp 
    670                 if _definition inherits IType 
    671                         return _definition 
     664                if .definition inherits IType 
     665                        return .definition 
    672666                else 
    673667                        return nil 
     
    763757                                        if not okay 
    764758                                                .compiler.warning(this, 'The expression (of type "[leftType.name]") is never of type "[.right.toCobraSource]".') 
    765                 if (right = .right) inherits IdentifierExpr  # TODO: change to IPotentialTypeExpr and make a test case first 
    766                         defi = right.definition 
    767                         if defi 
    768                                 if defi inherits Class 
    769                                         if .op <> 'INHERITS' 
    770                                                 .throwError('Use the "inherits" operator when testing objects against classes.') 
    771                                 else if defi inherits Struct 
    772                                         if .op <> 'INHERITS' 
    773                                                 .throwError('Use the "inherits" operator when testing objects against structs.') 
    774                                 else if defi inherits Interface 
    775                                         pass 
    776                                         #if .op <> 'IMPLEMENTS' 
    777                                         #       .throwError('Use the "implements" operator when testing objects against interfaces.') 
    778                                 else if defi inherits GenericParam 
    779                                         pass 
    780                                 else 
    781                                         .throwError('Cannot test "[.op.toLower]" against a [(defi to dynamic).englishName].') 
     759                defi = .right.definition 
     760                if defi inherits Class 
     761                        if .op <> 'INHERITS', .throwError('Use the "inherits" operator when testing objects against classes.') 
     762                else if defi inherits Struct 
     763                        if .op <> 'INHERITS', .throwError('Use the "inherits" operator when testing objects against structs.') 
     764                else if defi inherits Interface 
     765                        # got annoying: 
     766                        # if .op <> 'IMPLEMENTS', .throwError('Use the "implements" operator when testing objects against interfaces.') 
     767                        pass 
     768                else if defi inherits GenericParam 
     769                        pass 
     770                else if defi 
     771                        .throwError('Cannot test "[.op.toLower]" against a [defi.englishName].') 
    782772 
    783773 
  • cobra/trunk/Source/Expr.cobra

    r1741 r1763  
    1010        To see what really makes an expression, see the Expr class. 
    1111        """ 
     12 
     13        get definition 
     14                """ 
     15                Returns the definition corresponding to this expression. 
     16                Dynamically typed. 
     17                Returns nil by default. 
     18                Not all expressions have definitions. 
     19                """ 
     20 
    1221        def toCobraSource as String 
    1322 
     
    5665                base.addRefFields 
    5766                .addField('type', _type) 
     67                if .definition, .addField('definition', .definition) 
    5868 
    5969        pro argumentLabel from var 
     
    6171                Indicates the label for an argument such as 'out' or 'inout'. 
    6272                """ 
     73 
     74        get definition 
     75                return nil 
    6376 
    6477        get willChangeVar as bool 
     
    264277                .addField('name', _name) 
    265278 
    266         def addRefFields 
    267                 base.addRefFields 
    268                 .addField('definition', _definition) 
    269  
    270         get definition from var 
     279        get definition is override 
     280                return _definition 
     281 
     282        get namedDefinition from _definition 
    271283 
    272284        get name from var 
     
    274286        def memberForName(name as String) as IMember? is override 
    275287                or require 
    276                         .definition 
     288                        .namedDefinition 
    277289                body 
    278290                        return _definition.typeForReceiver.memberForName(name) 
     
    365377        var _args as List<of Expr> 
    366378        var _hasParens as bool 
    367         var _definition as INamedNode? 
     379        var _definition as INamedNode?  # TODO: could tighten this down to IMember right?s 
    368380 
    369381        def init(token as IToken, name as String, args as List<of Expr>, hasParens as bool) 
     
    382394                .addField('name', _name) 
    383395 
    384         def addRefFields is override 
    385                 base.addRefFields 
    386                 .addField('definition', _definition) 
    387  
    388396        def addSubFields is override 
    389397                base.addSubFields 
     
    414422                has Subnodes 
    415423 
    416         get definition from var 
     424        get definition is override 
     425                return _definition 
     426 
     427        get memberDefinition from _definition 
    417428 
    418429        get member as IMember? 
     
    484495                assert _type, _definition 
    485496                if .args.count == 0 and .hasParens 
     497                        # TODO: 
     498                        # if .definition inherits BoxMember and .definition.isMethod and not dotNode.isImplicit 
    486499                        if (.definition inherits Method or .definition inherits MemberOverload) and not dotNode.isImplicit 
    487500                                .compiler.warning(this, 'Unnecessary parentheses. You can remove them.') 
     
    741754                has Subnodes 
    742755         
    743         get definition from var 
     756        get definition is override 
     757                return _definition 
     758 
     759        get enumDefinition from _definition 
    744760         
    745761        get hasError as bool is override 
    746                 if base.hasError 
    747                         return true 
    748                 for arg in _args 
    749                         if arg.hasError 
    750                                 return true 
     762                if base.hasError, return true 
     763                for arg in _args, if arg.hasError, return true 
    751764                return false 
    752765 
     
    828841                if _nameExpr.definition 
    829842                        if _nameExpr.definition inherits IVar 
    830                                 _var = _nameExpr.definition to IVar 
     843                                _var = _nameExpr.definition 
    831844                        else 
    832845                                .throwError('Expecting a variable not a [_nameExpr.definition.getType.name].')  # TODO: what's the best way to report what was found? 
     
    10711084                .addField('args', _args) 
    10721085 
    1073         get definition from var 
     1086        get definition is override 
     1087                return _definition 
     1088 
     1089        get memberDefinition from _definition 
    10741090 
    10751091        get target from var 
     
    12621278                .addField('isReference', _isReference) 
    12631279 
    1264         def addRefFields is override 
    1265                 base.addRefFields 
    1266                 .addField('definition', _definition) 
    1267  
    12681280        get args as List<of Expr> 
    12691281                return List<of Expr>() 
    12701282 
    1271         get definition from var 
     1283        get definition is override 
     1284                return _definition 
     1285 
     1286        get memberDefinition from _definition 
    12721287 
    12731288        pro isReference from var 
     
    13291344                        # TODO: there should be a subclass of BinaryOpExpr called DotExpr and it should do the following work and maybe even the work above. 
    13301345                        # TODO: _receiverType = receiverType 
    1331                         .binarySuperNode.definition = _definition  # TODO: is this needed? 
    13321346                        .binarySuperNode.type = .type  # the type of foo.bar is what bar returns. A MemberExpr is the "bar" part. 
    13331347                        .binarySuperNode.receiverType = receiverType 
     
    15171531                expr = expr.bindImp 
    15181532 
    1519                 if expr inherits IdentifierExpr 
    1520                         if expr.definition inherits EnumDecl 
    1521                                 enumCall = EnumCallExpr(.token, expr.name, .args, expr.definition to EnumDecl).bindImp 
    1522                                 _type = enumCall.type to IType 
    1523                                 _transformTo(enumCall) 
    1524                                 return                                   
     1533                if expr.definition inherits EnumDecl 
     1534                        enumCall = EnumCallExpr(.token, expr.toCobraSource, .args, expr.definition to EnumDecl).bindImp  # CC: axe cast 
     1535                        _type = enumCall.type to IType 
     1536                        _transformTo(enumCall) 
     1537                        return 
    15251538 
    15261539                for arg in .args 
     
    16781691                        right = _expr.right 
    16791692                        if right inherits MemberExpr 
    1680                                 if right.definition inherits AbstractMethod or right.definition inherits MemberOverload 
    1681                                         right.isReference = true 
    1682                                 else if right.definition is nil 
     1693                                if right.definition is nil 
    16831694                                        # happens from error recovery such as: obj = BadClassName() ... ref obj.foo 
    16841695                                        pass 
     1696                                else if right.definition inherits AbstractMethod or right.definition inherits MemberOverload 
     1697                                        right.isReference = true 
    16851698                                else 
    16861699                                        .throwError('Only methods can be referenced, not [right.definition.englishName].') 
     
    16931706                                pass 
    16941707                        else 
    1695                                 .throwError('Only methods can be referenced, not [Utils.pluralize((_expr.definition to dynamic).englishName)].') 
     1708                                .throwError('Only methods can be referenced, not [Utils.pluralize(_expr.definition.englishName)].') 
    16961709                else 
    16971710                        .throwError('Unexpected reference. Refer to methods after `ref` or remove `ref`.') 
    1698                 _type = .compiler.passThroughType # TODO: Set a real type such as .libraryType('System.Delegate') 
     1711                _type = .compiler.passThroughType # TODO: Set a real type such as .compiler.delegateType 
    16991712                # TODO: need to do something more sophisticated like overriding:        def canBeAssignedTo(type as IType) as bool 
    17001713 
  • cobra/trunk/Source/Statements.cobra

    r1752 r1763  
    8888                        ve.bindImp 
    8989                        assert ve.definition 
    90                         varr = ve.definition to AbstractLocalVar 
     90                        varr = ve.definition 
    9191                else 
    9292                        throw FallThroughException(ve) 
     
    385385                if _varExpr.definition 
    386386                        if _varExpr.definition inherits IVar 
    387                                 _var = _varExpr.definition to IVar 
     387                                _var = _varExpr.definition 
    388388                        else 
    389389                                .throwError('Expecting a variable not a [_varExpr.definition.getType.name].')  # TODO: what's the best way to report what was found? 
     
    677677                                left = cond.left 
    678678                                if left inherits IdentifierExpr 
    679                                         leftVar = left.definition 
     679                                        leftVar = left.namedDefinition 
    680680                                        if leftVar inherits IVar  # if-inherits smarts only work on variables 
    681681                                                # if x inherits Y ... 
     
    689689                                else if left inherits AssignExpr 
    690690                                        if left.left inherits IdentifierExpr 
    691                                                 leftVar = (left.left to IdentifierExpr).definition 
     691                                                leftVar = left.left.definition 
    692692                                                if leftVar inherits IVar 
    693693                                                        # if (x = expr) inherits Y ... 
     
    702702                                if cond inherits TruthExpr 
    703703                                        if cond.expr inherits IdentifierExpr 
    704                                                 leftVar = (cond.expr to IdentifierExpr).definition 
     704                                                leftVar = cond.expr.definition 
    705705                                                leftType = leftVar.typeForIdentifier 
    706706                                                if leftType inherits NilableType or (leftType.isReference and leftType is not .compiler.objectType) 
     
    717717                                                # TODO? "if not x is nil"  "if nil is not x" 
    718718                                                notNil = true 
    719                   &nb