| 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 library dart2js.resolution; | 5 library dart2js.resolution; |
| 6 | 6 |
| 7 import 'dart:collection' show Queue; | 7 import 'dart:collection' show Queue; |
| 8 | 8 |
| 9 import '../common.dart'; | 9 import '../common.dart'; |
| 10 import '../common/names.dart' show Identifiers; | 10 import '../common/names.dart' show Identifiers; |
| (...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 /// | 343 /// |
| 344 /// This method should only be used by this library (or tests of | 344 /// This method should only be used by this library (or tests of |
| 345 /// this library). | 345 /// this library). |
| 346 ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) { | 346 ResolverVisitor visitorFor(Element element, {bool useEnclosingScope: false}) { |
| 347 return new ResolverVisitor(resolution, element, | 347 return new ResolverVisitor(resolution, element, |
| 348 new ResolutionRegistry(target, _ensureTreeElements(element)), | 348 new ResolutionRegistry(target, _ensureTreeElements(element)), |
| 349 useEnclosingScope: useEnclosingScope); | 349 useEnclosingScope: useEnclosingScope); |
| 350 } | 350 } |
| 351 | 351 |
| 352 WorldImpact resolveField(FieldElementX element) { | 352 WorldImpact resolveField(FieldElementX element) { |
| 353 VariableDefinitions tree = element.parseNode(parsingContext); | 353 return reporter.withCurrentElement(element, () { |
| 354 if (element.modifiers.isStatic && element.isTopLevel) { | 354 VariableDefinitions tree = element.parseNode(parsingContext); |
| 355 reporter.reportErrorMessage(element.modifiers.getStatic(), | 355 if (element.modifiers.isStatic && element.isTopLevel) { |
| 356 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); | 356 reporter.reportErrorMessage(element.modifiers.getStatic(), |
| 357 } | 357 MessageKind.TOP_LEVEL_VARIABLE_DECLARED_STATIC); |
| 358 ResolverVisitor visitor = visitorFor(element); | 358 } |
| 359 ResolutionRegistry registry = visitor.registry; | 359 ResolverVisitor visitor = visitorFor(element); |
| 360 // TODO(johnniwinther): Maybe remove this when placeholderCollector migrates | 360 ResolutionRegistry registry = visitor.registry; |
| 361 // to the backend ast. | 361 // TODO(johnniwinther): Maybe remove this when placeholderCollector migrat
es |
| 362 registry.defineElement(tree.definitions.nodes.head, element); | 362 // to the backend ast. |
| 363 // TODO(johnniwinther): Share the resolved type between all variables | 363 registry.defineElement(tree.definitions.nodes.head, element); |
| 364 // declared in the same declaration. | 364 // TODO(johnniwinther): Share the resolved type between all variables |
| 365 if (tree.type != null) { | 365 // declared in the same declaration. |
| 366 DartType type = visitor.resolveTypeAnnotation(tree.type); | 366 if (tree.type != null) { |
| 367 assert(invariant( | 367 DartType type = visitor.resolveTypeAnnotation(tree.type); |
| 368 element, | 368 assert(invariant( |
| 369 element.variables.type == null || | 369 element, |
| 370 // Crude check but we have no equivalence relation that | 370 element.variables.type == null || |
| 371 // equates malformed types, like matching creations of type | 371 // Crude check but we have no equivalence relation that |
| 372 // `Foo<Unresolved>`. | 372 // equates malformed types, like matching creations of type |
| 373 element.variables.type.toString() == type.toString(), | 373 // `Foo<Unresolved>`. |
| 374 message: "Unexpected type computed for $element. " | 374 element.variables.type.toString() == type.toString(), |
| 375 "Was ${element.variables.type}, computed $type.")); | 375 message: "Unexpected type computed for $element. " |
| 376 element.variables.type = type; | 376 "Was ${element.variables.type}, computed $type.")); |
| 377 } else if (element.variables.type == null) { | 377 element.variables.type = type; |
| 378 // Only assign the dynamic type if the element has no known type. This | 378 } else if (element.variables.type == null) { |
| 379 // happens for enum fields where the type is known but is not in the | 379 // Only assign the dynamic type if the element has no known type. This |
| 380 // synthesized AST. | 380 // happens for enum fields where the type is known but is not in the |
| 381 element.variables.type = const DynamicType(); | 381 // synthesized AST. |
| 382 } | 382 element.variables.type = const DynamicType(); |
| 383 } |
| 383 | 384 |
| 384 Expression initializer = element.initializer; | 385 Expression initializer = element.initializer; |
| 385 Modifiers modifiers = element.modifiers; | 386 Modifiers modifiers = element.modifiers; |
| 386 if (initializer != null) { | 387 if (initializer != null) { |
| 387 // TODO(johnniwinther): Avoid analyzing initializers if | 388 // TODO(johnniwinther): Avoid analyzing initializers if |
| 388 // [Compiler.analyzeSignaturesOnly] is set. | 389 // [Compiler.analyzeSignaturesOnly] is set. |
| 389 ResolutionResult result = visitor.visit(initializer); | 390 ResolutionResult result = visitor.visit(initializer); |
| 390 if (result.isConstant) { | 391 if (result.isConstant) { |
| 391 element.constant = result.constant; | 392 element.constant = result.constant; |
| 393 } |
| 394 } else if (modifiers.isConst) { |
| 395 reporter.reportErrorMessage( |
| 396 element, MessageKind.CONST_WITHOUT_INITIALIZER); |
| 397 } else if (modifiers.isFinal && !element.isInstanceMember) { |
| 398 reporter.reportErrorMessage( |
| 399 element, MessageKind.FINAL_WITHOUT_INITIALIZER); |
| 400 } else { |
| 401 // TODO(johnniwinther): Register a feature instead. |
| 402 registry.registerTypeUse(new TypeUse.instantiation(coreTypes.nullType)); |
| 392 } | 403 } |
| 393 } else if (modifiers.isConst) { | |
| 394 reporter.reportErrorMessage( | |
| 395 element, MessageKind.CONST_WITHOUT_INITIALIZER); | |
| 396 } else if (modifiers.isFinal && !element.isInstanceMember) { | |
| 397 reporter.reportErrorMessage( | |
| 398 element, MessageKind.FINAL_WITHOUT_INITIALIZER); | |
| 399 } else { | |
| 400 // TODO(johnniwinther): Register a feature instead. | |
| 401 registry.registerTypeUse(new TypeUse.instantiation(coreTypes.nullType)); | |
| 402 } | |
| 403 | 404 |
| 404 if (Elements.isStaticOrTopLevelField(element)) { | 405 if (Elements.isStaticOrTopLevelField(element)) { |
| 405 visitor.addDeferredAction(element, () { | 406 visitor.addDeferredAction(element, () { |
| 406 if (element.modifiers.isConst) { | 407 if (element.modifiers.isConst) { |
| 407 element.constant = constantCompiler.compileConstant(element); | 408 element.constant = constantCompiler.compileConstant(element); |
| 408 } else { | 409 } else { |
| 409 element.constant = constantCompiler.compileVariable(element); | 410 element.constant = constantCompiler.compileVariable(element); |
| 410 } | 411 } |
| 411 }); | 412 }); |
| 412 if (initializer != null) { | 413 if (initializer != null) { |
| 413 if (!element.modifiers.isConst) { | 414 if (!element.modifiers.isConst) { |
| 414 // TODO(johnniwinther): Determine the const-ness eagerly to avoid | 415 // TODO(johnniwinther): Determine the const-ness eagerly to avoid |
| 415 // unnecessary registrations. | 416 // unnecessary registrations. |
| 416 registry.registerFeature(Feature.LAZY_FIELD); | 417 registry.registerFeature(Feature.LAZY_FIELD); |
| 418 } |
| 417 } | 419 } |
| 418 } | 420 } |
| 419 } | |
| 420 | 421 |
| 421 // Perform various checks as side effect of "computing" the type. | 422 // Perform various checks as side effect of "computing" the type. |
| 422 element.computeType(resolution); | 423 element.computeType(resolution); |
| 423 | 424 |
| 424 resolution.target.resolveNativeElement(element, registry.worldImpact); | 425 resolution.target.resolveNativeElement(element, registry.worldImpact); |
| 425 | 426 |
| 426 return registry.worldImpact; | 427 return registry.worldImpact; |
| 428 }); |
| 427 } | 429 } |
| 428 | 430 |
| 429 DartType resolveTypeAnnotation(Element element, TypeAnnotation annotation) { | 431 DartType resolveTypeAnnotation(Element element, TypeAnnotation annotation) { |
| 430 DartType type = resolveReturnType(element, annotation); | 432 DartType type = resolveReturnType(element, annotation); |
| 431 if (type.isVoid) { | 433 if (type.isVoid) { |
| 432 reporter.reportErrorMessage(annotation, MessageKind.VOID_NOT_ALLOWED); | 434 reporter.reportErrorMessage(annotation, MessageKind.VOID_NOT_ALLOWED); |
| 433 } | 435 } |
| 434 return type; | 436 return type; |
| 435 } | 437 } |
| 436 | 438 |
| (...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1119 TreeElements get treeElements { | 1121 TreeElements get treeElements { |
| 1120 assert(invariant(this, _treeElements != null, | 1122 assert(invariant(this, _treeElements != null, |
| 1121 message: "TreeElements have not been computed for $this.")); | 1123 message: "TreeElements have not been computed for $this.")); |
| 1122 return _treeElements; | 1124 return _treeElements; |
| 1123 } | 1125 } |
| 1124 | 1126 |
| 1125 void reuseElement() { | 1127 void reuseElement() { |
| 1126 _treeElements = null; | 1128 _treeElements = null; |
| 1127 } | 1129 } |
| 1128 } | 1130 } |
| OLD | NEW |