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 interface TreeElements { | 5 interface TreeElements { |
| 6 Element operator[](Node node); | 6 Element operator[](Node node); |
| 7 Selector getSelector(Send send); | 7 Selector getSelector(Send send); |
| 8 Type getType(TypeAnnotation annotation); | 8 Type getType(TypeAnnotation annotation); |
| 9 } | 9 } |
| 10 | 10 |
| (...skipping 1195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1206 String labelName = node.target.source.slowToString(); | 1206 String labelName = node.target.source.slowToString(); |
| 1207 LabelElement label = statementScope.lookupLabel(labelName); | 1207 LabelElement label = statementScope.lookupLabel(labelName); |
| 1208 if (label === null) { | 1208 if (label === null) { |
| 1209 error(node.target, MessageKind.UNBOUND_LABEL, [labelName]); | 1209 error(node.target, MessageKind.UNBOUND_LABEL, [labelName]); |
| 1210 return; | 1210 return; |
| 1211 } | 1211 } |
| 1212 target = label.target; | 1212 target = label.target; |
| 1213 if (!target.statement.isValidContinueTarget()) { | 1213 if (!target.statement.isValidContinueTarget()) { |
| 1214 error(node.target, MessageKind.INVALID_CONTINUE, [labelName]); | 1214 error(node.target, MessageKind.INVALID_CONTINUE, [labelName]); |
| 1215 } | 1215 } |
| 1216 // TODO(lrn): Handle continues to switch cases. | |
| 1217 if (target.statement is SwitchCase) { | |
| 1218 unimplemented(node, "continue to switch case"); | |
| 1219 } | |
| 1216 label.setContinueTarget(); | 1220 label.setContinueTarget(); |
| 1217 mapping[node.target] = label; | 1221 mapping[node.target] = label; |
| 1218 } | 1222 } |
| 1219 mapping[node] = target; | 1223 mapping[node] = target; |
| 1220 } | 1224 } |
| 1221 | 1225 |
| 1222 visitForIn(ForIn node) { | 1226 visitForIn(ForIn node) { |
| 1223 visit(node.expression); | 1227 visit(node.expression); |
| 1224 Scope scope = new BlockScope(context); | 1228 Scope scope = new BlockScope(context); |
| 1225 Node declaration = node.declaredIdentifier; | 1229 Node declaration = node.declaredIdentifier; |
| 1226 visitIn(declaration, scope); | 1230 visitIn(declaration, scope); |
| 1227 visitLoopBodyIn(node, node.body, scope); | 1231 visitLoopBodyIn(node, node.body, scope); |
| 1228 | 1232 |
| 1229 // TODO(lrn): Also allow a single identifier. | 1233 // TODO(lrn): Also allow a single identifier. |
| 1230 if ((declaration is !Send || declaration.asSend().selector is !Identifier) | 1234 if ((declaration is !Send || declaration.asSend().selector is !Identifier) |
| 1231 && (declaration is !VariableDefinitions || | 1235 && (declaration is !VariableDefinitions || |
| 1232 !declaration.asVariableDefinitions().definitions.nodes.tail.isEmpty())) | 1236 !declaration.asVariableDefinitions().definitions.nodes.tail.isEmpty())) |
| 1233 { | 1237 { |
| 1234 // The variable declaration is either not an identifier, not a | 1238 // The variable declaration is either not an identifier, not a |
| 1235 // declaration, or it's declaring more than one variable. | 1239 // declaration, or it's declaring more than one variable. |
| 1236 error(node.declaredIdentifier, MessageKind.INVALID_FOR_IN, []); | 1240 error(node.declaredIdentifier, MessageKind.INVALID_FOR_IN, []); |
| 1237 } | 1241 } |
| 1238 } | 1242 } |
| 1239 | 1243 |
| 1244 visitLabel(Label node) { | |
|
ahe
2012/05/14 09:24:25
Perhaps add a comment to explain why this is empty
Lasse Reichstein Nielsen
2012/05/14 10:34:58
Done.
| |
| 1245 } | |
| 1246 | |
| 1240 visitLabeledStatement(LabeledStatement node) { | 1247 visitLabeledStatement(LabeledStatement node) { |
| 1241 String labelName = node.label.slowToString(); | 1248 String labelName = node.label.slowToString(); |
| 1242 LabelElement existingElement = statementScope.lookupLabel(labelName); | 1249 LabelElement existingElement = statementScope.lookupLabel(labelName); |
| 1243 if (existingElement !== null) { | 1250 if (existingElement !== null) { |
| 1244 warning(node.label, MessageKind.DUPLICATE_LABEL, [labelName]); | 1251 warning(node.label, MessageKind.DUPLICATE_LABEL, [labelName]); |
| 1245 warning(existingElement.label, MessageKind.EXISTING_LABEL, [labelName]); | 1252 warning(existingElement.label, MessageKind.EXISTING_LABEL, [labelName]); |
| 1246 } | 1253 } |
| 1247 Node body = node.getBody(); | 1254 Node body = node.getBody(); |
| 1248 TargetElement targetElement = getOrCreateTargetElement(body); | 1255 TargetElement targetElement = getOrCreateTargetElement(body); |
| 1249 | 1256 |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 1276 } | 1283 } |
| 1277 | 1284 |
| 1278 visitSwitchStatement(SwitchStatement node) { | 1285 visitSwitchStatement(SwitchStatement node) { |
| 1279 node.expression.accept(this); | 1286 node.expression.accept(this); |
| 1280 | 1287 |
| 1281 TargetElement breakElement = getOrCreateTargetElement(node); | 1288 TargetElement breakElement = getOrCreateTargetElement(node); |
| 1282 Map<String, LabelElement> continueLabels = <LabelElement>{}; | 1289 Map<String, LabelElement> continueLabels = <LabelElement>{}; |
| 1283 Link<Node> cases = node.cases.nodes; | 1290 Link<Node> cases = node.cases.nodes; |
| 1284 while (!cases.isEmpty()) { | 1291 while (!cases.isEmpty()) { |
| 1285 SwitchCase switchCase = cases.head; | 1292 SwitchCase switchCase = cases.head; |
| 1286 if (switchCase.label !== null) { | 1293 for (Node labelOrCase in switchCase.labelsAndCases) { |
| 1287 Label label = switchCase.label; | 1294 if (labelOrCase is! Label) continue; |
| 1295 Label label = labelOrCase; | |
| 1288 String labelName = label.slowToString(); | 1296 String labelName = label.slowToString(); |
| 1289 | 1297 |
| 1290 LabelElement existingElement = continueLabels[labelName]; | 1298 LabelElement existingElement = continueLabels[labelName]; |
| 1291 if (existingElement !== null) { | 1299 if (existingElement !== null) { |
| 1292 // It's an error if the same label occurs twice in the same switch. | 1300 // It's an error if the same label occurs twice in the same switch. |
| 1293 warning(label, MessageKind.DUPLICATE_LABEL, [labelName]); | 1301 warning(label, MessageKind.DUPLICATE_LABEL, [labelName]); |
| 1294 error(existingElement.label, MessageKind.EXISTING_LABEL, [labelName]); | 1302 error(existingElement.label, MessageKind.EXISTING_LABEL, [labelName]); |
| 1295 } else { | 1303 } else { |
| 1296 // It's only a warning if it shadows another label. | 1304 // It's only a warning if it shadows another label. |
| 1297 existingElement = statementScope.lookupLabel(labelName); | 1305 existingElement = statementScope.lookupLabel(labelName); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1308 enclosingElement); | 1316 enclosingElement); |
| 1309 mapping[switchCase] = targetElement; | 1317 mapping[switchCase] = targetElement; |
| 1310 | 1318 |
| 1311 LabelElement labelElement = | 1319 LabelElement labelElement = |
| 1312 new LabelElement(label, labelName, | 1320 new LabelElement(label, labelName, |
| 1313 targetElement, enclosingElement); | 1321 targetElement, enclosingElement); |
| 1314 mapping[label] = labelElement; | 1322 mapping[label] = labelElement; |
| 1315 continueLabels[labelName] = labelElement; | 1323 continueLabels[labelName] = labelElement; |
| 1316 } | 1324 } |
| 1317 cases = cases.tail; | 1325 cases = cases.tail; |
| 1326 // Test that only the last case, if any, is a default case. | |
| 1318 if (switchCase.defaultKeyword !== null && !cases.isEmpty()) { | 1327 if (switchCase.defaultKeyword !== null && !cases.isEmpty()) { |
| 1319 error(switchCase, MessageKind.INVALID_CASE_DEFAULT); | 1328 error(switchCase, MessageKind.INVALID_CASE_DEFAULT); |
| 1320 } | 1329 } |
| 1321 } | 1330 } |
| 1331 | |
| 1322 statementScope.enterSwitch(breakElement, continueLabels); | 1332 statementScope.enterSwitch(breakElement, continueLabels); |
| 1323 node.cases.accept(this); | 1333 node.cases.accept(this); |
| 1324 statementScope.exitSwitch(); | 1334 statementScope.exitSwitch(); |
| 1325 | 1335 |
| 1326 // Clean-up unused labels | 1336 // Clean-up unused labels. |
| 1327 continueLabels.forEach((String key, LabelElement label) { | 1337 continueLabels.forEach((String key, LabelElement label) { |
| 1328 TargetElement targetElement = label.target; | |
| 1329 SwitchCase switchCase = targetElement.statement; | |
| 1330 if (!label.isContinueTarget) { | 1338 if (!label.isContinueTarget) { |
| 1339 TargetElement targetElement = label.target; | |
| 1340 SwitchCase switchCase = targetElement.statement; | |
| 1331 mapping.remove(switchCase); | 1341 mapping.remove(switchCase); |
| 1332 mapping.remove(label.label); | 1342 mapping.remove(label.label); |
| 1333 } | 1343 } |
| 1334 }); | 1344 }); |
| 1335 } | 1345 } |
| 1336 | 1346 |
| 1337 visitSwitchCase(SwitchCase node) { | 1347 visitSwitchCase(SwitchCase node) { |
| 1338 // The label was handled in [visitSwitchStatement(SwitchStatement)]. | 1348 node.labelsAndCases.accept(this); |
| 1339 node.expressions.accept(this); | |
| 1340 visitIn(node.statements, new BlockScope(context)); | 1349 visitIn(node.statements, new BlockScope(context)); |
| 1341 } | 1350 } |
| 1342 | 1351 |
| 1352 visitCaseMatch(CaseMatch node) { | |
| 1353 visit(node.expression); | |
| 1354 } | |
| 1355 | |
| 1343 visitTryStatement(TryStatement node) { | 1356 visitTryStatement(TryStatement node) { |
| 1344 visit(node.tryBlock); | 1357 visit(node.tryBlock); |
| 1345 if (node.catchBlocks.isEmpty() && node.finallyBlock == null) { | 1358 if (node.catchBlocks.isEmpty() && node.finallyBlock == null) { |
| 1346 // TODO(ngeoffray): The precise location is | 1359 // TODO(ngeoffray): The precise location is |
| 1347 // node.getEndtoken.next. Adjust when issue #1581 is fixed. | 1360 // node.getEndtoken.next. Adjust when issue #1581 is fixed. |
| 1348 error(node, MessageKind.NO_CATCH_NOR_FINALLY); | 1361 error(node, MessageKind.NO_CATCH_NOR_FINALLY); |
| 1349 } | 1362 } |
| 1350 visit(node.catchBlocks); | 1363 visit(node.catchBlocks); |
| 1351 visit(node.finallyBlock); | 1364 visit(node.finallyBlock); |
| 1352 } | 1365 } |
| (...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1926 | 1939 |
| 1927 TopScope(LibraryElement library) : super(null, library); | 1940 TopScope(LibraryElement library) : super(null, library); |
| 1928 Element lookup(SourceString name) { | 1941 Element lookup(SourceString name) { |
| 1929 return library.find(name); | 1942 return library.find(name); |
| 1930 } | 1943 } |
| 1931 | 1944 |
| 1932 Element add(Element newElement) { | 1945 Element add(Element newElement) { |
| 1933 throw "Cannot add an element in the top scope"; | 1946 throw "Cannot add an element in the top scope"; |
| 1934 } | 1947 } |
| 1935 } | 1948 } |
| OLD | NEW |