| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 library fasta.body_builder; | 5 library fasta.body_builder; |
| 6 | 6 |
| 7 import '../parser/parser.dart' show FormalParameterType, optional; | 7 import '../parser/parser.dart' show FormalParameterType, optional; |
| 8 | 8 |
| 9 import '../parser/error_kind.dart' show ErrorKind; | 9 import '../parser/error_kind.dart' show ErrorKind; |
| 10 | 10 |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 void ignore(Unhandled value) { | 259 void ignore(Unhandled value) { |
| 260 pop(); | 260 pop(); |
| 261 } | 261 } |
| 262 | 262 |
| 263 void enterSwitchScope() { | 263 void enterSwitchScope() { |
| 264 push(switchScope ?? NullValue.SwitchScope); | 264 push(switchScope ?? NullValue.SwitchScope); |
| 265 switchScope = scope; | 265 switchScope = scope; |
| 266 } | 266 } |
| 267 | 267 |
| 268 void exitSwitchScope() { | 268 void exitSwitchScope() { |
| 269 switchScope = pop(); | 269 Scope outerSwitchScope = pop(); |
| 270 if (switchScope.unclaimedForwardDeclarations != null) { |
| 271 switchScope.unclaimedForwardDeclarations |
| 272 .forEach((String name, Builder builder) { |
| 273 if (outerSwitchScope == null) { |
| 274 addCompileTimeError(-1, "Label not found: '$name'."); |
| 275 } else { |
| 276 outerSwitchScope.forwardDeclareLabel(name, builder); |
| 277 } |
| 278 }); |
| 279 } |
| 280 switchScope = outerSwitchScope; |
| 270 } | 281 } |
| 271 | 282 |
| 272 @override | 283 @override |
| 273 JumpTarget createJumpTarget(JumpTargetKind kind, int charOffset) { | 284 JumpTarget createJumpTarget(JumpTargetKind kind, int charOffset) { |
| 274 return new JumpTarget(kind, functionNestingLevel, member, charOffset); | 285 return new JumpTarget(kind, functionNestingLevel, member, charOffset); |
| 275 } | 286 } |
| 276 | 287 |
| 277 @override | 288 @override |
| 278 void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) { | 289 void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) { |
| 279 debugEvent("Metadata"); | 290 debugEvent("Metadata"); |
| (...skipping 1493 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1773 Identifier name = pop(); | 1784 Identifier name = pop(); |
| 1774 VariableDeclaration variable = | 1785 VariableDeclaration variable = |
| 1775 new VariableDeclaration(name.name, isFinal: true); | 1786 new VariableDeclaration(name.name, isFinal: true); |
| 1776 push(new FunctionDeclaration( | 1787 push(new FunctionDeclaration( |
| 1777 variable, new FunctionNode(new InvalidStatement()))); | 1788 variable, new FunctionNode(new InvalidStatement()))); |
| 1778 scope[variable.name] = new KernelVariableBuilder( | 1789 scope[variable.name] = new KernelVariableBuilder( |
| 1779 variable, member ?? classBuilder ?? library, uri); | 1790 variable, member ?? classBuilder ?? library, uri); |
| 1780 enterLocalScope(); | 1791 enterLocalScope(); |
| 1781 } | 1792 } |
| 1782 | 1793 |
| 1794 void enterFunction() { |
| 1795 debugEvent("enterFunction"); |
| 1796 functionNestingLevel++; |
| 1797 push(switchScope ?? NullValue.SwitchScope); |
| 1798 switchScope = null; |
| 1799 } |
| 1800 |
| 1801 void exitFunction() { |
| 1802 debugEvent("exitFunction"); |
| 1803 functionNestingLevel--; |
| 1804 switchScope = pop(); |
| 1805 } |
| 1806 |
| 1783 @override | 1807 @override |
| 1784 void beginFunction(Token token) { | 1808 void beginFunction(Token token) { |
| 1785 debugEvent("beginFunction"); | 1809 debugEvent("beginFunction"); |
| 1786 functionNestingLevel++; | 1810 enterFunction(); |
| 1787 } | 1811 } |
| 1788 | 1812 |
| 1789 @override | 1813 @override |
| 1790 void beginUnnamedFunction(Token token) { | 1814 void beginUnnamedFunction(Token token) { |
| 1791 debugEvent("beginUnnamedFunction"); | 1815 debugEvent("beginUnnamedFunction"); |
| 1792 functionNestingLevel++; | 1816 enterFunction(); |
| 1793 } | 1817 } |
| 1794 | 1818 |
| 1795 @override | 1819 @override |
| 1796 void endFunction(Token getOrSet, Token endToken) { | 1820 void endFunction(Token getOrSet, Token endToken) { |
| 1797 debugEvent("Function"); | 1821 debugEvent("Function"); |
| 1798 Statement body = popStatement(); | 1822 Statement body = popStatement(); |
| 1799 AsyncMarker asyncModifier = pop(); | 1823 AsyncMarker asyncModifier = pop(); |
| 1800 if (functionNestingLevel != 0) { | 1824 if (functionNestingLevel != 0) { |
| 1801 exitLocalScope(); | 1825 exitLocalScope(); |
| 1802 } | 1826 } |
| 1803 FormalParameters formals = pop(); | 1827 FormalParameters formals = pop(); |
| 1804 List<TypeParameter> typeParameters = pop(); | 1828 List<TypeParameter> typeParameters = pop(); |
| 1805 push(formals.addToFunction(new FunctionNode(body, | 1829 push(formals.addToFunction(new FunctionNode(body, |
| 1806 typeParameters: typeParameters, asyncMarker: asyncModifier))); | 1830 typeParameters: typeParameters, asyncMarker: asyncModifier))); |
| 1807 functionNestingLevel--; | |
| 1808 } | 1831 } |
| 1809 | 1832 |
| 1810 @override | 1833 @override |
| 1811 void endFunctionDeclaration(Token token) { | 1834 void endFunctionDeclaration(Token token) { |
| 1812 debugEvent("FunctionDeclaration"); | 1835 debugEvent("FunctionDeclaration"); |
| 1813 FunctionNode function = pop(); | 1836 FunctionNode function = pop(); |
| 1814 exitLocalScope(); | 1837 exitLocalScope(); |
| 1815 FunctionDeclaration declaration = pop(); | 1838 FunctionDeclaration declaration = pop(); |
| 1816 function.returnType = pop() ?? const DynamicType(); | 1839 function.returnType = pop() ?? const DynamicType(); |
| 1817 pop(); // Modifiers. | 1840 pop(); // Modifiers. |
| 1841 exitFunction(); |
| 1818 declaration.function = function; | 1842 declaration.function = function; |
| 1819 function.parent = declaration; | 1843 function.parent = declaration; |
| 1820 push(declaration); | 1844 push(declaration); |
| 1821 } | 1845 } |
| 1822 | 1846 |
| 1823 @override | 1847 @override |
| 1824 void endUnnamedFunction(Token token) { | 1848 void endUnnamedFunction(Token token) { |
| 1825 debugEvent("UnnamedFunction"); | 1849 debugEvent("UnnamedFunction"); |
| 1826 Statement body = popStatement(); | 1850 Statement body = popStatement(); |
| 1827 AsyncMarker asyncModifier = pop(); | 1851 AsyncMarker asyncModifier = pop(); |
| 1828 exitLocalScope(); | 1852 exitLocalScope(); |
| 1829 FormalParameters formals = pop(); | 1853 FormalParameters formals = pop(); |
| 1854 exitFunction(); |
| 1830 List<TypeParameter> typeParameters = pop(); | 1855 List<TypeParameter> typeParameters = pop(); |
| 1831 FunctionNode function = formals.addToFunction(new FunctionNode(body, | 1856 FunctionNode function = formals.addToFunction(new FunctionNode(body, |
| 1832 typeParameters: typeParameters, asyncMarker: asyncModifier)); | 1857 typeParameters: typeParameters, asyncMarker: asyncModifier)); |
| 1833 push(new FunctionExpression(function)); | 1858 push(new FunctionExpression(function)); |
| 1834 functionNestingLevel--; | |
| 1835 } | 1859 } |
| 1836 | 1860 |
| 1837 @override | 1861 @override |
| 1838 void endDoWhileStatement( | 1862 void endDoWhileStatement( |
| 1839 Token doKeyword, Token whileKeyword, Token endToken) { | 1863 Token doKeyword, Token whileKeyword, Token endToken) { |
| 1840 debugEvent("DoWhileStatement"); | 1864 debugEvent("DoWhileStatement"); |
| 1841 Expression condition = popForValue(); | 1865 Expression condition = popForValue(); |
| 1842 Statement body = popStatement(); | 1866 Statement body = popStatement(); |
| 1843 JumpTarget continueTarget = exitContinueTarget(); | 1867 JumpTarget continueTarget = exitContinueTarget(); |
| 1844 JumpTarget breakTarget = exitBreakTarget(); | 1868 JumpTarget breakTarget = exitBreakTarget(); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2026 labels.add(labelOrExpression); | 2050 labels.add(labelOrExpression); |
| 2027 } else { | 2051 } else { |
| 2028 expressions.add(toValue(labelOrExpression)); | 2052 expressions.add(toValue(labelOrExpression)); |
| 2029 } | 2053 } |
| 2030 } | 2054 } |
| 2031 } | 2055 } |
| 2032 assert(scope == switchScope); | 2056 assert(scope == switchScope); |
| 2033 for (Label label in labels) { | 2057 for (Label label in labels) { |
| 2034 if (scope.hasLocalLabel(label.name)) { | 2058 if (scope.hasLocalLabel(label.name)) { |
| 2035 // TODO(ahe): Should validate this is a goto target and not duplicated. | 2059 // TODO(ahe): Should validate this is a goto target and not duplicated. |
| 2060 scope.claimLabel(label.name); |
| 2036 } else { | 2061 } else { |
| 2037 scope.declareLabel(label.name, createGotoTarget(firstToken.charOffset)); | 2062 scope.declareLabel(label.name, createGotoTarget(firstToken.charOffset)); |
| 2038 } | 2063 } |
| 2039 } | 2064 } |
| 2040 push(expressions); | 2065 push(expressions); |
| 2041 push(labels); | 2066 push(labels); |
| 2042 enterLocalScope(); | 2067 enterLocalScope(); |
| 2043 } | 2068 } |
| 2044 | 2069 |
| 2045 @override | 2070 @override |
| 2046 void handleSwitchCase( | 2071 void handleSwitchCase( |
| 2047 int labelCount, | 2072 int labelCount, |
| 2048 int expressionCount, | 2073 int expressionCount, |
| 2049 Token defaultKeyword, | 2074 Token defaultKeyword, |
| 2050 int statementCount, | 2075 int statementCount, |
| 2051 Token firstToken, | 2076 Token firstToken, |
| 2052 Token endToken) { | 2077 Token endToken) { |
| 2053 debugEvent("SwitchCase"); | 2078 debugEvent("SwitchCase"); |
| 2054 Block block = popBlock(statementCount); | 2079 Block block = popBlock(statementCount); |
| 2055 exitLocalScope(); | 2080 exitLocalScope(); |
| 2056 List<Label> labels = pop(); | 2081 List<Label> labels = pop(); |
| 2057 List<Expression> expressions = pop(); | 2082 List<Expression> expressions = pop(); |
| 2058 push(new SwitchCase(expressions, block, isDefault: defaultKeyword != null)); | 2083 push(new SwitchCase(expressions, block, isDefault: defaultKeyword != null) |
| 2084 ..fileOffset = firstToken.charOffset); |
| 2059 push(labels); | 2085 push(labels); |
| 2060 } | 2086 } |
| 2061 | 2087 |
| 2062 @override | 2088 @override |
| 2063 void endSwitchStatement(Token switchKeyword, Token endToken) { | 2089 void endSwitchStatement(Token switchKeyword, Token endToken) { |
| 2064 debugEvent("SwitchStatement"); | 2090 debugEvent("SwitchStatement"); |
| 2065 // Do nothing. Handled by [endSwitchBlock]. | 2091 // Do nothing. Handled by [endSwitchBlock]. |
| 2066 } | 2092 } |
| 2067 | 2093 |
| 2068 @override | 2094 @override |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2144 push(compileTimeErrorInLoopOrSwitch = buildCompileTimeErrorStatement( | 2170 push(compileTimeErrorInLoopOrSwitch = buildCompileTimeErrorStatement( |
| 2145 "Target of continue must be a label.", continueKeyword.charOffset)); | 2171 "Target of continue must be a label.", continueKeyword.charOffset)); |
| 2146 return; | 2172 return; |
| 2147 } | 2173 } |
| 2148 if (target == null) { | 2174 if (target == null) { |
| 2149 if (switchScope == null) { | 2175 if (switchScope == null) { |
| 2150 push(buildCompileTimeErrorStatement( | 2176 push(buildCompileTimeErrorStatement( |
| 2151 "Can't find label '$name'.", continueKeyword.next.charOffset)); | 2177 "Can't find label '$name'.", continueKeyword.next.charOffset)); |
| 2152 return; | 2178 return; |
| 2153 } | 2179 } |
| 2154 switchScope.declareLabel( | 2180 switchScope.forwardDeclareLabel( |
| 2155 identifier.name, target = createGotoTarget(identifier.fileOffset)); | 2181 identifier.name, target = createGotoTarget(identifier.fileOffset)); |
| 2156 } | 2182 } |
| 2157 if (target.isGotoTarget) { | 2183 if (target.isGotoTarget && |
| 2184 target.functionNestingLevel == functionNestingLevel) { |
| 2158 ContinueSwitchStatement statement = new ContinueSwitchStatement(null); | 2185 ContinueSwitchStatement statement = new ContinueSwitchStatement(null); |
| 2159 target.addGoto(statement); | 2186 target.addGoto(statement); |
| 2160 push(statement); | 2187 push(statement); |
| 2161 return; | 2188 return; |
| 2162 } | 2189 } |
| 2163 } | 2190 } |
| 2164 if (target == null) { | 2191 if (target == null) { |
| 2165 push(compileTimeErrorInLoopOrSwitch = buildCompileTimeErrorStatement( | 2192 push(compileTimeErrorInLoopOrSwitch = buildCompileTimeErrorStatement( |
| 2166 "No target of continue.", continueKeyword.charOffset)); | 2193 "No target of continue.", continueKeyword.charOffset)); |
| 2167 } else if (!target.isContinueTarget) { | 2194 } else if (!target.isContinueTarget) { |
| (...skipping 568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2736 } else if (node is PrefixBuilder) { | 2763 } else if (node is PrefixBuilder) { |
| 2737 return node.name; | 2764 return node.name; |
| 2738 } else if (node is ThisAccessor) { | 2765 } else if (node is ThisAccessor) { |
| 2739 return node.isSuper ? "super" : "this"; | 2766 return node.isSuper ? "super" : "this"; |
| 2740 } else if (node is BuilderAccessor) { | 2767 } else if (node is BuilderAccessor) { |
| 2741 return node.plainNameForRead; | 2768 return node.plainNameForRead; |
| 2742 } else { | 2769 } else { |
| 2743 return internalError("Unhandled: ${node.runtimeType}"); | 2770 return internalError("Unhandled: ${node.runtimeType}"); |
| 2744 } | 2771 } |
| 2745 } | 2772 } |
| OLD | NEW |