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

Side by Side Diff: frog/gen.dart

Issue 8497064: Fix method resolution to warn about things that don't exist on the declared type. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 9 years, 1 month 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 | « frog/frogsh ('k') | frog/lib/corelib.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 * Top level generator object for writing code and keeping track of 6 * Top level generator object for writing code and keeping track of
7 * dependencies. 7 * dependencies.
8 * 8 *
9 * Should have two compilation models, but only one implemented so far. 9 * Should have two compilation models, but only one implemented so far.
10 * 10 *
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 } else { 353 } else {
354 writer.writeln('var ${global.name} = ${global.exp.code};'); 354 writer.writeln('var ${global.name} = ${global.exp.code};');
355 } 355 }
356 } 356 }
357 } 357 }
358 358
359 /** Order a list of values in a Map by SourceSpan, then by name. */ 359 /** Order a list of values in a Map by SourceSpan, then by name. */
360 List _orderValues(Map map) { 360 List _orderValues(Map map) {
361 // TODO(jmesserly): should we copy the list? 361 // TODO(jmesserly): should we copy the list?
362 // Right now, the Maps are returning a copy already. 362 // Right now, the Maps are returning a copy already.
363 final values = map.getValues(); 363 List values = map.getValues();
364 values.sort(_compareMembers); 364 values.sort(_compareMembers);
365 return values; 365 return values;
366 } 366 }
367 367
368 int _compareMembers(x, y) { 368 int _compareMembers(x, y) {
369 if (x.span != null && y.span != null) { 369 if (x.span != null && y.span != null) {
370 // First compare by source span. 370 // First compare by source span.
371 int spans = x.span.compareTo(y.span); 371 int spans = x.span.compareTo(y.span);
372 if (spans != 0) return spans; 372 if (spans != 0) return spans;
373 } 373 }
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 : writer = new CodeWriter(), needsThis = false { 565 : writer = new CodeWriter(), needsThis = false {
566 if (enclosingMethod != null) { 566 if (enclosingMethod != null) {
567 _scope = new BlockScope(this, enclosingMethod._scope); 567 _scope = new BlockScope(this, enclosingMethod._scope);
568 captures = new Set(); 568 captures = new Set();
569 } else { 569 } else {
570 _scope = new BlockScope(this, null); 570 _scope = new BlockScope(this, null);
571 } 571 }
572 // For named lambdas, add the name to this scope so we can call it 572 // For named lambdas, add the name to this scope so we can call it
573 // recursively. 573 // recursively.
574 if (enclosingMethod != null && method.name != '') { 574 if (enclosingMethod != null && method.name != '') {
575 _scope.create(method.name, method.functionType, method.definition); 575 MethodMember m = method; // lambdas must be MethodMembers
576 _scope.create(m.name, m.functionType, m.definition);
576 } 577 }
577 _usedTemps = new Set(); 578 _usedTemps = new Set();
578 _freeTemps = []; 579 _freeTemps = [];
579 } 580 }
580 581
581 // TODO(jimhug): Where does this really belong? 582 // TODO(jimhug): Where does this really belong?
582 MemberSet findMembers(String name) { 583 MemberSet findMembers(String name) {
583 return method.library._findMembers(name); 584 return method.library._findMembers(name);
584 } 585 }
585 586
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 defWriter.exitBlock('}'); 709 defWriter.exitBlock('}');
709 } 710 }
710 if (method.isConstructor && method.constructorName != '') { 711 if (method.isConstructor && method.constructorName != '') {
711 defWriter.writeln( 712 defWriter.writeln(
712 '${method.declaringType.jsname}.${method.constructorName}\$ctor.prototyp e = ' + 713 '${method.declaringType.jsname}.${method.constructorName}\$ctor.prototyp e = ' +
713 '${method.declaringType.jsname}.prototype;'); 714 '${method.declaringType.jsname}.prototype;');
714 } 715 }
715 716
716 _provideOptionalParamInfo(defWriter); 717 _provideOptionalParamInfo(defWriter);
717 718
718 if (method is MethodMember && method._providePropertySyntax) { 719 if (method is MethodMember) {
719 defWriter.enterBlock( 720 MethodMember m = method;
720 '${method.declaringType.jsname}.prototype.get\$${method.jsname} = functi on() {'); 721 if (m._providePropertySyntax) {
721 // TODO(jimhug): Bind not availabe in Safari, need fallback. 722 defWriter.enterBlock('${m.declaringType.jsname}.prototype'
722 defWriter.writeln( 723 + '.get\$${m.jsname} = function() {');
723 'return ${method.declaringType.jsname}.prototype.${method.jsname}.bind(t his);'); 724 // TODO(jimhug): Bind not available in older Safari, need fallback?
724 defWriter.exitBlock('}'); 725 defWriter.writeln('return ${m.declaringType.jsname}.prototype.'
726 + '${m.jsname}.bind(this);');
727 defWriter.exitBlock('}');
725 728
726 if (method._provideFieldSyntax) { 729 if (m._provideFieldSyntax) {
727 world.internalError('bound method accessed with field syntax'); 730 world.internalError('bound m accessed with field syntax');
731 }
728 } 732 }
729 } 733 }
730 } 734 }
731 735
732 /** 736 /**
733 * Generates information about the default/named arguments into the JS code. 737 * Generates information about the default/named arguments into the JS code.
734 * Only methods that are passed as bound methods to "var" need this. It is 738 * Only methods that are passed as bound methods to "var" need this. It is
735 * generated to support run time stub creation. 739 * generated to support run time stub creation.
736 */ 740 */
737 _provideOptionalParamInfo(CodeWriter defWriter) { 741 _provideOptionalParamInfo(CodeWriter defWriter) {
738 if (method is MethodMember && method._provideOptionalParamInfo) { 742 if (method is MethodMember) {
739 var optNames = []; 743 MethodMember meth = method;
740 var optValues = []; 744 if (meth._provideOptionalParamInfo) {
741 method.genParameterValues(); 745 var optNames = [];
742 for (var param in method.parameters) { 746 var optValues = [];
743 if (param.isOptional) { 747 meth.genParameterValues();
744 optNames.add(param.name); 748 for (var param in meth.parameters) {
745 optValues.add(_escapeString(param.value.code)); 749 if (param.isOptional) {
750 optNames.add(param.name);
751 optValues.add(_escapeString(param.value.code));
752 }
746 } 753 }
747 } 754 if (optNames.length > 0) {
748 if (optNames.length > 0) { 755 // TODO(jmesserly): the logic for how to refer to
749 // TODO(jmesserly): the logic for how to refer to 756 // static/instance/top-level members is duplicated all over the place.
750 // static/instance/top-level members is duplicated all over the place. 757 // Badly needs cleanup.
751 // Badly needs cleanup. 758 var start = '';
752 var start = ''; 759 if (meth.isStatic) {
753 if (method.isStatic) { 760 if (!meth.declaringType.isTop) {
754 if (!method.declaringType.isTop) { 761 start = meth.declaringType.jsname + '.';
755 start = method.declaringType.jsname + '.'; 762 }
763 } else {
764 start = meth.declaringType.jsname + '.prototype.';
756 } 765 }
757 } else { 766
758 start = method.declaringType.jsname + '.prototype.'; 767 optNames.addAll(optValues);
768 var optional = "['" + Strings.join(optNames, "', '") + "']";
769 defWriter.writeln('${start}${meth.jsname}.\$optional = $optional');
759 } 770 }
760
761 optNames.addAll(optValues);
762 var optional = "['" + Strings.join(optNames, "', '") + "']";
763 defWriter.writeln('${start}${method.jsname}.\$optional = $optional');
764 } 771 }
765 } 772 }
766 } 773 }
767 774
768 writeBody() { 775 writeBody() {
769 var initializers = null; 776 var initializers = null;
770 var initializedFields = null; // to check that final fields are initialized 777 var initializedFields = null; // to check that final fields are initialized
771 if (method.isConstructor) { 778 if (method.isConstructor) {
772 initializers = []; 779 initializers = [];
773 initializedFields = new Set(); 780 initializedFields = new Set();
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
960 */ 967 */
961 static String _escapeString(String text) { 968 static String _escapeString(String text) {
962 // TODO(jimhug): Use a regex for performance here. 969 // TODO(jimhug): Use a regex for performance here.
963 return text.replaceAll('\\', '\\\\').replaceAll('"', '\\"').replaceAll( 970 return text.replaceAll('\\', '\\\\').replaceAll('"', '\\"').replaceAll(
964 '\n', '\\n').replaceAll('\r', '\\r'); 971 '\n', '\\n').replaceAll('\r', '\\r');
965 } 972 }
966 973
967 /** Visits [body] without creating a new block for a [BlockStatement]. */ 974 /** Visits [body] without creating a new block for a [BlockStatement]. */
968 bool visitStatementsInBlock(Statement body) { 975 bool visitStatementsInBlock(Statement body) {
969 if (body is BlockStatement) { 976 if (body is BlockStatement) {
970 for (var stmt in body.body) { 977 BlockStatement block = body;
978 for (var stmt in block.body) {
971 stmt.visit(this); 979 stmt.visit(this);
972 } 980 }
973 } else { 981 } else {
974 if (body != null) body.visit(this); 982 if (body != null) body.visit(this);
975 } 983 }
976 return false; 984 return false;
977 } 985 }
978 986
979 _pushBlock([bool reentrant = false]) { 987 _pushBlock([bool reentrant = false]) {
980 _scope = new BlockScope(this, _scope, reentrant); 988 _scope = new BlockScope(this, _scope, reentrant);
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
1527 meth.generator.writeDefinition(w, node); 1535 meth.generator.writeDefinition(w, node);
1528 1536
1529 return new Value(meth.functionType, w.text); 1537 return new Value(meth.functionType, w.text);
1530 } 1538 }
1531 1539
1532 visitCallExpression(CallExpression node) { 1540 visitCallExpression(CallExpression node) {
1533 var target; 1541 var target;
1534 var position = node.target; 1542 var position = node.target;
1535 var name = '\$call'; 1543 var name = '\$call';
1536 if (node.target is DotExpression) { 1544 if (node.target is DotExpression) {
1537 target = node.target.self.visit(this); 1545 DotExpression dot = node.target;
1538 name = node.target.name.name; 1546 target = dot.self.visit(this);
1539 position = node.target.name; 1547 name = dot.name.name;
1548 position = dot.name;
1540 } else if (node.target is VarExpression) { 1549 } else if (node.target is VarExpression) {
1541 name = node.target.name.name; 1550 VarExpression varExpr = node.target;
1551 name = varExpr.name.name;
1542 var meth = method.declaringType.resolveMember(name); 1552 var meth = method.declaringType.resolveMember(name);
1543 if (meth != null) { 1553 if (meth != null) {
1544 target = _makeThisOrType(); 1554 target = _makeThisOrType();
1545 return meth.invoke(this, node.target, target, 1555 return meth.invoke(this, varExpr, target,
1546 _makeArgs(node.arguments)); 1556 _makeArgs(node.arguments));
1547 } 1557 }
1548 // Look for members of the top-level type (or imported libs). 1558 // Look for members of the top-level type (or imported libs).
1549 meth = method.declaringType.library.lookup(name, node.target.span); 1559 meth = method.declaringType.library.lookup(name, varExpr.span);
1550 if (meth != null) { 1560 if (meth != null) {
1551 return meth.invoke(this, node.target, null, 1561 return meth.invoke(this, varExpr, null, _makeArgs(node.arguments));
1552 _makeArgs(node.arguments));
1553 } 1562 }
1554 1563
1555 name = '\$call'; 1564 name = '\$call';
1556 target = node.target.visit(this); 1565 target = varExpr.visit(this);
1557 } else { 1566 } else {
1558 target = node.target.visit(this); 1567 target = node.target.visit(this);
1559 } 1568 }
1560 1569
1561 return target.invoke(this, name, position, _makeArgs(node.arguments)); 1570 return target.invoke(this, name, position, _makeArgs(node.arguments));
1562 } 1571 }
1563 1572
1564 visitIndexExpression(IndexExpression node) { 1573 visitIndexExpression(IndexExpression node) {
1565 var target = visitValue(node.target); 1574 var target = visitValue(node.target);
1566 var index = visitValue(node.index); 1575 var index = visitValue(node.index);
(...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after
2214 result.add(new Value(world.varType, '\$$i', false, /*needsTemp:*/false)); 2223 result.add(new Value(world.varType, '\$$i', false, /*needsTemp:*/false));
2215 } 2224 }
2216 for (int i = bareCount; i < length; i++) { 2225 for (int i = bareCount; i < length; i++) {
2217 var name = getName(i); 2226 var name = getName(i);
2218 if (name == null) name = '\$$i'; 2227 if (name == null) name = '\$$i';
2219 result.add(new Value(world.varType, name, false, /*needsTemp:*/false)); 2228 result.add(new Value(world.varType, name, false, /*needsTemp:*/false));
2220 } 2229 }
2221 return new Arguments(nodes, result); 2230 return new Arguments(nodes, result);
2222 } 2231 }
2223 } 2232 }
OLDNEW
« no previous file with comments | « frog/frogsh ('k') | frog/lib/corelib.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698