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 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 442 error(selector, MessageKind.CANNOT_RESOLVE, [name]); | 442 error(selector, MessageKind.CANNOT_RESOLVE, [name]); |
| 443 } else if (target.kind != ElementKind.FIELD) { | 443 } else if (target.kind != ElementKind.FIELD) { |
| 444 error(selector, MessageKind.NOT_A_FIELD, [name]); | 444 error(selector, MessageKind.NOT_A_FIELD, [name]); |
| 445 } else if (!target.isInstanceMember()) { | 445 } else if (!target.isInstanceMember()) { |
| 446 error(selector, MessageKind.INIT_STATIC_FIELD, [name]); | 446 error(selector, MessageKind.INIT_STATIC_FIELD, [name]); |
| 447 } | 447 } |
| 448 } else { | 448 } else { |
| 449 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); | 449 error(init, MessageKind.INVALID_RECEIVER_IN_INITIALIZER); |
| 450 } | 450 } |
| 451 visitor.useElement(init, target); | 451 visitor.useElement(init, target); |
| 452 visitor.world.registerStaticUse(target); | |
| 452 // Check for duplicate initializers. | 453 // Check for duplicate initializers. |
| 453 if (initialized.containsKey(name)) { | 454 if (initialized.containsKey(name)) { |
| 454 error(init, MessageKind.DUPLICATE_INITIALIZER, [name]); | 455 error(init, MessageKind.DUPLICATE_INITIALIZER, [name]); |
| 455 warning(initialized[name], MessageKind.ALREADY_INITIALIZED, [name]); | 456 warning(initialized[name], MessageKind.ALREADY_INITIALIZED, [name]); |
| 456 } | 457 } |
| 457 initialized[name] = init; | 458 initialized[name] = init; |
| 458 // Resolve initializing value. | 459 // Resolve initializing value. |
| 459 visitor.visitInStaticContext(init.arguments.head); | 460 visitor.visitInStaticContext(init.arguments.head); |
| 460 } | 461 } |
| 461 | 462 |
| 462 Element resolveSuperOrThisForSend(FunctionElement constructor, | 463 Element resolveSuperOrThisForSend(FunctionElement constructor, |
| 463 FunctionExpression functionNode, | 464 FunctionExpression functionNode, |
| 464 Send call) { | 465 Send call) { |
| 465 // Resolve the selector and the arguments. | 466 // Resolve the selector and the arguments. |
| 466 ResolverTask resolver = visitor.compiler.resolver; | 467 ResolverTask resolver = visitor.compiler.resolver; |
| 467 visitor.inStaticContext(() { | 468 visitor.inStaticContext(() { |
| 468 visitor.resolveSelector(call); | 469 visitor.resolveSelector(call); |
| 469 visitor.visitArguments(call.argumentsNode); | 470 visitor.resolveArguments(call.argumentsNode); |
| 470 }); | 471 }); |
| 471 Selector selector = visitor.mapping.getSelector(call); | 472 Selector selector = visitor.mapping.getSelector(call); |
| 472 bool isSuperCall = Initializers.isSuperConstructorCall(call); | 473 bool isSuperCall = Initializers.isSuperConstructorCall(call); |
| 473 SourceString constructorName = resolver.getConstructorName(call); | 474 SourceString constructorName = resolver.getConstructorName(call); |
| 474 Element result = resolveSuperOrThis( | 475 Element result = resolveSuperOrThis( |
| 475 constructor, isSuperCall, false, constructorName, selector, call); | 476 constructor, isSuperCall, false, constructorName, selector, call); |
| 476 visitor.useElement(call, result); | 477 visitor.useElement(call, result); |
| 478 visitor.world.registerStaticUse(result); | |
| 477 return result; | 479 return result; |
| 478 } | 480 } |
| 479 | 481 |
| 480 void resolveImplicitSuperConstructorSend(FunctionElement constructor, | 482 void resolveImplicitSuperConstructorSend(FunctionElement constructor, |
| 481 FunctionExpression functionNode) { | 483 FunctionExpression functionNode) { |
| 482 // If the class has a super resolve the implicit super call. | 484 // If the class has a super resolve the implicit super call. |
| 483 ClassElement classElement = constructor.getEnclosingClass(); | 485 ClassElement classElement = constructor.getEnclosingClass(); |
| 484 ClassElement superClass = classElement.superclass; | 486 ClassElement superClass = classElement.superclass; |
| 485 if (classElement != visitor.compiler.objectClass) { | 487 if (classElement != visitor.compiler.objectClass) { |
| 486 assert(superClass !== null); | 488 assert(superClass !== null); |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 956 if (existing != element) { | 958 if (existing != element) { |
| 957 error(node, MessageKind.DUPLICATE_DEFINITION, [node]); | 959 error(node, MessageKind.DUPLICATE_DEFINITION, [node]); |
| 958 } | 960 } |
| 959 } | 961 } |
| 960 return element; | 962 return element; |
| 961 } | 963 } |
| 962 | 964 |
| 963 Element useElement(Node node, Element element) { | 965 Element useElement(Node node, Element element) { |
| 964 if (element === null) return null; | 966 if (element === null) return null; |
| 965 mapping[node] = element; | 967 mapping[node] = element; |
| 966 if (element.isTopLevel() || element.isMember()) { | |
| 967 if (element.isInstanceMember()) { | |
| 968 var send = node.asSend(); | |
| 969 if (send !== null) { | |
| 970 Selector selector = mapping.getSelector(send); | |
| 971 if (selector !== null) { | |
| 972 world.registerDynamicInvocation(element.name, selector); | |
| 973 } | |
| 974 } | |
| 975 } else { | |
| 976 if (!element.isPrefix() && | |
| 977 !element.isClass() && | |
| 978 !element.isTypedef() && | |
| 979 !element.isTypeVariable()) { | |
| 980 world.registerStaticUse(element); | |
| 981 } | |
| 982 } | |
| 983 } | |
| 984 return element; | 968 return element; |
|
ahe
2012/08/15 14:32:21
These two lines can be merged.
And yay!
kasperl
2012/08/16 10:35:47
Done.
| |
| 985 } | 969 } |
| 986 | 970 |
| 987 Type useType(TypeAnnotation annotation, Type type) { | 971 Type useType(TypeAnnotation annotation, Type type) { |
| 988 if (type !== null) { | 972 if (type !== null) { |
| 989 mapping.setType(annotation, type); | 973 mapping.setType(annotation, type); |
| 990 useElement(annotation, type.element); | 974 useElement(annotation, type.element); |
| 991 } | 975 } |
| 992 return type; | 976 return type; |
| 993 } | 977 } |
| 994 | 978 |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1178 if (node === null) { | 1162 if (node === null) { |
| 1179 // node is of the form !Type. | 1163 // node is of the form !Type. |
| 1180 node = argument.asSend().receiver.asTypeAnnotation(); | 1164 node = argument.asSend().receiver.asTypeAnnotation(); |
| 1181 if (node === null) compiler.cancel("malformed send"); | 1165 if (node === null) compiler.cancel("malformed send"); |
| 1182 } | 1166 } |
| 1183 return resolveTypeRequired(node); | 1167 return resolveTypeRequired(node); |
| 1184 } | 1168 } |
| 1185 | 1169 |
| 1186 static Selector computeSendSelector(Send node, LibraryElement library) { | 1170 static Selector computeSendSelector(Send node, LibraryElement library) { |
| 1187 // First determine if this is part of an assignment. | 1171 // First determine if this is part of an assignment. |
| 1188 bool isSet = node is SendSet; | 1172 bool isSet = node.asSendSet() !== null; |
| 1189 | 1173 |
| 1190 if (node.isIndex) { | 1174 if (node.isIndex) { |
| 1191 return isSet ? new Selector.indexSet() : new Selector.index(); | 1175 return isSet ? new Selector.indexSet() : new Selector.index(); |
| 1192 } | 1176 } |
| 1193 | 1177 |
| 1194 if (node.isOperator) { | 1178 if (node.isOperator) { |
| 1195 SourceString source = node.selector.asOperator().source; | 1179 SourceString source = node.selector.asOperator().source; |
| 1196 switch (source.stringValue) { | 1180 String string = source.stringValue; |
| 1197 case '!' : case '&&' : case '||': | 1181 if (string === '!' || string === '&&' || string == '||' || |
| 1198 case 'is' : case 'as' : | 1182 string === 'is' || string === 'as' || |
| 1199 case '===': case '!==': | 1183 string === '===' || string === '!==' || |
| 1200 case '>>>': | 1184 string === '>>>') { |
| 1201 return null; | 1185 return null; |
| 1202 } | 1186 } |
| 1203 return node.arguments.isEmpty() | 1187 return node.arguments.isEmpty() |
| 1204 ? new Selector.unaryOperator(source) | 1188 ? new Selector.unaryOperator(source) |
| 1205 : new Selector.binaryOperator(source); | 1189 : new Selector.binaryOperator(source); |
| 1206 } | 1190 } |
| 1207 | 1191 |
| 1208 Identifier identifier = node.selector.asIdentifier(); | 1192 Identifier identifier = node.selector.asIdentifier(); |
| 1209 if (node.isPropertyAccess) { | 1193 if (node.isPropertyAccess) { |
| 1210 assert(!isSet); | 1194 assert(!isSet); |
| 1211 return new Selector.getter(identifier.source, library); | 1195 return new Selector.getter(identifier.source, library); |
| 1212 } else if (isSet) { | 1196 } else if (isSet) { |
| 1213 return new Selector.setter(identifier.source, library); | 1197 return new Selector.setter(identifier.source, library); |
| 1214 } | 1198 } |
| 1215 | 1199 |
| 1216 // Compute the arity and the list of named arguments. | 1200 // Compute the arity and the list of named arguments. |
| 1217 int arity = 0; | 1201 int arity = 0; |
| 1218 List<SourceString> named = <SourceString>[]; | 1202 List<SourceString> named = <SourceString>[]; |
| 1219 for (Link<Node> link = node.argumentsNode.nodes; | 1203 for (Link<Node> link = node.argumentsNode.nodes; |
| 1220 !link.isEmpty(); | 1204 !link.isEmpty(); |
| 1221 link = link.tail) { | 1205 link = link.tail) { |
| 1222 Expression argument = link.head; | 1206 Expression argument = link.head; |
| 1223 if (argument.asNamedArgument() != null) { | 1207 NamedArgument namedArgument = argument.asNamedArgument(); |
| 1224 named.add((argument as NamedArgument).name.source); | 1208 if (namedArgument !== null) { |
| 1209 named.add(namedArgument.name.source); | |
| 1225 } | 1210 } |
| 1226 arity++; | 1211 arity++; |
| 1227 } | 1212 } |
| 1228 | 1213 |
| 1229 // If we're invoking a closure, we do not have an identifier. In | 1214 // If we're invoking a closure, we do not have an identifier. |
| 1230 // that case, we create a wildcard selector that can call any | 1215 return (identifier === null) |
| 1231 // method that may have been closurized. | 1216 ? new Selector.callClosure(arity, named) |
| 1232 return (identifier == null) | |
| 1233 ? new Selector.callAny(arity, named) | |
| 1234 : new Selector.call(identifier.source, library, arity, named); | 1217 : new Selector.call(identifier.source, library, arity, named); |
| 1235 } | 1218 } |
| 1236 | 1219 |
| 1237 Selector resolveSelector(Send node) { | 1220 Selector resolveSelector(Send node) { |
| 1238 LibraryElement library = enclosingElement.getLibrary(); | 1221 LibraryElement library = enclosingElement.getLibrary(); |
| 1239 Selector selector = computeSendSelector(node, library); | 1222 Selector selector = computeSendSelector(node, library); |
| 1240 if (selector != null) mapping.setSelector(node, selector); | 1223 if (selector != null) mapping.setSelector(node, selector); |
| 1241 return selector; | 1224 return selector; |
| 1242 } | 1225 } |
| 1243 | 1226 |
| 1244 void visitArguments(NodeList list) { | 1227 void resolveArguments(NodeList list) { |
| 1228 if (list === null) return; | |
| 1245 bool seenNamedArgument = false; | 1229 bool seenNamedArgument = false; |
| 1246 for (Link<Node> link = list.nodes; !link.isEmpty(); link = link.tail) { | 1230 for (Link<Node> link = list.nodes; !link.isEmpty(); link = link.tail) { |
| 1247 Expression argument = link.head; | 1231 Expression argument = link.head; |
| 1248 visit(argument); | 1232 visit(argument); |
| 1249 if (argument.asNamedArgument() != null) { | 1233 if (argument.asNamedArgument() != null) { |
| 1250 seenNamedArgument = true; | 1234 seenNamedArgument = true; |
| 1251 } else if (seenNamedArgument) { | 1235 } else if (seenNamedArgument) { |
| 1252 error(argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED); | 1236 error(argument, MessageKind.INVALID_ARGUMENT_AFTER_NAMED); |
| 1253 } | 1237 } |
| 1254 } | 1238 } |
| 1255 } | 1239 } |
| 1256 | 1240 |
| 1257 visitSend(Send node) { | 1241 visitSend(Send node) { |
| 1258 Element target = resolveSend(node); | 1242 Element target = resolveSend(node); |
| 1259 if (node.isOperator) { | |
| 1260 Operator op = node.selector.asOperator(); | |
| 1261 if (op.source.stringValue === 'is' || op.source.stringValue === 'as') { | |
| 1262 resolveTypeTest(node.arguments.head); | |
| 1263 assert(node.arguments.tail.isEmpty()); | |
| 1264 } else if (node.arguments.isEmpty()) { | |
| 1265 assert(op.token.kind !== PLUS_TOKEN); | |
| 1266 } else { | |
| 1267 visit(node.argumentsNode); | |
| 1268 } | |
| 1269 } else if (node.isIndex) { | |
| 1270 visit(node.argumentsNode); | |
| 1271 assert(node.arguments.tail.isEmpty()); | |
| 1272 } else if (node.isPropertyAccess) { | |
| 1273 // Nothing to do here. | |
| 1274 } else { | |
| 1275 visitArguments(node.argumentsNode); | |
| 1276 } | |
| 1277 | |
| 1278 if (target != null && target.kind == ElementKind.ABSTRACT_FIELD) { | 1243 if (target != null && target.kind == ElementKind.ABSTRACT_FIELD) { |
| 1279 AbstractFieldElement field = target; | 1244 AbstractFieldElement field = target; |
| 1280 target = field.getter; | 1245 target = field.getter; |
| 1281 } | 1246 } |
| 1247 | |
| 1248 bool resolvedArguments = false; | |
| 1249 if (node.isOperator) { | |
| 1250 String operatorString = node.selector.asOperator().source.stringValue; | |
| 1251 if (operatorString === 'is' || operatorString === 'as') { | |
| 1252 assert(node.arguments.tail.isEmpty()); | |
| 1253 resolveTypeTest(node.arguments.head); | |
| 1254 resolvedArguments = true; | |
| 1255 } | |
| 1256 } | |
| 1257 | |
| 1258 if (!resolvedArguments) { | |
| 1259 resolveArguments(node.argumentsNode); | |
| 1260 } | |
| 1261 | |
| 1262 // If the selector is null, it means that we will not be generating | |
| 1263 // code for this as a send. | |
| 1264 Selector selector = mapping.getSelector(node); | |
| 1265 if (selector === null) return; | |
| 1266 | |
| 1267 // If we don't know what we're calling or if we are calling a getter, | |
| 1268 // we need to register that fact that we may be calling a closure | |
| 1269 // with the same arguments. | |
| 1282 if (node.isCall && | 1270 if (node.isCall && |
| 1283 (target === null || | 1271 (target === null || |
| 1284 target.isGetter() || | 1272 target.isGetter() || |
| 1285 Elements.isClosureSend(node, target))) { | 1273 Elements.isClosureSend(node, target))) { |
| 1286 Selector selector = mapping.getSelector(node); | 1274 Selector call = new Selector.callClosureFrom(selector); |
| 1287 Selector call = new Selector.call( | 1275 world.registerDynamicInvocation(call.name, call); |
| 1288 compiler.namer.CLOSURE_INVOCATION_NAME, | |
| 1289 selector.library, | |
| 1290 selector.argumentCount, | |
| 1291 selector.namedArguments); | |
| 1292 world.registerDynamicInvocation(compiler.namer.CLOSURE_INVOCATION_NAME, | |
| 1293 call); | |
| 1294 } | 1276 } |
| 1277 | |
| 1295 // TODO(ngeoffray): We should do the check in | 1278 // TODO(ngeoffray): We should do the check in |
| 1296 // visitExpressionStatement instead. | 1279 // visitExpressionStatement instead. |
| 1297 if (target === compiler.assertMethod && !node.isCall) { | 1280 if (target === compiler.assertMethod && !node.isCall) { |
| 1298 // We can only use assert by calling it. | 1281 // We can only use assert by calling it. |
| 1299 if (!inInstanceContext) { | 1282 if (!inInstanceContext) { |
| 1300 error(node, MessageKind.MISSING_ARGUMENTS_TO_ASSERT, [node]); | 1283 error(node, MessageKind.MISSING_ARGUMENTS_TO_ASSERT, [node]); |
| 1301 } | 1284 } |
| 1302 target = null; | 1285 target = null; |
| 1303 } | 1286 } |
| 1287 | |
| 1304 // TODO(ngeoffray): Warn if target is null and the send is | 1288 // TODO(ngeoffray): Warn if target is null and the send is |
| 1305 // unqualified. | 1289 // unqualified. |
| 1306 useElement(node, target); | 1290 useElement(node, target); |
| 1307 if (target === null) registerDynamicSend(node); | 1291 registerSend(node, selector, target); |
| 1308 if (node.isPropertyAccess) return target; | 1292 return node.isPropertyAccess ? target : null; |
| 1309 } | 1293 } |
| 1310 | 1294 |
| 1311 visitSendSet(SendSet node) { | 1295 visitSendSet(SendSet node) { |
| 1312 Element target = resolveSend(node); | 1296 Element target = resolveSend(node); |
| 1313 Element setter = null; | 1297 Element setter = target; |
| 1314 Element getter = null; | 1298 Element getter = target; |
| 1315 if (target != null && target.kind == ElementKind.ABSTRACT_FIELD) { | 1299 if (target != null && target.kind == ElementKind.ABSTRACT_FIELD) { |
| 1316 AbstractFieldElement field = target; | 1300 AbstractFieldElement field = target; |
| 1317 setter = field.setter; | 1301 setter = field.setter; |
| 1318 getter = field.getter; | 1302 getter = field.getter; |
| 1319 } else { | |
| 1320 setter = target; | |
| 1321 getter = target; | |
| 1322 } | 1303 } |
| 1304 | |
| 1305 visit(node.argumentsNode); | |
| 1306 | |
| 1323 // TODO(ngeoffray): Check if the target can be assigned. | 1307 // TODO(ngeoffray): Check if the target can be assigned. |
| 1324 Identifier identifier = node.assignmentOperator; | |
| 1325 bool compoundAssignment = identifier.source.stringValue !== '='; | |
| 1326 if (compoundAssignment) { | |
| 1327 useElement(node.selector, getter); | |
| 1328 } | |
| 1329 visit(node.argumentsNode); | |
| 1330 // TODO(ngeoffray): Warn if target is null and the send is | 1308 // TODO(ngeoffray): Warn if target is null and the send is |
| 1331 // unqualified. | 1309 // unqualified. |
| 1332 registerDynamicSend(node); | 1310 |
| 1311 Selector selector = mapping.getSelector(node); | |
| 1312 Identifier identifier = node.assignmentOperator; | |
| 1313 bool isCompound = identifier.source.stringValue !== '='; | |
|
floitsch
2012/08/15 14:14:04
this should be a predicate on the SendSet node.
No
| |
| 1314 if (isCompound) { | |
| 1315 useElement(node.selector, getter); | |
| 1316 registerSend(node, new Selector.getterFrom(selector), getter); | |
| 1317 } | |
| 1318 | |
| 1319 registerSend(node, selector, setter); | |
| 1333 return useElement(node, setter); | 1320 return useElement(node, setter); |
| 1334 } | 1321 } |
| 1335 | 1322 |
| 1336 registerDynamicSend(Send node) { | 1323 void registerSend(Node node, Selector selector, Element target) { |
| 1337 Identifier id = node.selector.asIdentifier(); | 1324 if (target === null || target.isInstanceMember()) { |
| 1338 if (id === null) return; | 1325 if (selector.isGetter()) { |
| 1339 SourceString name = node.selector.asIdentifier().source; | 1326 world.registerDynamicGetter(selector.name, selector); |
| 1340 if (node.isIndex && node is SendSet) { | 1327 } else if (selector.isSetter()) { |
| 1341 name = Elements.constructOperatorName( | 1328 world.registerDynamicSetter(selector.name, selector); |
| 1342 const SourceString('operator'), | 1329 } else { |
| 1343 const SourceString('[]=')); | 1330 world.registerDynamicInvocation(selector.name, selector); |
| 1344 } else if (node.selector.asOperator() != null) { | |
| 1345 switch (name.stringValue) { | |
| 1346 case '===': | |
| 1347 case '!==': | |
| 1348 case '!': | |
| 1349 case '&&': | |
| 1350 case '||': | |
| 1351 case 'is': | |
| 1352 case 'as': | |
| 1353 case '>>>': | |
| 1354 return null; | |
| 1355 } | 1331 } |
| 1356 name = Elements.constructOperatorName( | 1332 } else if (Elements.isStaticOrTopLevel(target)) { |
| 1357 const SourceString('operator'), | 1333 world.registerStaticUse(target); |
| 1358 name, | |
| 1359 node.argumentsNode is Prefix); | |
| 1360 } | 1334 } |
| 1361 Selector selector = mapping.getSelector(node); | 1335 |
| 1362 if (selector.isGetter()) { | 1336 // TODO(kasperl): Pass the selector directly. |
| 1363 world.registerDynamicGetter(name, selector); | |
| 1364 } else if (selector.isSetter()) { | |
| 1365 world.registerDynamicSetter(name, selector); | |
| 1366 // Also register the getter for compound assignments. | |
| 1367 LibraryElement library = enclosingElement.getLibrary(); | |
| 1368 Selector getter = new Selector.getter(name, library); | |
| 1369 world.registerDynamicGetter(name, getter); | |
| 1370 } else { | |
| 1371 if (selector.isIndexSet()) { | |
| 1372 // Also register the index selector for compound assignments. | |
| 1373 Selector index = new Selector.index(); | |
| 1374 world.registerDynamicInvocation(index.name, index); | |
| 1375 } | |
| 1376 world.registerDynamicInvocation(name, selector); | |
| 1377 } | |
| 1378 var interceptor = new Interceptors(compiler).getStaticInterceptor( | 1337 var interceptor = new Interceptors(compiler).getStaticInterceptor( |
| 1379 name, | 1338 selector.name, |
| 1380 node.argumentCount()); | 1339 selector.argumentCount); |
| 1381 if (interceptor !== null) { | 1340 if (interceptor !== null) { |
| 1382 world.registerStaticUse(interceptor); | 1341 world.registerStaticUse(interceptor); |
| 1383 } | 1342 } |
| 1384 } | 1343 } |
| 1385 | 1344 |
| 1386 visitLiteralInt(LiteralInt node) { | 1345 visitLiteralInt(LiteralInt node) { |
| 1387 } | 1346 } |
| 1388 | 1347 |
| 1389 visitLiteralDouble(LiteralDouble node) { | 1348 visitLiteralDouble(LiteralDouble node) { |
| 1390 } | 1349 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1435 | 1394 |
| 1436 visitParenthesizedExpression(ParenthesizedExpression node) { | 1395 visitParenthesizedExpression(ParenthesizedExpression node) { |
| 1437 visit(node.expression); | 1396 visit(node.expression); |
| 1438 } | 1397 } |
| 1439 | 1398 |
| 1440 visitNewExpression(NewExpression node) { | 1399 visitNewExpression(NewExpression node) { |
| 1441 Node selector = node.send.selector; | 1400 Node selector = node.send.selector; |
| 1442 | 1401 |
| 1443 FunctionElement constructor = resolveConstructor(node); | 1402 FunctionElement constructor = resolveConstructor(node); |
| 1444 resolveSelector(node.send); | 1403 resolveSelector(node.send); |
| 1445 visitArguments(node.send.argumentsNode); | 1404 resolveArguments(node.send.argumentsNode); |
| 1446 if (constructor === null) return null; | 1405 if (constructor === null) return null; |
| 1447 // TODO(karlklose): handle optional arguments. | 1406 // TODO(karlklose): handle optional arguments. |
| 1448 if (node.send.argumentCount() != constructor.parameterCount(compiler)) { | 1407 if (node.send.argumentCount() != constructor.parameterCount(compiler)) { |
| 1449 // TODO(ngeoffray): resolution error with wrong number of | 1408 // TODO(ngeoffray): resolution error with wrong number of |
| 1450 // parameters. We cannot do this rigth now because of the | 1409 // parameters. We cannot do this rigth now because of the |
| 1451 // List constructor. | 1410 // List constructor. |
| 1452 } | 1411 } |
| 1453 useElement(node.send, constructor); | 1412 useElement(node.send, constructor); |
| 1413 world.registerStaticUse(constructor); | |
| 1454 compiler.withCurrentElement(constructor, () { | 1414 compiler.withCurrentElement(constructor, () { |
| 1455 FunctionExpression tree = constructor.parseNode(compiler); | 1415 FunctionExpression tree = constructor.parseNode(compiler); |
| 1456 compiler.resolver.resolveConstructorImplementation(constructor, tree); | 1416 compiler.resolver.resolveConstructorImplementation(constructor, tree); |
| 1457 }); | 1417 }); |
| 1458 world.registerStaticUse(constructor.defaultImplementation); | 1418 world.registerStaticUse(constructor.defaultImplementation); |
| 1459 ClassElement cls = constructor.defaultImplementation.getEnclosingClass(); | 1419 ClassElement cls = constructor.defaultImplementation.getEnclosingClass(); |
| 1460 world.registerInstantiatedClass(cls); | 1420 world.registerInstantiatedClass(cls); |
| 1461 cls.forEachInstanceField( | 1421 cls.forEachInstanceField( |
| 1462 includeBackendMembers: false, | 1422 includeBackendMembers: false, |
| 1463 includeSuperMembers: true, | 1423 includeSuperMembers: true, |
| (...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2459 TopScope(LibraryElement library) : super(null, library); | 2419 TopScope(LibraryElement library) : super(null, library); |
| 2460 Element lookup(SourceString name) { | 2420 Element lookup(SourceString name) { |
| 2461 return library.find(name); | 2421 return library.find(name); |
| 2462 } | 2422 } |
| 2463 | 2423 |
| 2464 Element add(Element newElement) { | 2424 Element add(Element newElement) { |
| 2465 throw "Cannot add an element in the top scope"; | 2425 throw "Cannot add an element in the top scope"; |
| 2466 } | 2426 } |
| 2467 String toString() => '$element'; | 2427 String toString() => '$element'; |
| 2468 } | 2428 } |
| OLD | NEW |