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

Side by Side Diff: pkg/front_end/lib/src/fasta/kernel/body_builder.dart

Issue 2746923002: Implement nested switches and missing switch continue targets. (Closed)
Patch Set: Long line. Created 3 years, 9 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
OLDNEW
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « pkg/front_end/lib/src/fasta/fasta.dart ('k') | pkg/front_end/lib/src/fasta/kernel/kernel_target.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698