Changeset 1560

Show
Ignore:
Timestamp:
07/30/08 02:34:05 (4 months ago)
Author:
Chuck.Esterbrook
Message:

Added support for declaring and raising events.

Location:
cobra/trunk
Files:
1 added
5 modified

Legend:

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

    r1549 r1560  
    22 
    33* 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 
     5* Added support for declaring and raising events. 
    46 
    57* Add support for specifying unsigned integers as Hex literals 
  • cobra/trunk/Source/Boxes.cobra

    r1553 r1560  
    18241824                sig ComputeSomething(a is int, b as int) as int 
    18251825 
    1826         .NET's calls these delegates and describes them as type-safe method signatures. 
     1826        .NET calls these delegates and describes them as type-safe method signatures. 
    18271827        The "sig" keyword fits nicely with other declaration keywords like "var" "def" and "get". 
    18281828        And "sig" is a more platform neutral term should we have other non-CLI backends. 
  • cobra/trunk/Source/CobraParser.cobra

    r1553 r1560  
    851851                return theStruct 
    852852 
     853        def eventDecl as BoxEvent 
     854                token = .expect('EVENT') 
     855                name = .expect('ID').value to String 
     856                .expect('AS') 
     857                handlerType = .typeId 
     858                # ahem, duplicated from .boxVarDecl 
     859                docString = '' to ? 
     860                isNames = List<of String>(_isNamesStack) 
     861                if .peek.which=='IS' 
     862                        isNames = .isDeclNames 
     863                        attribs = .hasAttribs 
     864                        assert .last.which=='EOL' 
     865                        .undo  # need the EOL 
     866                        if .optionalIndent 
     867                                docString = .docString 
     868                                .dedent 
     869                else if .optionalIndent 
     870                        isNames = .isDeclNames 
     871                        attribs = .hasAttribs 
     872                        docString = .docString 
     873                        .dedent 
     874                else 
     875                        attribs = AttributeList() 
     876                return BoxEvent(token, .curBox, name, isNames, attribs, docString, handlerType) 
     877 
    853878        def enumDecl as EnumDecl 
    854879                token = .expect('ENUM') 
     
    10231048                                        on 'EOL', .endOfLine 
    10241049                                        on 'ENUM', .addDecl(box, .enumDecl) 
     1050                                        on 'EVENT', .addDecl(box, .eventDecl) 
    10251051                                        on 'SIG', .addDecl(box, .declareMethodSig) 
    10261052                                        on 'SHARED', .bodiedBoxMemberDeclsShared(box) 
     
    10941120                                docString = .docString 
    10951121                                .dedent 
    1096                 else 
    1097                         if .optionalIndent 
    1098                                 isNames = .isDeclNames 
    1099                                 attribs = .hasAttribs 
    1100                                 docString = .docString 
    1101                                 .dedent 
     1122                else if .optionalIndent 
     1123                        isNames = .isDeclNames 
     1124                        attribs = .hasAttribs 
     1125                        docString = .docString 
     1126                        .dedent 
    11021127                return BoxVar(tok, .curBox, identifier, type, isNames, initExpr, docString) 
    11031128 
     
    20362061 
    20372062        def raiseStmt as Stmt 
    2038                 .expect('RAISE') 
    2039                 .throwError('The "raise" keyword may be used in the future to raise events. If you are trying to throw an exception, use the "throw" keyword.') 
    2040                 return nil to passthrough # CC: throw FallThroughException() 
     2063                token = .expect('RAISE') 
     2064                exprs = .commaSepExprs('EOL') 
     2065                if exprs.count == 0 
     2066                        .throwError('Expecting one or more expressions after "raise", starting with the event. If you meant to throw the currently caught exception, use "throw" instead.') 
     2067                return RaiseStmt(token, exprs) 
    20412068 
    20422069        def returnStmt as Stmt 
  • cobra/trunk/Source/Members.cobra

    r1557 r1560  
    119119                Returns true if the class member has one or more parameters defined. 
    120120                """ 
    121                 return false 
     121                return .params.count > 0 
    122122 
    123123        get params as List<of Param> 
     
    391391        get handlerTypeProxy from var 
    392392 
     393        get isCallable as bool is override 
     394                return true 
     395 
     396        get params as List<of Param> is override 
     397                assert .didBindInt 
     398                if _handlerType inherits MethodSig 
     399                        return _handlerType.params 
     400                else if _handlerType inherits Class 
     401                        method = _handlerType.memberForName('invoke') 
     402                        if method inherits AbstractMethod 
     403                                return method.params 
     404                        else 
     405                                .compiler.warning(this, 'Cannot locate a single invoke method of "[_handlerType.name]".') 
     406                                return List<of Param>()                  
     407                else 
     408                        if not .hasError 
     409                                .compiler.warning(this, 'Cannot determine parameters of event "[.name]".') 
     410                        return List<of Param>()                  
     411 
    393412        get resultType as IType is override 
    394413                return .handlerType to ! 
     
    405424                # TODO: error check that _handlerType is a delegate 
    406425                # _handlerType.isDescendantOf(.compiler.libraryType('System.Delegate')) 
     426 
     427        get sharpName as String is override 
     428                return Utils.capped(.name) 
     429 
     430        def writeSharpDef(sw as SharpWriter) is override 
     431                base.writeSharpDef(sw) 
     432                .writeSharpAttribs(sw) 
     433                .writeSharpIsNames(sw) 
     434                sw.write(.handlerType.sharpRef) 
     435                sw.write(' [.sharpName]') 
     436                sw.write(';\n') 
    407437 
    408438 
     
    599629                _locals = List<of LocalVar>() 
    600630                _stmts = List<of Stmt>() 
    601  
    602         get hasParams as bool is override 
    603                 return _params.count > 0 
    604631 
    605632        get params as List<of Param> is override 
  • cobra/trunk/Source/Statements.cobra

    r1553 r1560  
    11611161 
    11621162 
     1163class RaiseStmt 
     1164        inherits Stmt 
     1165        """ 
     1166        Raise an event. 
     1167         
     1168        TODO: give a good error message for the case where the user is trying to raise an exception 
     1169        TODO: test raising an inherited event, either from source or from binary 
     1170        TODO: support missing arguments such as 'this' and 'EventArgs()' 
     1171        """ 
     1172 
     1173        var _name = '' 
     1174        var _exprs as List<of Expr> 
     1175        var _definition as BoxEvent? 
     1176 
     1177        def init(token as IToken, exprs as List<of Expr>) 
     1178                require exprs.count > 0 
     1179                base.init(token) 
     1180                _exprs = exprs 
     1181 
     1182        def addSubFields 
     1183                base.addSubFields 
     1184                .addField('exprs', _exprs) 
     1185 
     1186        get name from var 
     1187 
     1188        get exprs from var 
     1189 
     1190        def _bindImp 
     1191                base._bindImp 
     1192                hasError = false 
     1193                for expr in _exprs 
     1194                        try 
     1195                                expr.bindImp 
     1196                        catch ne as NodeException 
     1197                                .compiler.recordError(ne) 
     1198                                hasError = true 
     1199                if not hasError 
     1200                        expr = _exprs[0] 
     1201                        if expr inherits DotExpr 
     1202                                right = expr.right 
     1203                                if right inherits IDotRightExpr 
     1204                                        defi = (right to dynamic).definition 
     1205                                        if defi inherits BoxEvent 
     1206                                                _definition = defi 
     1207                                                _name = defi.name 
     1208                                        else 
     1209                                                .throwError('Expecting an event to raise.') 
     1210                                else 
     1211                                        assert false # should be impossible to get here since it was a dotexpr 
     1212                        else 
     1213                                .throwError('Invalid expression for raising events. Try "raise .someEvent, args" or "throw SomeException(args)".') 
     1214 
     1215        def writeSharpDef(sw as SharpWriter) 
     1216                base.writeSharpDef(sw) 
     1217                name = Utils.capped(.name) 
     1218                sw.write('if (this.[name]!=null) this.[name](') 
     1219                sep = '' 
     1220                for expr in _exprs[1:] 
     1221                        sw.write(sep) 
     1222                        expr.writeSharpDef(sw, false) 
     1223                        sep = ', ' 
     1224                sw.write(');\n') 
     1225 
     1226 
    11631227class ReturnStmt 
    11641228        inherits Stmt 
     
    11741238                base.addSubFields 
    11751239                .addField('expr', _expr) 
     1240 
     1241        get expr from var 
    11761242 
    11771243        pro sharpResultVarName from var