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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/resolution/members.dart

Issue 24488004: Implement correct scoping rules for variables. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 2 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 part of resolution; 5 part of resolution;
6 6
7 abstract class TreeElements { 7 abstract class TreeElements {
8 Element get currentElement; 8 Element get currentElement;
9 Set<Node> get superUses; 9 Set<Node> get superUses;
10 10
(...skipping 1344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 cancel(node, 1355 cancel(node,
1356 'internal error: Unhandled node: ${node.getObjectDescription()}'); 1356 'internal error: Unhandled node: ${node.getObjectDescription()}');
1357 } 1357 }
1358 1358
1359 R visitEmptyStatement(Node node) => null; 1359 R visitEmptyStatement(Node node) => null;
1360 1360
1361 /** Convenience method for visiting nodes that may be null. */ 1361 /** Convenience method for visiting nodes that may be null. */
1362 R visit(Node node) => (node == null) ? null : node.accept(this); 1362 R visit(Node node) => (node == null) ? null : node.accept(this);
1363 1363
1364 void error(Node node, MessageKind kind, [Map arguments = const {}]) { 1364 void error(Node node, MessageKind kind, [Map arguments = const {}]) {
1365 // TODO(karlklose): change this to use [compiler.reportError] and
1366 // explicitly report fatal errors where necessary.
1365 compiler.reportFatalError(node, kind, arguments); 1367 compiler.reportFatalError(node, kind, arguments);
1366 } 1368 }
1367 1369
1368 void dualError(Node node, DualKind kind, [Map arguments = const {}]) { 1370 void dualError(Node node, DualKind kind, [Map arguments = const {}]) {
1369 error(node, kind.error, arguments); 1371 error(node, kind.error, arguments);
1370 } 1372 }
1371 1373
1372 void warning(Node node, MessageKind kind, [Map arguments = const {}]) { 1374 void warning(Node node, MessageKind kind, [Map arguments = const {}]) {
1373 ResolutionWarning message = 1375 ResolutionWarning message =
1374 new ResolutionWarning(kind, arguments, compiler.terseDiagnostics); 1376 new ResolutionWarning(kind, arguments, compiler.terseDiagnostics);
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after
1906 ErroneousElement warnAndCreateErroneousElement(Node node, 1908 ErroneousElement warnAndCreateErroneousElement(Node node,
1907 SourceString name, 1909 SourceString name,
1908 DualKind kind, 1910 DualKind kind,
1909 [Map arguments = const {}]) { 1911 [Map arguments = const {}]) {
1910 ResolutionWarning warning = new ResolutionWarning( 1912 ResolutionWarning warning = new ResolutionWarning(
1911 kind.warning, arguments, compiler.terseDiagnostics); 1913 kind.warning, arguments, compiler.terseDiagnostics);
1912 compiler.reportWarning(node, warning); 1914 compiler.reportWarning(node, warning);
1913 return new ErroneousElementX(kind.error, arguments, name, enclosingElement); 1915 return new ErroneousElementX(kind.error, arguments, name, enclosingElement);
1914 } 1916 }
1915 1917
1918 Element resolveIdentifier(Identifier node) {
1919 Element result = scope.lookup(node.source);
1920 if (result == null) return null;
1921
1922 if (result is VariableElement &&
1923 Elements.isLocal(result)) {
ngeoffray 2013/09/26 07:48:38 One line? Also, what is this check? That result is
1924 VariableElement variable = result;
1925 Node definition = variable.parseNode(compiler);
1926 if (definition.getEndToken().charOffset >=
1927 node.getBeginToken().charOffset) {
1928 compiler.reportError(node, MessageKind.ACCESS_BEFORE_INITIALIZATION,
1929 {'variableName': node});
1930 }
1931 }
1932 return result;
1933 }
1934
1916 Element visitIdentifier(Identifier node) { 1935 Element visitIdentifier(Identifier node) {
1917 if (node.isThis()) { 1936 if (node.isThis()) {
1918 if (!inInstanceContext) { 1937 if (!inInstanceContext) {
1919 error(node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node}); 1938 error(node, MessageKind.NO_INSTANCE_AVAILABLE, {'name': node});
1920 } 1939 }
1921 return null; 1940 return null;
1922 } else if (node.isSuper()) { 1941 } else if (node.isSuper()) {
1923 if (!inInstanceContext) error(node, MessageKind.NO_SUPER_IN_STATIC); 1942 if (!inInstanceContext) error(node, MessageKind.NO_SUPER_IN_STATIC);
1924 if ((ElementCategory.SUPER & allowedCategory) == 0) { 1943 if ((ElementCategory.SUPER & allowedCategory) == 0) {
1925 error(node, MessageKind.INVALID_USE_OF_SUPER); 1944 error(node, MessageKind.INVALID_USE_OF_SUPER);
1926 } 1945 }
1927 return null; 1946 return null;
1928 } else { 1947 } else {
1948 Element element = resolveIdentifier(node);
1929 SourceString name = node.source; 1949 SourceString name = node.source;
1930 Element element = scope.lookup(name);
1931 if (Elements.isUnresolved(element) && name.slowToString() == 'dynamic') { 1950 if (Elements.isUnresolved(element) && name.slowToString() == 'dynamic') {
1932 element = compiler.dynamicClass; 1951 element = compiler.dynamicClass;
1933 } 1952 }
1934 element = reportLookupErrorIfAny(element, node, node.source); 1953 element = reportLookupErrorIfAny(element, node, node.source);
1935 if (element == null) { 1954 if (element == null) {
1936 if (!inInstanceContext) { 1955 if (!inInstanceContext) {
1937 element = warnAndCreateErroneousElement( 1956 element = warnAndCreateErroneousElement(
1938 node, node.source, MessageKind.CANNOT_RESOLVE, 1957 node, node.source, MessageKind.CANNOT_RESOLVE,
1939 {'name': node}); 1958 {'name': node});
1940 compiler.backend.registerThrowNoSuchMethod(mapping); 1959 compiler.backend.registerThrowNoSuchMethod(mapping);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1991 if (!initializers.isEmpty && 2010 if (!initializers.isEmpty &&
1992 Initializers.isConstructorRedirect(initializers.head)) { 2011 Initializers.isConstructorRedirect(initializers.head)) {
1993 Selector selector = 2012 Selector selector =
1994 getRedirectingThisOrSuperConstructorSelector(initializers.head); 2013 getRedirectingThisOrSuperConstructorSelector(initializers.head);
1995 final ClassElement classElement = constructor.getEnclosingClass(); 2014 final ClassElement classElement = constructor.getEnclosingClass();
1996 return classElement.lookupConstructor(selector); 2015 return classElement.lookupConstructor(selector);
1997 } 2016 }
1998 return null; 2017 return null;
1999 } 2018 }
2000 2019
2020 void declareVariables(VariableDefinitions declaration) {
2021 VariableListElement variables = new VariableListElementX.node(
2022 declaration, ElementKind.VARIABLE_LIST, enclosingElement);
2023 if (declaration.type != null) {
2024 variables.type = resolveTypeAnnotation(declaration.type);
2025 } else {
2026 variables.type = compiler.types.dynamicType;
2027 }
2028
2029 for (Node node in declaration.definitions) {
2030 Identifier identifier = node.asIdentifier();
2031 if (identifier == null) {
2032 identifier = node.asSend().selector.asIdentifier();
2033 }
2034 SourceString name = identifier.source;
2035 VariableElement element =
2036 new VariableElementX(name, variables, ElementKind.VARIABLE, node);
2037 defineElement(node, element);
2038 }
2039 }
2040
2001 void setupFunction(FunctionExpression node, FunctionElement function) { 2041 void setupFunction(FunctionExpression node, FunctionElement function) {
2002 Element enclosingElement = function.enclosingElement; 2042 Element enclosingElement = function.enclosingElement;
2003 if (node.modifiers.isStatic() && 2043 if (node.modifiers.isStatic() &&
2004 enclosingElement.kind != ElementKind.CLASS) { 2044 enclosingElement.kind != ElementKind.CLASS) {
2005 compiler.reportError(node, MessageKind.ILLEGAL_STATIC); 2045 compiler.reportError(node, MessageKind.ILLEGAL_STATIC);
2006 } 2046 }
2007 2047
2008 scope = new MethodScope(scope, function); 2048 scope = new MethodScope(scope, function);
2009 // Put the parameters in scope. 2049 // Put the parameters in scope.
2010 FunctionSignature functionParameters = 2050 FunctionSignature functionParameters =
(...skipping 30 matching lines...) Expand all
2041 } 2081 }
2042 2082
2043 visitCascadeReceiver(CascadeReceiver node) { 2083 visitCascadeReceiver(CascadeReceiver node) {
2044 visit(node.expression); 2084 visit(node.expression);
2045 } 2085 }
2046 2086
2047 Element visitClassNode(ClassNode node) { 2087 Element visitClassNode(ClassNode node) {
2048 cancel(node, "shouldn't be called"); 2088 cancel(node, "shouldn't be called");
2049 } 2089 }
2050 2090
2051 visitIn(Node node, Scope nestedScope) { 2091 inScope(Scope nestedScope, f()) {
2052 Scope oldScope = scope; 2092 Scope oldScope = scope;
2053 scope = nestedScope; 2093 scope = nestedScope;
2054 Element element = visit(node); 2094 var result = f();
2055 scope = oldScope; 2095 scope = oldScope;
2056 return element; 2096 return result;
2097 }
2098
2099 visitIn(Node node, Scope nestedScope) {
2100 return inScope(nestedScope, () {
2101 return visit(node);
2102 });
2057 } 2103 }
2058 2104
2059 /** 2105 /**
2060 * Introduces new default targets for break and continue 2106 * Introduces new default targets for break and continue
2061 * before visiting the body of the loop 2107 * before visiting the body of the loop
2062 */ 2108 */
2063 visitLoopBodyIn(Node loop, Node body, Scope bodyScope) { 2109 visitLoopBodyIn(Node loop, Node body, Scope bodyScope) {
2064 TargetElement element = getOrCreateTargetElement(loop); 2110 TargetElement element = getOrCreateTargetElement(loop);
2065 statementScope.enterLoop(element); 2111 statementScope.enterLoop(element);
2066 visitIn(body, bodyScope); 2112 visitIn(body, bodyScope);
2067 statementScope.exitLoop(); 2113 statementScope.exitLoop();
2068 if (!element.isTarget) { 2114 if (!element.isTarget) {
2069 mapping.remove(loop); 2115 mapping.remove(loop);
2070 } 2116 }
2071 } 2117 }
2072 2118
2073 visitBlock(Block node) { 2119 visitBlock(Block node) {
2074 visitIn(node.statements, new BlockScope(scope)); 2120 inScope(new BlockScope(scope), () {
2121 node.declarations.forEach(declareVariables);
2122 visit(node.statements);
2123 });
2075 } 2124 }
2076 2125
2077 visitDoWhile(DoWhile node) { 2126 visitDoWhile(DoWhile node) {
2078 visitLoopBodyIn(node, node.body, new BlockScope(scope)); 2127 visitLoopBodyIn(node, node.body, createDeclarationScope(node.body));
2079 visit(node.condition); 2128 visit(node.condition);
2080 } 2129 }
2081 2130
2082 visitEmptyStatement(EmptyStatement node) { } 2131 visitEmptyStatement(EmptyStatement node) { }
2083 2132
2084 visitExpressionStatement(ExpressionStatement node) { 2133 visitExpressionStatement(ExpressionStatement node) {
2085 ExpressionStatement oldExpressionStatement = currentExpressionStatement; 2134 ExpressionStatement oldExpressionStatement = currentExpressionStatement;
2086 currentExpressionStatement = node; 2135 currentExpressionStatement = node;
2087 visit(node.expression); 2136 visit(node.expression);
2088 currentExpressionStatement = oldExpressionStatement; 2137 currentExpressionStatement = oldExpressionStatement;
2089 } 2138 }
2090 2139
2091 visitFor(For node) { 2140 visitFor(For node) {
2092 Scope blockScope = new BlockScope(scope); 2141 BlockScope blockScope = createDeclarationScope(node.body);
2093 visitIn(node.initializer, blockScope); 2142 inScope(blockScope, () {
2094 visitIn(node.condition, blockScope); 2143 if (node.initializer is VariableDefinitions) {
2095 visitIn(node.update, blockScope); 2144 declareVariables(node.initializer);
2145 }
2146 visit(node.initializer);
2147 visit(node.condition);
2148 visit(node.update);
2149 });
2096 visitLoopBodyIn(node, node.body, blockScope); 2150 visitLoopBodyIn(node, node.body, blockScope);
2097 } 2151 }
2098 2152
2099 visitFunctionDeclaration(FunctionDeclaration node) { 2153 visitFunctionDeclaration(FunctionDeclaration node) {
2100 assert(node.function.name != null); 2154 assert(node.function.name != null);
2101 visit(node.function); 2155 visit(node.function);
2102 FunctionElement functionElement = mapping[node.function]; 2156 FunctionElement functionElement = mapping[node.function];
2103 // TODO(floitsch): this might lead to two errors complaining about 2157 // TODO(floitsch): this might lead to two errors complaining about
2104 // shadowing. 2158 // shadowing.
2105 defineElement(node, functionElement); 2159 defineElement(node, functionElement);
(...skipping 24 matching lines...) Expand all
2130 2184
2131 scope = oldScope; 2185 scope = oldScope;
2132 enclosingElement = previousEnclosingElement; 2186 enclosingElement = previousEnclosingElement;
2133 2187
2134 world.registerClosure(function, mapping); 2188 world.registerClosure(function, mapping);
2135 world.registerInstantiatedClass(compiler.functionClass, mapping); 2189 world.registerInstantiatedClass(compiler.functionClass, mapping);
2136 } 2190 }
2137 2191
2138 visitIf(If node) { 2192 visitIf(If node) {
2139 visit(node.condition); 2193 visit(node.condition);
2140 visitIn(node.thenPart, new BlockScope(scope)); 2194 visitIn(node.thenPart, createDeclarationScope(node.thenPart));
2141 visitIn(node.elsePart, new BlockScope(scope)); 2195 visitIn(node.elsePart, createDeclarationScope(node.elsePart));
2142 } 2196 }
2143 2197
2144 static bool isLogicalOperator(Identifier op) { 2198 static bool isLogicalOperator(Identifier op) {
2145 String str = op.source.stringValue; 2199 String str = op.source.stringValue;
2146 return (identical(str, '&&') || str == '||' || str == '!'); 2200 return (identical(str, '&&') || str == '||' || str == '!');
2147 } 2201 }
2148 2202
2149 Element resolveSend(Send node) { 2203 Element resolveSend(Send node) {
2150 Selector selector = resolveSelector(node, null); 2204 Selector selector = resolveSelector(node, null);
2151 if (node.isSuperCall) mapping.superUses.add(node); 2205 if (node.isSuperCall) mapping.superUses.add(node);
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after
2714 2768
2715 visitThrow(Throw node) { 2769 visitThrow(Throw node) {
2716 compiler.backend.registerThrowExpression(mapping); 2770 compiler.backend.registerThrowExpression(mapping);
2717 visit(node.expression); 2771 visit(node.expression);
2718 } 2772 }
2719 2773
2720 visitVariableDefinitions(VariableDefinitions node) { 2774 visitVariableDefinitions(VariableDefinitions node) {
2721 VariableDefinitionsVisitor visitor = 2775 VariableDefinitionsVisitor visitor =
2722 new VariableDefinitionsVisitor(compiler, node, this, 2776 new VariableDefinitionsVisitor(compiler, node, this,
2723 ElementKind.VARIABLE); 2777 ElementKind.VARIABLE);
2724 // Ensure that we set the type of the [VariableListElement] since it depends
2725 // on the current scope. If the current scope is a [MethodScope] or
2726 // [BlockScope] it will not be available for the
2727 // [VariableListElement.computeType] method.
2728 if (node.type != null) {
2729 visitor.variables.type = resolveTypeAnnotation(node.type);
2730 } else {
2731 visitor.variables.type = compiler.types.dynamicType;
2732 }
2733
2734 Modifiers modifiers = node.modifiers; 2778 Modifiers modifiers = node.modifiers;
2735 void reportExtraModifier(String modifier) { 2779 void reportExtraModifier(String modifier) {
2736 Node modifierNode; 2780 Node modifierNode;
2737 for (var nodes = modifiers.nodes; !nodes.isEmpty; nodes = nodes.tail) { 2781 for (var nodes = modifiers.nodes; !nodes.isEmpty; nodes = nodes.tail) {
2738 if (modifier == nodes.head.asIdentifier().source.stringValue) { 2782 if (modifier == nodes.head.asIdentifier().source.stringValue) {
2739 modifierNode = nodes.head; 2783 modifierNode = nodes.head;
2740 break; 2784 break;
2741 } 2785 }
2742 } 2786 }
2743 assert(modifierNode != null); 2787 assert(modifierNode != null);
2744 compiler.reportError(modifierNode, MessageKind.EXTRANEOUS_MODIFIER, 2788 compiler.reportError(modifierNode, MessageKind.EXTRANEOUS_MODIFIER,
2745 {'modifier': modifier}); 2789 {'modifier': modifier});
2746 } 2790 }
2747 if (modifiers.isFinal() && (modifiers.isConst() || modifiers.isVar())) { 2791 if (modifiers.isFinal() && (modifiers.isConst() || modifiers.isVar())) {
2748 reportExtraModifier('final'); 2792 reportExtraModifier('final');
2749 } 2793 }
2750 if (modifiers.isVar() && (modifiers.isConst() || node.type != null)) { 2794 if (modifiers.isVar() && (modifiers.isConst() || node.type != null)) {
2751 reportExtraModifier('var'); 2795 reportExtraModifier('var');
2752 } 2796 }
2753 2797
2754 visitor.visit(node.definitions); 2798 visitor.visit(node.definitions);
2755 } 2799 }
2756 2800
2801 BlockScope createDeclarationScope(Node body) {
2802 Scope blockScope = new BlockScope(scope);
2803 if (body != null && body.asVariableDefinitions() != null) {
2804 inScope(blockScope, () {
2805 declareVariables(body);
2806 });
2807 }
2808 return blockScope;
2809 }
2810
2757 visitWhile(While node) { 2811 visitWhile(While node) {
2758 visit(node.condition); 2812 visit(node.condition);
2759 visitLoopBodyIn(node, node.body, new BlockScope(scope)); 2813 visitLoopBodyIn(node, node.body, createDeclarationScope(node.body));
2760 } 2814 }
2761 2815
2762 visitParenthesizedExpression(ParenthesizedExpression node) { 2816 visitParenthesizedExpression(ParenthesizedExpression node) {
2763 bool oldSendIsMemberAccess = sendIsMemberAccess; 2817 bool oldSendIsMemberAccess = sendIsMemberAccess;
2764 sendIsMemberAccess = false; 2818 sendIsMemberAccess = false;
2765 visit(node.expression); 2819 visit(node.expression);
2766 sendIsMemberAccess = oldSendIsMemberAccess; 2820 sendIsMemberAccess = oldSendIsMemberAccess;
2767 } 2821 }
2768 2822
2769 visitNewExpression(NewExpression node) { 2823 visitNewExpression(NewExpression node) {
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
2999 visitForIn(ForIn node) { 3053 visitForIn(ForIn node) {
3000 LibraryElement library = enclosingElement.getLibrary(); 3054 LibraryElement library = enclosingElement.getLibrary();
3001 mapping.setIteratorSelector(node, compiler.iteratorSelector); 3055 mapping.setIteratorSelector(node, compiler.iteratorSelector);
3002 world.registerDynamicGetter(compiler.iteratorSelector); 3056 world.registerDynamicGetter(compiler.iteratorSelector);
3003 mapping.setCurrentSelector(node, compiler.currentSelector); 3057 mapping.setCurrentSelector(node, compiler.currentSelector);
3004 world.registerDynamicGetter(compiler.currentSelector); 3058 world.registerDynamicGetter(compiler.currentSelector);
3005 mapping.setMoveNextSelector(node, compiler.moveNextSelector); 3059 mapping.setMoveNextSelector(node, compiler.moveNextSelector);
3006 world.registerDynamicInvocation(compiler.moveNextSelector); 3060 world.registerDynamicInvocation(compiler.moveNextSelector);
3007 3061
3008 visit(node.expression); 3062 visit(node.expression);
3009 Scope blockScope = new BlockScope(scope);
3010 Node declaration = node.declaredIdentifier; 3063 Node declaration = node.declaredIdentifier;
3064 BlockScope blockScope = createDeclarationScope(node.body);
3011 visitIn(declaration, blockScope); 3065 visitIn(declaration, blockScope);
3012 3066
3013 Send send = declaration.asSend(); 3067 Send send = declaration.asSend();
3014 VariableDefinitions variableDefinitions = 3068 VariableDefinitions variableDefinitions =
3015 declaration.asVariableDefinitions(); 3069 declaration.asVariableDefinitions();
3016 Element loopVariable; 3070 Element loopVariable;
3017 Selector loopVariableSelector; 3071 Selector loopVariableSelector;
3018 if (send != null) { 3072 if (send != null) {
3019 loopVariable = mapping[send]; 3073 loopVariable = mapping[send];
3020 Identifier identifier = send.selector.asIdentifier(); 3074 Identifier identifier = send.selector.asIdentifier();
3021 if (identifier == null) { 3075 if (identifier == null) {
3022 compiler.reportError(send.selector, MessageKind.INVALID_FOR_IN); 3076 compiler.reportError(send.selector, MessageKind.INVALID_FOR_IN);
3023 } else { 3077 } else {
3024 loopVariableSelector = new Selector.setter(identifier.source, library); 3078 loopVariableSelector = new Selector.setter(identifier.source, library);
3025 } 3079 }
3026 if (send.receiver != null) { 3080 if (send.receiver != null) {
3027 compiler.reportError(send.receiver, MessageKind.INVALID_FOR_IN); 3081 compiler.reportError(send.receiver, MessageKind.INVALID_FOR_IN);
3028 } 3082 }
3029 } else if (variableDefinitions != null) { 3083 } else if (variableDefinitions != null) {
3084 inScope(blockScope, () {
3085 declareVariables(variableDefinitions);
3086 });
3030 Link<Node> nodes = variableDefinitions.definitions.nodes; 3087 Link<Node> nodes = variableDefinitions.definitions.nodes;
3031 if (!nodes.tail.isEmpty) { 3088 if (!nodes.tail.isEmpty) {
3032 compiler.reportError(nodes.tail.head, MessageKind.INVALID_FOR_IN); 3089 compiler.reportError(nodes.tail.head, MessageKind.INVALID_FOR_IN);
3033 } 3090 }
3034 Node first = nodes.head; 3091 Node first = nodes.head;
3035 Identifier identifier = first.asIdentifier(); 3092 Identifier identifier = first.asIdentifier();
3036 if (identifier == null) { 3093 if (identifier == null) {
3037 compiler.reportError(first, MessageKind.INVALID_FOR_IN); 3094 compiler.reportError(first, MessageKind.INVALID_FOR_IN);
3038 } else { 3095 } else {
3039 loopVariableSelector = new Selector.setter(identifier.source, library); 3096 loopVariableSelector = new Selector.setter(identifier.source, library);
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
3200 mapping.remove(label.label); 3257 mapping.remove(label.label);
3201 } 3258 }
3202 }); 3259 });
3203 // TODO(ngeoffray): We should check here instead of the SSA backend if 3260 // TODO(ngeoffray): We should check here instead of the SSA backend if
3204 // there might be an error. 3261 // there might be an error.
3205 compiler.backend.registerFallThroughError(mapping); 3262 compiler.backend.registerFallThroughError(mapping);
3206 } 3263 }
3207 3264
3208 visitSwitchCase(SwitchCase node) { 3265 visitSwitchCase(SwitchCase node) {
3209 node.labelsAndCases.accept(this); 3266 node.labelsAndCases.accept(this);
3210 visitIn(node.statements, new BlockScope(scope)); 3267 inScope(new BlockScope(scope), () {
3268 node.declarations.forEach(declareVariables);
3269 visit(node.statements);
3270 });
3211 } 3271 }
3212 3272
3213 visitCaseMatch(CaseMatch node) { 3273 visitCaseMatch(CaseMatch node) {
3214 visit(node.expression); 3274 visit(node.expression);
3215 } 3275 }
3216 3276
3217 visitTryStatement(TryStatement node) { 3277 visitTryStatement(TryStatement node) {
3218 visit(node.tryBlock); 3278 visit(node.tryBlock);
3219 if (node.catchBlocks.isEmpty && node.finallyBlock == null) { 3279 if (node.catchBlocks.isEmpty && node.finallyBlock == null) {
3220 // TODO(ngeoffray): The precise location is 3280 // TODO(ngeoffray): The precise location is
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3267 } 3327 }
3268 TypeAnnotation type = declaration.type; 3328 TypeAnnotation type = declaration.type;
3269 if (type != null) { 3329 if (type != null) {
3270 error(type, MessageKind.PARAMETER_WITH_TYPE_IN_CATCH); 3330 error(type, MessageKind.PARAMETER_WITH_TYPE_IN_CATCH);
3271 } 3331 }
3272 } 3332 }
3273 } 3333 }
3274 } 3334 }
3275 3335
3276 Scope blockScope = new BlockScope(scope); 3336 Scope blockScope = new BlockScope(scope);
3277 doInCheckContext(() => visitIn(node.type, blockScope)); 3337 List<VariableDefinitions> declarations = <VariableDefinitions>[];
3278 visitIn(node.formals, blockScope); 3338 if (exceptionDefinition != null) {
3279 var oldInCatchBlock = inCatchBlock; 3339 declarations.add(exceptionDefinition);
3280 inCatchBlock = true; 3340 }
3281 visitIn(node.block, blockScope); 3341 if (stackTraceDefinition != null) {
3282 inCatchBlock = oldInCatchBlock; 3342 declarations.add(stackTraceDefinition);
3343 }
3344
3345 inScope(blockScope, () {
3346 declarations.forEach(declareVariables);
3347 doInCheckContext(() => visitIn(node.type, blockScope));
3348 visitIn(node.formals, blockScope);
3349 var oldInCatchBlock = inCatchBlock;
3350 inCatchBlock = true;
3351 visit(node.block);
3352 inCatchBlock = oldInCatchBlock;
3353 });
3283 3354
3284 if (node.type != null && exceptionDefinition != null) { 3355 if (node.type != null && exceptionDefinition != null) {
3285 DartType exceptionType = mapping.getType(node.type); 3356 DartType exceptionType = mapping.getType(node.type);
3286 Node exceptionVariable = exceptionDefinition.definitions.nodes.head; 3357 Node exceptionVariable = exceptionDefinition.definitions.nodes.head;
3287 VariableElementX exceptionElement = mapping[exceptionVariable]; 3358 VariableElementX exceptionElement = mapping[exceptionVariable];
3288 exceptionElement.variables.type = exceptionType; 3359 exceptionElement.variables.type = exceptionType;
3289 } 3360 }
3290 if (stackTraceDefinition != null) { 3361 if (stackTraceDefinition != null) {
3291 Node stackTraceVariable = stackTraceDefinition.definitions.nodes.head; 3362 Node stackTraceVariable = stackTraceDefinition.definitions.nodes.head;
3292 VariableElementX stackTraceElement = mapping[stackTraceVariable]; 3363 VariableElementX stackTraceElement = mapping[stackTraceVariable];
(...skipping 642 matching lines...) Expand 10 before | Expand all | Expand 10 after
3935 return; 4006 return;
3936 } 4007 }
3937 loadSupertype(e, node); 4008 loadSupertype(e, node);
3938 } 4009 }
3939 } 4010 }
3940 4011
3941 class VariableDefinitionsVisitor extends CommonResolverVisitor<SourceString> { 4012 class VariableDefinitionsVisitor extends CommonResolverVisitor<SourceString> {
3942 VariableDefinitions definitions; 4013 VariableDefinitions definitions;
3943 ResolverVisitor resolver; 4014 ResolverVisitor resolver;
3944 ElementKind kind; 4015 ElementKind kind;
3945 VariableListElement variables;
3946 4016
3947 VariableDefinitionsVisitor(Compiler compiler, 4017 VariableDefinitionsVisitor(Compiler compiler,
3948 this.definitions, this.resolver, this.kind) 4018 this.definitions, this.resolver, this.kind)
3949 : super(compiler) { 4019 : super(compiler) {
3950 variables = new VariableListElementX.node(
3951 definitions, ElementKind.VARIABLE_LIST, resolver.enclosingElement);
3952 } 4020 }
3953 4021
3954 SourceString visitSendSet(SendSet node) { 4022 SourceString visitSendSet(SendSet node) {
3955 assert(node.arguments.tail.isEmpty); // Sanity check 4023 assert(node.arguments.tail.isEmpty); // Sanity check
3956 Identifier identifier = node.selector; 4024 Identifier identifier = node.selector;
3957 SourceString name = identifier.source; 4025 SourceString name = identifier.source;
3958 VariableDefinitionScope scope = 4026 resolver.visit(node.arguments.head);
3959 new VariableDefinitionScope(resolver.scope, name);
3960 resolver.visitIn(node.arguments.head, scope);
3961 if (scope.variableReferencedInInitializer) {
3962 resolver.error(identifier, MessageKind.REFERENCE_IN_INITIALIZATION,
3963 {'variableName': name.toString()});
3964 }
3965 return name; 4027 return name;
3966 } 4028 }
3967 4029
3968 SourceString visitIdentifier(Identifier node) { 4030 SourceString visitIdentifier(Identifier node) {
3969 // The variable is initialized to null. 4031 // The variable is initialized to null.
3970 resolver.world.registerInstantiatedClass(compiler.nullClass, 4032 resolver.world.registerInstantiatedClass(compiler.nullClass,
3971 resolver.mapping); 4033 resolver.mapping);
3972 if (definitions.modifiers.isConst()) { 4034 if (definitions.modifiers.isConst()) {
3973 compiler.reportError(node, MessageKind.CONST_WITHOUT_INITIALIZER); 4035 compiler.reportError(node, MessageKind.CONST_WITHOUT_INITIALIZER);
3974 } 4036 }
3975 return node.source; 4037 return node.source;
3976 } 4038 }
3977 4039
3978 visitNodeList(NodeList node) { 4040 visitNodeList(NodeList node) {
3979 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) { 4041 for (Link<Node> link = node.nodes; !link.isEmpty; link = link.tail) {
3980 SourceString name = visit(link.head); 4042 SourceString name = visit(link.head);
3981 VariableElement element =
3982 new VariableElementX(name, variables, kind, link.head);
3983 resolver.defineElement(link.head, element);
3984 } 4043 }
3985 } 4044 }
3986 } 4045 }
3987 4046
3988 /** 4047 /**
3989 * [SignatureResolver] resolves function signatures. 4048 * [SignatureResolver] resolves function signatures.
3990 */ 4049 */
3991 class SignatureResolver extends CommonResolverVisitor<Element> { 4050 class SignatureResolver extends CommonResolverVisitor<Element> {
3992 final Element enclosingElement; 4051 final Element enclosingElement;
3993 final bool defaultValuesAllowed; 4052 final bool defaultValuesAllowed;
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
4350 } 4409 }
4351 } else { 4410 } else {
4352 internalError(node.receiver, 'unexpected element $e'); 4411 internalError(node.receiver, 'unexpected element $e');
4353 } 4412 }
4354 return e; 4413 return e;
4355 } 4414 }
4356 4415
4357 Element visitIdentifier(Identifier node) { 4416 Element visitIdentifier(Identifier node) {
4358 SourceString name = node.source; 4417 SourceString name = node.source;
4359 Element e = resolver.reportLookupErrorIfAny( 4418 Element e = resolver.reportLookupErrorIfAny(
4360 resolver.scope.lookup(name), node, name); 4419 resolver.resolveIdentifier(node), node, name);
4361 // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1. 4420 // TODO(johnniwinther): Change errors to warnings, cf. 11.11.1.
4362 if (e == null) { 4421 if (e == null) {
4363 return failOrReturnErroneousElement(resolver.enclosingElement, node, name, 4422 return failOrReturnErroneousElement(resolver.enclosingElement, node, name,
4364 MessageKind.CANNOT_RESOLVE, 4423 MessageKind.CANNOT_RESOLVE,
4365 {'name': name}); 4424 {'name': name});
4366 } else if (e.isErroneous()) { 4425 } else if (e.isErroneous()) {
4367 return e; 4426 return e;
4368 } else if (identical(e.kind, ElementKind.TYPEDEF)) { 4427 } else if (identical(e.kind, ElementKind.TYPEDEF)) {
4369 error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF, 4428 error(node, MessageKind.CANNOT_INSTANTIATE_TYPEDEF,
4370 {'typedefName': name}); 4429 {'typedefName': name});
4371 } else if (identical(e.kind, ElementKind.TYPE_VARIABLE)) { 4430 } else if (identical(e.kind, ElementKind.TYPE_VARIABLE)) {
4372 error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE, 4431 error(node, MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE,
4373 {'typeVariableName': name}); 4432 {'typeVariableName': name});
4374 } else if (!identical(e.kind, ElementKind.CLASS) 4433 } else if (!identical(e.kind, ElementKind.CLASS)
4375 && !identical(e.kind, ElementKind.PREFIX)) { 4434 && !identical(e.kind, ElementKind.PREFIX)) {
4376 error(node, MessageKind.NOT_A_TYPE.error, {'node': name}); 4435 error(node, MessageKind.NOT_A_TYPE.error, {'node': name});
4377 } 4436 }
4378 return e; 4437 return e;
4379 } 4438 }
4380 4439
4381 /// Assumed to be called by [resolveRedirectingFactory]. 4440 /// Assumed to be called by [resolveRedirectingFactory].
4382 Element visitReturn(Return node) { 4441 Element visitReturn(Return node) {
4383 Node expression = node.expression; 4442 Node expression = node.expression;
4384 return finishConstructorReference(visit(expression), 4443 return finishConstructorReference(visit(expression),
4385 expression, expression); 4444 expression, expression);
4386 } 4445 }
4387 } 4446 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698