Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(262)

Side by Side Diff: dart/frog/analyze.dart

Issue 9325029: Fix for issue 1480: analyze a method even if it does not have a body, and do not try to evaluate ... (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | dart/frog/gen.dart » ('j') | dart/frog/gen.dart » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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.
11 * 11 *
12 * Ultimately, this should include abstract interpreter work. This will 12 * Ultimately, this should include abstract interpreter work. This will
13 * result in an interesting split beteen this class and MethodGenerator 13 * result in an interesting split beteen this class and MethodGenerator
14 * which should be turned into nothing more than a code generator. 14 * which should be turned into nothing more than a code generator.
15 */ 15 */
16 // TODO(jimhug): This class shares too much code with MethodGenerator. 16 // TODO(jimhug): This class shares too much code with MethodGenerator.
17 class MethodAnalyzer implements TreeVisitor { 17 class MethodAnalyzer implements TreeVisitor {
18 MethodMember method; 18 MethodMember method;
19 Statement body; 19 Statement body;
20 20
21 CallFrame _frame; 21 CallFrame _frame;
22 22
23 /** 23 /**
24 * Track whether or not [body] refers to any type parameters from the 24 * Track whether or not [body] refers to any type parameters from the
25 * enclosing type to advise future code generation and analysis. 25 * enclosing type to advise future code generation and analysis.
26 */ 26 */
27 bool hasTypeParams = false; 27 bool hasTypeParams = false;
28 bool visitingInitializers = false;
28 29
29 MethodAnalyzer(this.method, this.body); 30 MethodAnalyzer(this.method, this.body);
30 31
31 // TODO(jimhug): Type issue with requiring CallFrame here... 32 // TODO(jimhug): Type issue with requiring CallFrame here...
32 void analyze(CallFrame context) { 33 void analyze(CallFrame context) {
33 var thisValue; 34 var thisValue;
34 // TODO(jimhug): Move Constructor analysis to here and below. 35 // TODO(jimhug): Move Constructor analysis to here and below.
35 36
36 if (context != null) { 37 if (context != null) {
37 thisValue = context.thisValue; 38 thisValue = context.thisValue;
38 } else { 39 } else {
39 thisValue = new PureStaticValue(method.declaringType, null); 40 thisValue = new PureStaticValue(method.declaringType, null);
40 } 41 }
41 var values = []; 42 var values = [];
42 for (var p in method.parameters) { 43 for (var p in method.parameters) {
43 values.add(new PureStaticValue(p.type, null)); 44 values.add(new PureStaticValue(p.type, null));
44 } 45 }
45 var args = new Arguments(null, values); 46 var args = new Arguments(null, values);
46 47
47 _frame = new CallFrame(this, method, thisValue, args, context); 48 _frame = new CallFrame(this, method, thisValue, args, context);
48 _bindArguments(_frame.args); 49 _bindArguments(_frame.args);
49 body.visit(this); 50
51 final declaredInitializers = method.definition.dynamic.initializers;
kasperl 2012/02/03 15:39:20 Add a comment here that explains how this is dealt
ngeoffray 2012/02/06 11:50:31 Done.
52 var initializerCall = null;
53 if (declaredInitializers != null) {
54 visitingInitializers = true;
55 for (var init in declaredInitializers) {
56 if (init is CallExpression) {
kasperl 2012/02/03 15:39:20 How bad would it be to add an optional parameter t
ngeoffray 2012/02/06 11:50:31 Done.
57 init.visit(this);;
kasperl 2012/02/03 15:39:20 ;; -> ;
ngeoffray 2012/02/06 11:50:31 Done.
58 }
59 }
60 visitingInitializers = false;
61 }
62
63 if (body != null) body.visit(this);
50 } 64 }
51 65
52 /* Checks whether or not a particular TypeReference Node includes references 66 /* Checks whether or not a particular TypeReference Node includes references
53 * to type parameters. */ 67 * to type parameters. */
54 bool _hasTypeParams(node) { 68 bool _hasTypeParams(node) {
55 if (node is NameTypeReference) { 69 if (node is NameTypeReference) {
56 var name = node.name.name; 70 var name = node.name.name;
57 return (method.declaringType.lookupTypeParam(name) != null); 71 return (method.declaringType.lookupTypeParam(name) != null);
58 } else if (node is GenericTypeReference) { 72 } else if (node is GenericTypeReference) {
59 for (var typeArg in node.typeArguments) { 73 for (var typeArg in node.typeArguments) {
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 visitLambdaExpression(LambdaExpression node) { 401 visitLambdaExpression(LambdaExpression node) {
388 var name = (node.func.name != null) ? node.func.name.name : ''; 402 var name = (node.func.name != null) ? node.func.name.name : '';
389 403
390 MethodMember meth = _makeLambdaMethod(name, node.func); 404 MethodMember meth = _makeLambdaMethod(name, node.func);
391 // TODO(jimhug): Worry about proper scope for recursive lambda. 405 // TODO(jimhug): Worry about proper scope for recursive lambda.
392 meth.methodData.analyze(); 406 meth.methodData.analyze();
393 407
394 return _frame._makeValue(world.functionType, node); 408 return _frame._makeValue(world.functionType, node);
395 } 409 }
396 410
411 analyzeThisOrSuperConstructorCall(CallExpression node,
kasperl 2012/02/03 15:39:20 analyzeInitializerConstructorCall instead? In this
ngeoffray 2012/02/06 11:50:31 Done.
412 Expression receiver,
413 String name) {
414 var type = _frame.method.declaringType;
415 if (receiver is SuperExpression) {
416 type = type.parent;
417 }
418 var member = type.getConstructor(name);
419 if (member !== null) {
420 return member.invoke(_frame, node, _frame.makeThisValue(node),
421 _visitArgs(node.arguments));
422 } else {
423 world.warning('cannot find "$name"', node.span);
kasperl 2012/02/03 15:39:20 How does this look if name is the empty string? Ma
ngeoffray 2012/02/06 11:50:31 Done.
424 return _frame._makeValue(world.varType, node);
425 }
426 }
427
428 bool isThisOrSuper(Expression node) {
429 return node is ThisExpression || node is SuperExpression;
430 }
431
397 Value visitCallExpression(CallExpression node) { 432 Value visitCallExpression(CallExpression node) {
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 analyzeThisOrSuperConstructorCall(node, dot.self, name);
442 } else {
443 position = dot.name;
444 }
445 } else if (isThisOrSuper(node.target) && visitingInitializers) {
446 return analyzeThisOrSuperConstructorCall(node, node.target, '');
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
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
OLDNEW
« no previous file with comments | « no previous file | dart/frog/gen.dart » ('j') | dart/frog/gen.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698