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

Side by Side Diff: pkg/compiler/lib/src/resolution/resolution.dart

Issue 2230853002: Ensure correct current element for field initializers. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 4 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
« no previous file with comments | « no previous file | tests/language/final_initializer_instance_reference_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 }
OLDNEW
« no previous file with comments | « no previous file | tests/language/final_initializer_instance_reference_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698