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

Side by Side Diff: lib/compiler/implementation/resolver.dart

Issue 10915083: Change assert implementation to not depend on a top-level function called 'assert'. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address review comments. Created 8 years, 3 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 | « lib/compiler/implementation/lib/mock.dart ('k') | lib/compiler/implementation/ssa/codegen.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) 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 interface TreeElements { 5 interface TreeElements {
6 Element operator[](Node node); 6 Element operator[](Node node);
7 Selector getSelector(Send send); 7 Selector getSelector(Send send);
8 DartType getType(TypeAnnotation annotation); 8 DartType getType(TypeAnnotation annotation);
9 bool isParameterChecked(Element element); 9 bool isParameterChecked(Element element);
10 } 10 }
(...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after
948 } 948 }
949 949
950 class ResolverVisitor extends CommonResolverVisitor<Element> { 950 class ResolverVisitor extends CommonResolverVisitor<Element> {
951 final TreeElementMapping mapping; 951 final TreeElementMapping mapping;
952 final Element enclosingElement; 952 final Element enclosingElement;
953 final TypeResolver typeResolver; 953 final TypeResolver typeResolver;
954 bool inInstanceContext; 954 bool inInstanceContext;
955 bool inCheckContext; 955 bool inCheckContext;
956 Scope scope; 956 Scope scope;
957 ClassElement currentClass; 957 ClassElement currentClass;
958 ExpressionStatement currentExpressionStatement;
958 bool typeRequired = false; 959 bool typeRequired = false;
959 StatementScope statementScope; 960 StatementScope statementScope;
960 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION; 961 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION;
961 962
962 ResolverVisitor(Compiler compiler, Element element) 963 ResolverVisitor(Compiler compiler, Element element)
963 : this.mapping = new TreeElementMapping(), 964 : this.mapping = new TreeElementMapping(),
964 this.enclosingElement = element, 965 this.enclosingElement = element,
965 // When the element is a field, we are actually resolving its 966 // When the element is a field, we are actually resolving its
966 // initial value, which should not have access to instance 967 // initial value, which should not have access to instance
967 // fields. 968 // fields.
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after
1156 } 1157 }
1157 1158
1158 visitDoWhile(DoWhile node) { 1159 visitDoWhile(DoWhile node) {
1159 visitLoopBodyIn(node, node.body, new BlockScope(scope)); 1160 visitLoopBodyIn(node, node.body, new BlockScope(scope));
1160 visit(node.condition); 1161 visit(node.condition);
1161 } 1162 }
1162 1163
1163 visitEmptyStatement(EmptyStatement node) { } 1164 visitEmptyStatement(EmptyStatement node) { }
1164 1165
1165 visitExpressionStatement(ExpressionStatement node) { 1166 visitExpressionStatement(ExpressionStatement node) {
1167 ExpressionStatement oldExpressionStatement = currentExpressionStatement;
1168 currentExpressionStatement = node;
1166 visit(node.expression); 1169 visit(node.expression);
1170 currentExpressionStatement = oldExpressionStatement;
1167 } 1171 }
1168 1172
1169 visitFor(For node) { 1173 visitFor(For node) {
1170 Scope blockScope = new BlockScope(scope); 1174 Scope blockScope = new BlockScope(scope);
1171 visitIn(node.initializer, blockScope); 1175 visitIn(node.initializer, blockScope);
1172 visitIn(node.condition, blockScope); 1176 visitIn(node.condition, blockScope);
1173 visitIn(node.update, blockScope); 1177 visitIn(node.update, blockScope);
1174 visitLoopBodyIn(node, node.body, blockScope); 1178 visitLoopBodyIn(node, node.body, blockScope);
1175 } 1179 }
1176 1180
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1210 visit(node.condition); 1214 visit(node.condition);
1211 visit(node.thenPart); 1215 visit(node.thenPart);
1212 visit(node.elsePart); 1216 visit(node.elsePart);
1213 } 1217 }
1214 1218
1215 static bool isLogicalOperator(Identifier op) { 1219 static bool isLogicalOperator(Identifier op) {
1216 String str = op.source.stringValue; 1220 String str = op.source.stringValue;
1217 return (str === '&&' || str == '||' || str == '!'); 1221 return (str === '&&' || str == '||' || str == '!');
1218 } 1222 }
1219 1223
1224 /**
1225 * Check the lexical scope chain for a declaration with the name "assert".
1226 *
1227 * This is used to detect whether "assert(x)" is actually an assertion or
1228 * just a call expression.
1229 * It does not check fields inherited from a superclass.
1230 */
1231 bool isAssertInLexicalScope() {
1232 return scope.lexicalLookup(const SourceString("assert")) !== null;
1233 }
1234
1235 /** Check if [node] is the expression of the current expression statement. */
1236 bool isExpressionStatementExpression(Node node) {
1237 return currentExpressionStatement !== null &&
1238 currentExpressionStatement.expression === node;
1239 }
1240
1220 Element resolveSend(Send node) { 1241 Element resolveSend(Send node) {
1221 Selector selector = resolveSelector(node); 1242 Selector selector = resolveSelector(node);
1222 1243
1223 if (node.receiver === null) { 1244 if (node.receiver === null) {
1245 // If this send is the expression of an expression statement, and is on
1246 // the form "assert(expr);", and there is no declaration with name
1247 // "assert" in the lexical scope, then this is actually an assertion.
1248 if (isExpressionStatementExpression(node) &&
1249 selector.isAssertSyntax() &&
1250 !isAssertInLexicalScope()) {
1251 return compiler.assertMethod;
1252 }
1224 return node.selector.accept(this); 1253 return node.selector.accept(this);
1225 } 1254 }
1226 1255
1227 var oldCategory = allowedCategory; 1256 var oldCategory = allowedCategory;
1228 allowedCategory |= 1257 allowedCategory |=
1229 ElementCategory.CLASS | ElementCategory.PREFIX | ElementCategory.SUPER; 1258 ElementCategory.CLASS | ElementCategory.PREFIX | ElementCategory.SUPER;
1230 Element resolvedReceiver = visit(node.receiver); 1259 Element resolvedReceiver = visit(node.receiver);
1231 allowedCategory = oldCategory; 1260 allowedCategory = oldCategory;
1232 1261
1233 Element target; 1262 Element target;
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1401 // we need to register that fact that we may be calling a closure 1430 // we need to register that fact that we may be calling a closure
1402 // with the same arguments. 1431 // with the same arguments.
1403 if (node.isCall && 1432 if (node.isCall &&
1404 (Elements.isUnresolved(target) || 1433 (Elements.isUnresolved(target) ||
1405 target.isGetter() || 1434 target.isGetter() ||
1406 Elements.isClosureSend(node, target))) { 1435 Elements.isClosureSend(node, target))) {
1407 Selector call = new Selector.callClosureFrom(selector); 1436 Selector call = new Selector.callClosureFrom(selector);
1408 world.registerDynamicInvocation(call.name, call); 1437 world.registerDynamicInvocation(call.name, call);
1409 } 1438 }
1410 1439
1411 // TODO(ngeoffray): We should do the check in
1412 // visitExpressionStatement instead.
1413 if (target === compiler.assertMethod && !node.isCall) {
1414 // We can only use assert by calling it.
1415 if (!inInstanceContext) {
1416 error(node, MessageKind.MISSING_ARGUMENTS_TO_ASSERT, [node]);
1417 }
1418 target = null;
1419 }
1420
1421 // TODO(ngeoffray): Warn if target is null and the send is 1440 // TODO(ngeoffray): Warn if target is null and the send is
1422 // unqualified. 1441 // unqualified.
1423 useElement(node, target); 1442 useElement(node, target);
1424 registerSend(selector, target); 1443 registerSend(selector, target);
1425 return node.isPropertyAccess ? target : null; 1444 return node.isPropertyAccess ? target : null;
1426 } 1445 }
1427 1446
1428 visitSendSet(SendSet node) { 1447 visitSendSet(SendSet node) {
1429 Element target = resolveSend(node); 1448 Element target = resolveSend(node);
1430 Element setter = target; 1449 Element setter = target;
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
1910 error(modifier, MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH); 1929 error(modifier, MessageKind.PARAMETER_WITH_MODIFIER_IN_CATCH);
1911 } 1930 }
1912 TypeAnnotation type = declaration.type; 1931 TypeAnnotation type = declaration.type;
1913 if (type !== null) { 1932 if (type !== null) {
1914 error(type, MessageKind.PARAMETER_WITH_TYPE_IN_CATCH); 1933 error(type, MessageKind.PARAMETER_WITH_TYPE_IN_CATCH);
1915 } 1934 }
1916 } 1935 }
1917 } 1936 }
1918 1937
1919 Scope blockScope = new BlockScope(scope); 1938 Scope blockScope = new BlockScope(scope);
1920 doInCheckContext(() => visitIn(node.type, blockScope)); 1939 doInCheckContext(() => visitIn(node.type, blockScope));
1921 visitIn(node.formals, blockScope); 1940 visitIn(node.formals, blockScope);
1922 visitIn(node.block, blockScope); 1941 visitIn(node.block, blockScope);
1923 } 1942 }
1924 1943
1925 visitTypedef(Typedef node) { 1944 visitTypedef(Typedef node) {
1926 unimplemented(node, 'typedef'); 1945 unimplemented(node, 'typedef');
1927 } 1946 }
1928 } 1947 }
1929 1948
1930 class TypeDefinitionVisitor extends CommonResolverVisitor<DartType> { 1949 class TypeDefinitionVisitor extends CommonResolverVisitor<DartType> {
(...skipping 655 matching lines...) Expand 10 before | Expand all | Expand 10 after
2586 return e; 2605 return e;
2587 } 2606 }
2588 } 2607 }
2589 2608
2590 class Scope { 2609 class Scope {
2591 final Element element; 2610 final Element element;
2592 final Scope parent; 2611 final Scope parent;
2593 2612
2594 Scope(this.parent, this.element); 2613 Scope(this.parent, this.element);
2595 abstract Element add(Element element); 2614 abstract Element add(Element element);
2596 abstract Element lookup(SourceString name); 2615
2616 Element lookup(SourceString name) {
2617 Element result = localLookup(name);
2618 if (result != null) return result;
2619 return parent.lookup(name);
2620 }
2621
2622 Element lexicalLookup(SourceString name) {
2623 Element result = localLookup(name);
2624 if (result != null) return result;
2625 return parent.lexicalLookup(name);
2626 }
2627
2628 abstract Element localLookup(SourceString name);
2597 } 2629 }
2598 2630
2599 class VariableScope extends Scope { 2631 class VariableScope extends Scope {
2600 VariableScope(parent, element) : super(parent, element); 2632 VariableScope(parent, element) : super(parent, element);
2601 2633
2602 Element add(Element newElement) { 2634 Element add(Element newElement) {
2603 throw "Cannot add element to VariableScope"; 2635 throw "Cannot add element to VariableScope";
2604 } 2636 }
2605 2637
2606 Element lookup(SourceString name) => parent.lookup(name); 2638 Element lookup(SourceString name) => parent.lookup(name);
(...skipping 13 matching lines...) Expand all
2620 2652
2621 TypeDeclarationScope(parent, TypeDeclarationElement element) 2653 TypeDeclarationScope(parent, TypeDeclarationElement element)
2622 : super(parent, element) { 2654 : super(parent, element) {
2623 assert(parent !== null); 2655 assert(parent !== null);
2624 } 2656 }
2625 2657
2626 Element add(Element newElement) { 2658 Element add(Element newElement) {
2627 throw "Cannot add element to TypeDeclarationScope"; 2659 throw "Cannot add element to TypeDeclarationScope";
2628 } 2660 }
2629 2661
2630 Element lookup(SourceString name) { 2662 Element localLookup(SourceString name) {
2631 Link<DartType> typeVariableLink = element.typeVariables; 2663 Link<DartType> typeVariableLink = element.typeVariables;
2632 while (!typeVariableLink.isEmpty()) { 2664 while (!typeVariableLink.isEmpty()) {
2633 TypeVariableType typeVariable = typeVariableLink.head; 2665 TypeVariableType typeVariable = typeVariableLink.head;
2634 if (typeVariable.name == name) { 2666 if (typeVariable.name == name) {
2635 return typeVariable.element; 2667 return typeVariable.element;
2636 } 2668 }
2637 typeVariableLink = typeVariableLink.tail; 2669 typeVariableLink = typeVariableLink.tail;
2638 } 2670 }
2639 2671 return null;
2640 return parent.lookup(name);
2641 } 2672 }
2642 2673
2643 String toString() => 2674 String toString() =>
2644 '$element${element.typeVariables} > $parent'; 2675 '$element${element.typeVariables} > $parent';
2645 } 2676 }
2646 2677
2647 class MethodScope extends Scope { 2678 class MethodScope extends Scope {
2648 final Map<SourceString, Element> elements; 2679 final Map<SourceString, Element> elements;
2649 2680
2650 MethodScope(Scope parent, Element element) 2681 MethodScope(Scope parent, Element element)
2651 : super(parent, element), 2682 : super(parent, element),
2652 this.elements = new Map<SourceString, Element>() { 2683 this.elements = new Map<SourceString, Element>() {
2653 assert(parent !== null); 2684 assert(parent !== null);
2654 } 2685 }
2655 2686
2656 Element lookup(SourceString name) { 2687 Element localLookup(SourceString name) => elements[name];
2657 Element found = elements[name];
2658 if (found !== null) return found;
2659 return parent.lookup(name);
2660 }
2661 2688
2662 Element add(Element newElement) { 2689 Element add(Element newElement) {
2663 if (elements.containsKey(newElement.name)) { 2690 if (elements.containsKey(newElement.name)) {
2664 return elements[newElement.name]; 2691 return elements[newElement.name];
2665 } 2692 }
2666 elements[newElement.name] = newElement; 2693 elements[newElement.name] = newElement;
2667 return newElement; 2694 return newElement;
2668 } 2695 }
2669 2696
2670 String toString() => '$element${elements.getKeys()} > $parent'; 2697 String toString() => '$element${elements.getKeys()} > $parent';
2671 } 2698 }
2672 2699
2673 class BlockScope extends MethodScope { 2700 class BlockScope extends MethodScope {
2674 BlockScope(Scope parent) : super(parent, parent.element); 2701 BlockScope(Scope parent) : super(parent, parent.element);
2675 2702
2676 String toString() => 'block${elements.getKeys()} > $parent'; 2703 String toString() => 'block${elements.getKeys()} > $parent';
2677 } 2704 }
2678 2705
2679 /** 2706 /**
2680 * [ClassScope] defines the inner scope of a class/interface declaration in 2707 * [ClassScope] defines the inner scope of a class/interface declaration in
2681 * which declared members, declared type variables, entities in the enclosing 2708 * which declared members, declared type variables, entities in the enclosing
2682 * scope and inherited members are available, in the given order. 2709 * scope and inherited members are available, in the given order.
2683 */ 2710 */
2684 class ClassScope extends TypeDeclarationScope { 2711 class ClassScope extends TypeDeclarationScope {
2685 bool inStaticContext = false; 2712 bool inStaticContext = false;
2686 2713
2687 ClassScope(Scope parentScope, ClassElement element) 2714 ClassScope(Scope parentScope, ClassElement element)
2688 : super(parentScope, element); 2715 : super(parentScope, element);
2689 2716
2690 Element lookup(SourceString name) { 2717 Element localLookup(SourceString name) {
2691 ClassElement cls = element; 2718 ClassElement cls = element;
2692 Element result = cls.lookupLocalMember(name); 2719 Element result = cls.lookupLocalMember(name);
2693 if (result !== null) return result; 2720 if (result !== null) return result;
2694 if (!inStaticContext) { 2721 if (!inStaticContext) {
2695 // If not in a static context, we can lookup in the 2722 // If not in a static context, we can lookup in the
2696 // TypeDeclaration scope, which contains the type variables of 2723 // TypeDeclaration scope, which contains the type variables of
2697 // the class. 2724 // the class.
2698 result = super.lookup(name); 2725 return super.localLookup(name);
2699 } else {
2700 result = parent.lookup(name);
2701 } 2726 }
2702 if (result != null) return result; 2727 return null;
2728 }
2729
2730 Element lookup(SourceString name) {
2731 Element result = super.lookup(name);
2732 if (result !== null) return result;
2733 ClassElement cls = element;
2703 return cls.lookupSuperMember(name); 2734 return cls.lookupSuperMember(name);
2704 } 2735 }
2705 2736
2706 Element add(Element newElement) { 2737 Element add(Element newElement) {
2707 throw "Cannot add an element in a class scope"; 2738 throw "Cannot add an element in a class scope";
2708 } 2739 }
2709 2740
2710 String toString() => '$element > $parent'; 2741 String toString() => '$element > $parent';
2711 } 2742 }
2712 2743
2713 class TopScope extends Scope { 2744 class TopScope extends Scope {
2714 LibraryElement get library => element; 2745 LibraryElement get library => element;
2715 2746
2716 TopScope(LibraryElement library) : super(null, library); 2747 TopScope(LibraryElement library) : super(null, library);
2717 Element lookup(SourceString name) { 2748
2718 return library.find(name); 2749 Element localLookup(SourceString name) => library.find(name);
2719 } 2750 Element lookup(SourceString name) => localLookup(name);
2751 Element lexicalLookup(SourceString name) => localLookup(name);
2720 2752
2721 Element add(Element newElement) { 2753 Element add(Element newElement) {
2722 throw "Cannot add an element in the top scope"; 2754 throw "Cannot add an element in the top scope";
2723 } 2755 }
2724 String toString() => '$element'; 2756 String toString() => '$element';
2725 } 2757 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/lib/mock.dart ('k') | lib/compiler/implementation/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698