Changeset 1566

Show
Ignore:
Timestamp:
07/31/08 21:19:39 (4 months ago)
Author:
Chuck.Esterbrook
Message:

Added support for omitting "this" and/or EventArgs?() in a "raise" statement.
Also, added warning that "this" is unnecessary and can be removed.
Also, added more error checking.

Location:
cobra/trunk
Files:
4 modified

Legend:

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

    r1564 r1566  
    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. 
    44 
    5 * Added support for declaring and raising events. 
     5* Added support for declaring and raising events. When raising events, passing "this" is implied (e.g., not required) since that is the normal behavior for events. Also, if the events argument has a default constructor, it too can be omitted. 
    66 
    77* Add support for specifying unsigned integers as Hex literals 
  • cobra/trunk/Source/Statements.cobra

    r1562 r1566  
    11721172 
    11731173        var _name = '' 
     1174        var _exprs as List<of Expr> 
     1175 
     1176        # computed in _bindImp 
     1177        var _definition as BoxEvent? 
    11741178        var _eventType as IType? 
    1175         var _exprs as List<of Expr> 
    1176         var _definition as BoxEvent? 
     1179        var _params as List<of Param>? 
     1180        var _args as List<of Expr>? 
    11771181 
    11781182        def init(token as IToken, exprs as List<of Expr>) 
     
    12061210                                        _definition = defi 
    12071211                                        _name = defi.name 
    1208                                         _eventType = defi.handlerType            
     1212                                        _eventType = defi.handlerType 
    12091213                                else 
    12101214                                        .throwError('Expecting an event to raise.') 
     
    12151219                        else 
    12161220                                .throwError('Invalid expression for raising events. Try "raise .someEvent, args" or "throw SomeException(args)".') 
     1221                        if _eventType inherits MethodSig 
     1222                                _params = _eventType.params 
     1223                        else 
     1224                                member = _eventType.memberForName('invoke') 
     1225                                if member inherits Method 
     1226                                        _params = member.params 
     1227                                else 
     1228                                        .throwError('Cannot find a single "invoke" method for "_eventType.name".') 
     1229                        # TODO: check type compatibility of exprs with params 
     1230                        args = _exprs[1:] 
     1231                        params = _params 
     1232                        unThis = 'Unnecessary "this" which is already implied by raising an event. You can remove it.' 
     1233                        if args.count == params.count 
     1234                                if args.count > 0 and args[0] inherits ThisLit 
     1235                                        .compiler.warning(this, unThis) 
     1236                        else if args.count == params.count - 1 
     1237                                # off by one. 
     1238                                if args[0] inherits ThisLit 
     1239                                        .compiler.warning(this, unThis) 
     1240                                        # since we have 'this', try appending the args object 
     1241                                        args.add(_postCallForType(params[params.count-1].type)) 
     1242                                else 
     1243                                        # since we don't have 'this', try prepending 'this' 
     1244                                        args.insert(0, ThisLit(.token, .compiler.boxStack.peek).bindImp) 
     1245                        else if args.count == 0 and params.count == 2 
     1246                                # missing both 'this' and event args 
     1247                                args.add(ThisLit(.token, .compiler.boxStack.peek).bindImp) 
     1248                                args.add(_postCallForType(params[params.count-1].type)) 
     1249                        else 
     1250                                .throwError('Event expects [params.count] arguments, but the "raise" statement is providing [args.count].') 
     1251                        _args = args 
     1252 
     1253        def _postCallForType(type as IType) as PostCallExpr              
     1254                inits = type.memberForName('init') 
     1255                if inits inherits Initializer 
     1256                        if inits.params.count <> 0 
     1257                                .throwError('Missing argument for "raise" of type "[type.name]".') 
     1258                        else 
     1259                                token = .token.copy('ID', type.name) 
     1260                                return PostCallExpr(token, TypeExpr(token, type), List<of Expr>()).bindImp 
     1261                else 
     1262                        .throwError('Missing argument for "raise" of type "[type.name]".') 
     1263                throw FallThroughException() # suppress an error 
    12171264 
    12181265        def writeSharpDef(sw as SharpWriter) 
     
    12201267                name = Utils.capped(.name) 
    12211268                localName = '_lh_event_[.serialNum]' 
     1269                sw.writeLine('// raise [.name] ...') 
    12221270                sw.write('{ [_eventType.sharpRef] [localName] = this.[name]; if ([localName]!=null) [localName](') 
    12231271                sep = '' 
    1224                 # Assuming usual argsList case is 2 args (sender, eventArgs). If have fewer than this 
    1225                 # presume the first arg - sender ('this') -  is elided 
    1226                 # TODO: need to compare to the actual count of the parameter list instead of assuming this 
    1227                 if _exprs.count == 2  
    1228                         sep = 'this, ' 
    1229                 for expr in _exprs[1:] 
     1272                for expr in _args 
    12301273                        sw.write(sep) 
    12311274                        expr.writeSharpDef(sw, false) 
    12321275                        sep = ', ' 
    12331276                sw.write('); }\n') 
    1234                  
     1277 
    12351278 
    12361279class ReturnStmt 
  • cobra/trunk/Tests/220-delegates-etc/120-events/300-raise.cobra

    r1560 r1566  
    55        event click as ClickHandler 
    66 
    7         def receiveMouseClick 
     7        def receiveMouseClick1 
    88                # pretend it's always in our bounds and we're enabled 
    9 #               raise .click(this, EventArgs()) 
    10                 raise .click, this, EventArgs() 
    11 #               raise .click, EventArgs() 
    12 #               raise .click 
    13 #               raise .click, this 
     9                raise .click, this, EventArgs()  # .warning. unnecessary "this" 
     10         
     11        def receiveMouseClick2 
     12                raise .click, EventArgs() 
     13 
     14        def receiveMouseClick3 
     15                raise .click, this  # .warning. unnecessary "this" 
     16 
     17        def receiveMouseClick4 
     18                raise .click 
    1419 
    1520 
     
    1823        shared 
    1924 
    20                 var _didClick = false 
     25                var _butt as Button 
     26                var _clickCount = 0 
    2127                 
    2228                def main 
    23                         butt = Button() 
     29                        butt = _butt = Button() 
     30 
    2431                        listen butt.click, ref .handleClick 
    25                         assert not _didClick 
    26                         butt.receiveMouseClick 
    27                         assert _didClick 
     32                        assert .clickCount == 0 
     33 
     34                        butt.receiveMouseClick1 
     35                        assert .clickCount == 1 
     36 
     37                        butt.receiveMouseClick2 
     38                        assert .clickCount == 2 
     39 
     40                        butt.receiveMouseClick3 
     41                        assert .clickCount == 3 
     42 
     43                        butt.receiveMouseClick4 
     44                        assert .clickCount == 4 
     45 
     46                get clickCount from var 
    2847 
    2948                def handleClick(sender as Object, args as EventArgs) 
    30                         _didClick = true 
     49                        assert sender is _butt 
     50                        assert (args to dynamic?) inherits EventArgs 
     51                        _clickCount += 1 
  • cobra/trunk/Tests/220-delegates-etc/120-events/304-raise-protected.cobra

    r1562 r1566  
    55        event _click as ClickHandler 
    66 
    7         def addClickHandler( clickhdlr as ClickHandler) 
     7        def addClickHandler(clickhdlr as ClickHandler) 
    88                listen _click, clickhdlr 
    99                 
    1010        def _onMouseClick 
    1111                # pretend it's always in our bounds and we're enabled 
    12 #               raise .click(this, EventArgs()) 
    13                 raise _click, this, EventArgs() 
    14 #               raise .click, EventArgs() 
    15 #               raise .click 
    16 #               raise .click, this 
     12                raise _click, EventArgs() 
    1713 
    1814        def receiveMouseClick 
    1915                _onMouseClick 
     16 
    2017 
    2118class Program