| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * A simple code analyzer for Dart. | 6 * A simple code analyzer for Dart. |
| 7 * | 7 * |
| 8 * Currently used to ensure all concrete generic types are visited. | 8 * Currently used to ensure all concrete generic types are visited. |
| 9 * Also performs all static type checks - so these don't need to be | 9 * Also performs all static type checks - so these don't need to be |
| 10 * done in later phases. | 10 * done in later phases. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 thisValue = new PureStaticValue(method.declaringType, null); | 39 thisValue = new PureStaticValue(method.declaringType, null); |
| 40 } | 40 } |
| 41 var values = []; | 41 var values = []; |
| 42 for (var p in method.parameters) { | 42 for (var p in method.parameters) { |
| 43 values.add(new PureStaticValue(p.type, null)); | 43 values.add(new PureStaticValue(p.type, null)); |
| 44 } | 44 } |
| 45 var args = new Arguments(null, values); | 45 var args = new Arguments(null, values); |
| 46 | 46 |
| 47 _frame = new CallFrame(this, method, thisValue, args, context); | 47 _frame = new CallFrame(this, method, thisValue, args, context); |
| 48 _bindArguments(_frame.args); | 48 _bindArguments(_frame.args); |
| 49 body.visit(this); | 49 |
| 50 // Visit the super or this call in a constructor, if any. |
| 51 final declaredInitializers = method.definition.dynamic.initializers; |
| 52 if (declaredInitializers != null) { |
| 53 for (var init in declaredInitializers) { |
| 54 if (init is CallExpression) { |
| 55 visitCallExpression(init, true); |
| 56 } |
| 57 } |
| 58 } |
| 59 |
| 60 if (body != null) body.visit(this); |
| 50 } | 61 } |
| 51 | 62 |
| 52 /* Checks whether or not a particular TypeReference Node includes references | 63 /* Checks whether or not a particular TypeReference Node includes references |
| 53 * to type parameters. */ | 64 * to type parameters. */ |
| 54 bool _hasTypeParams(node) { | 65 bool _hasTypeParams(node) { |
| 55 if (node is NameTypeReference) { | 66 if (node is NameTypeReference) { |
| 56 var name = node.name.name; | 67 var name = node.name.name; |
| 57 return (method.declaringType.lookupTypeParam(name) != null); | 68 return (method.declaringType.lookupTypeParam(name) != null); |
| 58 } else if (node is GenericTypeReference) { | 69 } else if (node is GenericTypeReference) { |
| 59 for (var typeArg in node.typeArguments) { | 70 for (var typeArg in node.typeArguments) { |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 visitLambdaExpression(LambdaExpression node) { | 398 visitLambdaExpression(LambdaExpression node) { |
| 388 var name = (node.func.name != null) ? node.func.name.name : ''; | 399 var name = (node.func.name != null) ? node.func.name.name : ''; |
| 389 | 400 |
| 390 MethodMember meth = _makeLambdaMethod(name, node.func); | 401 MethodMember meth = _makeLambdaMethod(name, node.func); |
| 391 // TODO(jimhug): Worry about proper scope for recursive lambda. | 402 // TODO(jimhug): Worry about proper scope for recursive lambda. |
| 392 meth.methodData.analyze(); | 403 meth.methodData.analyze(); |
| 393 | 404 |
| 394 return _frame._makeValue(world.functionType, node); | 405 return _frame._makeValue(world.functionType, node); |
| 395 } | 406 } |
| 396 | 407 |
| 397 Value visitCallExpression(CallExpression node) { | 408 analyzeInitializerConstructorCall(CallExpression node, |
| 409 Expression receiver, |
| 410 String name) { |
| 411 var type = _frame.method.declaringType; |
| 412 if (receiver is SuperExpression) { |
| 413 type = type.parent; |
| 414 } |
| 415 var member = type.getConstructor(name == null ? '' : name); |
| 416 if (member !== null) { |
| 417 return member.invoke(_frame, node, _frame.makeThisValue(node), |
| 418 _visitArgs(node.arguments)); |
| 419 } else { |
| 420 String constructorName = name == null ? '' : '.$name'; |
| 421 world.warning('cannot find constructor "${type.name}$constructorName"', |
| 422 node.span); |
| 423 return _frame._makeValue(world.varType, node); |
| 424 } |
| 425 } |
| 426 |
| 427 bool isThisOrSuper(Expression node) { |
| 428 return node is ThisExpression || node is SuperExpression; |
| 429 } |
| 430 |
| 431 Value visitCallExpression(CallExpression node, |
| 432 [bool visitingInitializers = false]) { |
| 398 var target; | 433 var target; |
| 399 var position = node.target; | 434 var position = node.target; |
| 400 var name = ':call'; | 435 var name = ':call'; |
| 401 if (node.target is DotExpression) { | 436 if (node.target is DotExpression) { |
| 402 DotExpression dot = node.target; | 437 DotExpression dot = node.target; |
| 403 target = dot.self.visit(this); | 438 target = dot.self.visit(this); |
| 404 name = dot.name.name; | 439 name = dot.name.name; |
| 405 position = dot.name; | 440 if (isThisOrSuper(dot.self) && visitingInitializers) { |
| 441 return analyzeInitializerConstructorCall(node, dot.self, name); |
| 442 } else { |
| 443 position = dot.name; |
| 444 } |
| 445 } else if (isThisOrSuper(node.target) && visitingInitializers) { |
| 446 return analyzeInitializerConstructorCall(node, node.target, null); |
| 406 } else if (node.target is VarExpression) { | 447 } else if (node.target is VarExpression) { |
| 407 VarExpression varExpr = node.target; | 448 VarExpression varExpr = node.target; |
| 408 name = varExpr.name.name; | 449 name = varExpr.name.name; |
| 409 // First check in block scopes. | 450 // First check in block scopes. |
| 410 target = _frame.lookup(name); | 451 target = _frame.lookup(name); |
| 411 if (target != null) { | 452 if (target != null) { |
| 412 return target.get(position).invoke(_frame, ':call', node, | 453 return target.get(position).invoke(_frame, ':call', node, |
| 413 _visitArgs(node.arguments)); | 454 _visitArgs(node.arguments)); |
| 414 } | 455 } |
| 415 | 456 |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 741 for (var item in node.pieces) { | 782 for (var item in node.pieces) { |
| 742 var val = visitValue(item); | 783 var val = visitValue(item); |
| 743 var sval = val.invoke(_frame, 'toString', item, Arguments.EMPTY); | 784 var sval = val.invoke(_frame, 'toString', item, Arguments.EMPTY); |
| 744 ret = ret.binop(TokenKind.ADD, sval, _frame, item); | 785 ret = ret.binop(TokenKind.ADD, sval, _frame, item); |
| 745 } | 786 } |
| 746 return _frame._makeValue(world.stringType, node); //???ret; | 787 return _frame._makeValue(world.stringType, node); //???ret; |
| 747 */ | 788 */ |
| 748 } | 789 } |
| 749 } | 790 } |
| 750 | 791 |
| OLD | NEW |