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

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

Issue 10911006: Collect the types used in is-checks in the resolver phase. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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
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 Type getType(TypeAnnotation annotation); 8 Type getType(TypeAnnotation annotation);
9 } 9 }
10 10
(...skipping 927 matching lines...) Expand 10 before | Expand all | Expand 10 after
938 } 938 }
939 return arguments.toLink(); 939 return arguments.toLink();
940 } 940 }
941 } 941 }
942 942
943 class ResolverVisitor extends CommonResolverVisitor<Element> { 943 class ResolverVisitor extends CommonResolverVisitor<Element> {
944 final TreeElementMapping mapping; 944 final TreeElementMapping mapping;
945 final Element enclosingElement; 945 final Element enclosingElement;
946 final TypeResolver typeResolver; 946 final TypeResolver typeResolver;
947 bool inInstanceContext; 947 bool inInstanceContext;
948 bool inCheckContext;
948 Scope scope; 949 Scope scope;
949 ClassElement currentClass; 950 ClassElement currentClass;
950 bool typeRequired = false; 951 bool typeRequired = false;
951 StatementScope statementScope; 952 StatementScope statementScope;
952 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION; 953 int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION;
953 954
954 ResolverVisitor(Compiler compiler, Element element) 955 ResolverVisitor(Compiler compiler, Element element)
955 : this.mapping = new TreeElementMapping(), 956 : this.mapping = new TreeElementMapping(),
956 this.enclosingElement = element, 957 this.enclosingElement = element,
957 // When the element is a field, we are actually resolving its 958 // When the element is a field, we are actually resolving its
958 // initial value, which should not have access to instance 959 // initial value, which should not have access to instance
959 // fields. 960 // fields.
960 inInstanceContext = (element.isInstanceMember() && !element.isField()) 961 inInstanceContext = (element.isInstanceMember() && !element.isField())
961 || element.isGenerativeConstructor(), 962 || element.isGenerativeConstructor(),
962 this.currentClass = element.isMember() ? 963 this.currentClass = element.isMember() ? element.getEnclosingClass()
963 element.getEnclosingClass() : 964 : null,
964 null,
965 this.statementScope = new StatementScope(), 965 this.statementScope = new StatementScope(),
966 typeResolver = new TypeResolver(compiler), 966 typeResolver = new TypeResolver(compiler),
967 scope = element.buildEnclosingScope(), 967 scope = element.buildEnclosingScope(),
968 inCheckContext = compiler.enableTypeAssertions,
968 super(compiler) { 969 super(compiler) {
969 } 970 }
970 971
971 Enqueuer get world => compiler.enqueuer.resolution; 972 Enqueuer get world => compiler.enqueuer.resolution;
972 973
973 Element lookup(Node node, SourceString name) { 974 Element lookup(Node node, SourceString name) {
974 Element result = scope.lookup(name); 975 Element result = scope.lookup(name);
975 if (!inInstanceContext && result != null && result.isInstanceMember()) { 976 if (!inInstanceContext && result != null && result.isInstanceMember()) {
976 error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]); 977 error(node, MessageKind.NO_INSTANCE_AVAILABLE, [node]);
977 } 978 }
978 return result; 979 return result;
979 } 980 }
980 981
981 // Create, or reuse an already created, statement element for a statement. 982 // Create, or reuse an already created, statement element for a statement.
982 TargetElement getOrCreateTargetElement(Node statement) { 983 TargetElement getOrCreateTargetElement(Node statement) {
983 TargetElement element = mapping[statement]; 984 TargetElement element = mapping[statement];
984 if (element === null) { 985 if (element === null) {
985 element = new TargetElement(statement, 986 element = new TargetElement(statement,
986 statementScope.nestingLevel, 987 statementScope.nestingLevel,
987 enclosingElement); 988 enclosingElement);
988 mapping[statement] = element; 989 mapping[statement] = element;
989 } 990 }
990 return element; 991 return element;
991 } 992 }
992 993
994 doInCheckContext(action()) {
995 bool wasInCheckContext = inCheckContext;
996 inCheckContext = true;
997 var result = action();
998 inCheckContext = wasInCheckContext;
999 return result;
1000 }
1001
993 inStaticContext(action()) { 1002 inStaticContext(action()) {
994 bool wasInstanceContext = inInstanceContext; 1003 bool wasInstanceContext = inInstanceContext;
995 inInstanceContext = false; 1004 inInstanceContext = false;
996 var result = action(); 1005 var result = action();
997 inInstanceContext = wasInstanceContext; 1006 inInstanceContext = wasInstanceContext;
998 return result; 1007 return result;
999 } 1008 }
1000 1009
1001 visitInStaticContext(Node node) { 1010 visitInStaticContext(Node node) {
1002 inStaticContext(() => visit(node)); 1011 inStaticContext(() => visit(node));
(...skipping 20 matching lines...) Expand all
1023 // TODO(ahe): Improve error message. Need UX input. 1032 // TODO(ahe): Improve error message. Need UX input.
1024 error(node, MessageKind.GENERIC, ["is not an expression $element"]); 1033 error(node, MessageKind.GENERIC, ["is not an expression $element"]);
1025 } 1034 }
1026 } 1035 }
1027 return useElement(node, element); 1036 return useElement(node, element);
1028 } 1037 }
1029 } 1038 }
1030 1039
1031 Element visitTypeAnnotation(TypeAnnotation node) { 1040 Element visitTypeAnnotation(TypeAnnotation node) {
1032 Type type = resolveTypeAnnotation(node); 1041 Type type = resolveTypeAnnotation(node);
1033 if (type !== null) return type.element; 1042 if (type !== null) {
1043 if (inCheckContext) {
1044 compiler.enqueuer.resolution.registerIsCheck(type);
1045 }
1046 return type.element;
1047 }
1034 return null; 1048 return null;
1035 } 1049 }
1036 1050
1037 Element defineElement(Node node, Element element, 1051 Element defineElement(Node node, Element element,
1038 [bool doAddToScope = true]) { 1052 [bool doAddToScope = true]) {
1039 compiler.ensure(element !== null); 1053 compiler.ensure(element !== null);
1040 mapping[node] = element; 1054 mapping[node] = element;
1041 if (doAddToScope) { 1055 if (doAddToScope) {
1042 Element existing = scope.add(element); 1056 Element existing = scope.add(element);
1043 if (existing != element) { 1057 if (existing != element) {
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
1329 && target.kind == ElementKind.ABSTRACT_FIELD) { 1343 && target.kind == ElementKind.ABSTRACT_FIELD) {
1330 AbstractFieldElement field = target; 1344 AbstractFieldElement field = target;
1331 target = field.getter; 1345 target = field.getter;
1332 } 1346 }
1333 1347
1334 bool resolvedArguments = false; 1348 bool resolvedArguments = false;
1335 if (node.isOperator) { 1349 if (node.isOperator) {
1336 String operatorString = node.selector.asOperator().source.stringValue; 1350 String operatorString = node.selector.asOperator().source.stringValue;
1337 if (operatorString === 'is' || operatorString === 'as') { 1351 if (operatorString === 'is' || operatorString === 'as') {
1338 assert(node.arguments.tail.isEmpty()); 1352 assert(node.arguments.tail.isEmpty());
1339 resolveTypeTest(node.arguments.head); 1353 Type type = resolveTypeTest(node.arguments.head);
1354 if (type != null) {
1355 compiler.enqueuer.resolution.registerIsCheck(type);
1356 }
1340 resolvedArguments = true; 1357 resolvedArguments = true;
1341 } 1358 }
1342 } 1359 }
1343 1360
1344 if (!resolvedArguments) { 1361 if (!resolvedArguments) {
1345 resolveArguments(node.argumentsNode); 1362 resolveArguments(node.argumentsNode);
1346 } 1363 }
1347 1364
1348 // If the selector is null, it means that we will not be generating 1365 // If the selector is null, it means that we will not be generating
1349 // code for this as a send. 1366 // code for this as a send.
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1588 Type resolveTypeRequired(TypeAnnotation node) { 1605 Type resolveTypeRequired(TypeAnnotation node) {
1589 bool old = typeRequired; 1606 bool old = typeRequired;
1590 typeRequired = true; 1607 typeRequired = true;
1591 Type result = resolveTypeAnnotation(node); 1608 Type result = resolveTypeAnnotation(node);
1592 typeRequired = old; 1609 typeRequired = old;
1593 return result; 1610 return result;
1594 } 1611 }
1595 1612
1596 Type resolveTypeAnnotation(TypeAnnotation node) { 1613 Type resolveTypeAnnotation(TypeAnnotation node) {
1597 Function report = typeRequired ? error : warning; 1614 Function report = typeRequired ? error : warning;
1598 return typeResolver.resolveTypeAnnotation(node, inScope: scope, 1615 Type type = typeResolver.resolveTypeAnnotation(node, inScope: scope,
1599 onFailure: report, 1616 onFailure: report,
1600 whenResolved: useType); 1617 whenResolved: useType);
1618 if (compiler.enableTypeAssertions) {
1619 compiler.enqueuer.resolution.registerIsCheck(type);
1620 }
1621 return type;
1601 } 1622 }
1602 1623
1603 visitModifiers(Modifiers node) { 1624 visitModifiers(Modifiers node) {
1604 // TODO(ngeoffray): Implement this. 1625 // TODO(ngeoffray): Implement this.
1605 unimplemented(node, 'modifiers'); 1626 unimplemented(node, 'modifiers');
1606 } 1627 }
1607 1628
1608 visitLiteralList(LiteralList node) { 1629 visitLiteralList(LiteralList node) {
1609 NodeList arguments = node.typeArguments; 1630 NodeList arguments = node.typeArguments;
1610 if (arguments !== null) { 1631 if (arguments !== null) {
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
1841 visitCatchBlock(CatchBlock node) { 1862 visitCatchBlock(CatchBlock node) {
1842 Scope blockScope = new BlockScope(scope); 1863 Scope blockScope = new BlockScope(scope);
1843 if (node.formals.isEmpty()) { 1864 if (node.formals.isEmpty()) {
1844 error(node, MessageKind.EMPTY_CATCH_DECLARATION); 1865 error(node, MessageKind.EMPTY_CATCH_DECLARATION);
1845 } else if (!node.formals.nodes.tail.isEmpty() 1866 } else if (!node.formals.nodes.tail.isEmpty()
1846 && !node.formals.nodes.tail.tail.isEmpty()) { 1867 && !node.formals.nodes.tail.tail.isEmpty()) {
1847 for (Node extra in node.formals.nodes.tail.tail) { 1868 for (Node extra in node.formals.nodes.tail.tail) {
1848 error(extra, MessageKind.EXTRA_CATCH_DECLARATION); 1869 error(extra, MessageKind.EXTRA_CATCH_DECLARATION);
1849 } 1870 }
1850 } 1871 }
1851 visitIn(node.type, blockScope); 1872 if (node.type != null) {
1852 visitIn(node.formals, blockScope); 1873 doInCheckContext(() => visitIn(node.type, blockScope));
1874 visitIn(node.formals, blockScope);
1875 } else {
1876 // The type annotation for the exception type is on the first formal.
1877 doInCheckContext(() => visitIn(node.formals.nodes.head, blockScope));
1878 if (!node.formals.nodes.tail.isEmpty()) {
1879 visitIn(node.formals.nodes.tail.head, blockScope);
1880 }
1881 }
1853 visitIn(node.block, blockScope); 1882 visitIn(node.block, blockScope);
1854 } 1883 }
1855 1884
1856 visitTypedef(Typedef node) { 1885 visitTypedef(Typedef node) {
1857 unimplemented(node, 'typedef'); 1886 unimplemented(node, 'typedef');
1858 } 1887 }
1859 } 1888 }
1860 1889
1861 class TypeDefinitionVisitor extends CommonResolverVisitor<Type> { 1890 class TypeDefinitionVisitor extends CommonResolverVisitor<Type> {
1862 Scope scope; 1891 Scope scope;
(...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after
2628 TopScope(LibraryElement library) : super(null, library); 2657 TopScope(LibraryElement library) : super(null, library);
2629 Element lookup(SourceString name) { 2658 Element lookup(SourceString name) {
2630 return library.find(name); 2659 return library.find(name);
2631 } 2660 }
2632 2661
2633 Element add(Element newElement) { 2662 Element add(Element newElement) {
2634 throw "Cannot add an element in the top scope"; 2663 throw "Cannot add an element in the top scope";
2635 } 2664 }
2636 String toString() => '$element'; 2665 String toString() => '$element';
2637 } 2666 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698