Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 } |
| OLD | NEW |