Show
Ignore:
Timestamp:
07/31/08 21:19:39 (5 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.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • 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