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

Side by Side Diff: pkg/compiler/lib/src/inferrer/inferrer_visitor.dart

Issue 2569733002: Even less reliance on Compiler.closedWorld (Closed)
Patch Set: Updated cf. comments. Created 4 years 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) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 inferrer_visitor; 5 library inferrer_visitor;
6 6
7 import 'dart:collection' show IterableMixin; 7 import 'dart:collection' show IterableMixin;
8 8
9 import '../common.dart'; 9 import '../common.dart';
10 import '../options.dart' show CompilerOptions;
10 import '../compiler.dart' show Compiler; 11 import '../compiler.dart' show Compiler;
11 import '../constants/constant_system.dart'; 12 import '../constants/constant_system.dart';
12 import '../constants/expressions.dart'; 13 import '../constants/expressions.dart';
13 import '../dart_types.dart'; 14 import '../dart_types.dart';
14 import '../elements/elements.dart'; 15 import '../elements/elements.dart';
15 import '../resolution/operators.dart'; 16 import '../resolution/operators.dart';
16 import '../resolution/semantic_visitor.dart'; 17 import '../resolution/semantic_visitor.dart';
17 import '../resolution/tree_elements.dart' show TreeElements; 18 import '../resolution/tree_elements.dart' show TreeElements;
18 import '../tree/tree.dart'; 19 import '../tree/tree.dart';
19 import '../types/constants.dart' show computeTypeMask; 20 import '../types/constants.dart' show computeTypeMask;
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 365
365 /** 366 /**
366 * Records that the captured variable [local] is read. 367 * Records that the captured variable [local] is read.
367 */ 368 */
368 void recordCapturedLocalRead(Local local); 369 void recordCapturedLocalRead(Local local);
369 370
370 /** 371 /**
371 * Records that the variable [local] is being updated. 372 * Records that the variable [local] is being updated.
372 */ 373 */
373 void recordLocalUpdate(Local local, T type); 374 void recordLocalUpdate(Local local, T type);
375
376 /// The [ClosedWorld] on which inference reasoning is based.
377 ClosedWorld get closedWorld;
374 } 378 }
375 379
376 /** 380 /**
377 * Placeholder for inferred types of local variables. 381 * Placeholder for inferred types of local variables.
378 */ 382 */
379 class LocalsHandler<T> { 383 class LocalsHandler<T> {
380 final Compiler compiler; 384 final CompilerOptions options;
381 final TypeSystem<T> types; 385 final TypeSystem<T> types;
382 final MinimalInferrerEngine<T> inferrer; 386 final MinimalInferrerEngine<T> inferrer;
383 final VariableScope<T> locals; 387 final VariableScope<T> locals;
384 final Map<Local, Element> captured; 388 final Map<Local, Element> captured;
385 final Map<Local, Element> capturedAndBoxed; 389 final Map<Local, Element> capturedAndBoxed;
386 final FieldInitializationScope<T> fieldScope; 390 final FieldInitializationScope<T> fieldScope;
387 LocalsHandler<T> tryBlock; 391 LocalsHandler<T> tryBlock;
388 bool seenReturnOrThrow = false; 392 bool seenReturnOrThrow = false;
389 bool seenBreakOrContinue = false; 393 bool seenBreakOrContinue = false;
390 394
391 bool get aborts { 395 bool get aborts {
392 return seenReturnOrThrow || seenBreakOrContinue; 396 return seenReturnOrThrow || seenBreakOrContinue;
393 } 397 }
394 398
395 bool get inTryBlock => tryBlock != null; 399 bool get inTryBlock => tryBlock != null;
396 400
397 LocalsHandler(this.inferrer, this.types, this.compiler, Node block, 401 LocalsHandler(this.inferrer, this.types, this.options, Node block,
398 [this.fieldScope]) 402 [this.fieldScope])
399 : locals = new VariableScope<T>(block), 403 : locals = new VariableScope<T>(block),
400 captured = new Map<Local, Element>(), 404 captured = new Map<Local, Element>(),
401 capturedAndBoxed = new Map<Local, Element>(), 405 capturedAndBoxed = new Map<Local, Element>(),
402 tryBlock = null; 406 tryBlock = null;
403 407
404 LocalsHandler.from(LocalsHandler<T> other, Node block, 408 LocalsHandler.from(LocalsHandler<T> other, Node block,
405 {bool useOtherTryBlock: true}) 409 {bool useOtherTryBlock: true})
406 : locals = new VariableScope<T>(block, other.locals), 410 : locals = new VariableScope<T>(block, other.locals),
407 fieldScope = new FieldInitializationScope<T>.from(other.fieldScope), 411 fieldScope = new FieldInitializationScope<T>.from(other.fieldScope),
408 captured = other.captured, 412 captured = other.captured,
409 capturedAndBoxed = other.capturedAndBoxed, 413 capturedAndBoxed = other.capturedAndBoxed,
410 types = other.types, 414 types = other.types,
411 inferrer = other.inferrer, 415 inferrer = other.inferrer,
412 compiler = other.compiler { 416 options = other.options {
413 tryBlock = useOtherTryBlock ? other.tryBlock : this; 417 tryBlock = useOtherTryBlock ? other.tryBlock : this;
414 } 418 }
415 419
416 LocalsHandler.deepCopyOf(LocalsHandler<T> other) 420 LocalsHandler.deepCopyOf(LocalsHandler<T> other)
417 : locals = new VariableScope<T>.deepCopyOf(other.locals), 421 : locals = new VariableScope<T>.deepCopyOf(other.locals),
418 fieldScope = new FieldInitializationScope<T>.from(other.fieldScope), 422 fieldScope = new FieldInitializationScope<T>.from(other.fieldScope),
419 captured = other.captured, 423 captured = other.captured,
420 capturedAndBoxed = other.capturedAndBoxed, 424 capturedAndBoxed = other.capturedAndBoxed,
421 tryBlock = other.tryBlock, 425 tryBlock = other.tryBlock,
422 types = other.types, 426 types = other.types,
423 inferrer = other.inferrer, 427 inferrer = other.inferrer,
424 compiler = other.compiler; 428 options = other.options;
425 429
426 LocalsHandler.topLevelCopyOf(LocalsHandler<T> other) 430 LocalsHandler.topLevelCopyOf(LocalsHandler<T> other)
427 : locals = new VariableScope<T>.topLevelCopyOf(other.locals), 431 : locals = new VariableScope<T>.topLevelCopyOf(other.locals),
428 fieldScope = new FieldInitializationScope<T>.from(other.fieldScope), 432 fieldScope = new FieldInitializationScope<T>.from(other.fieldScope),
429 captured = other.captured, 433 captured = other.captured,
430 capturedAndBoxed = other.capturedAndBoxed, 434 capturedAndBoxed = other.capturedAndBoxed,
431 tryBlock = other.tryBlock, 435 tryBlock = other.tryBlock,
432 types = other.types, 436 types = other.types,
433 inferrer = other.inferrer, 437 inferrer = other.inferrer,
434 compiler = other.compiler; 438 options = other.options;
435 439
436 T use(Local local) { 440 T use(Local local) {
437 if (capturedAndBoxed.containsKey(local)) { 441 if (capturedAndBoxed.containsKey(local)) {
438 return inferrer.typeOfElement(capturedAndBoxed[local]); 442 return inferrer.typeOfElement(capturedAndBoxed[local]);
439 } else { 443 } else {
440 if (captured.containsKey(local)) { 444 if (captured.containsKey(local)) {
441 inferrer.recordCapturedLocalRead(local); 445 inferrer.recordCapturedLocalRead(local);
442 } 446 }
443 return locals[local]; 447 return locals[local];
444 } 448 }
445 } 449 }
446 450
447 void update(LocalElement local, T type, Node node) { 451 void update(LocalElement local, T type, Node node) {
448 assert(type != null); 452 assert(type != null);
449 if (compiler.options.trustTypeAnnotations || 453 if (options.trustTypeAnnotations || options.enableTypeAssertions) {
450 compiler.options.enableTypeAssertions) {
451 type = types.narrowType(type, local.type); 454 type = types.narrowType(type, local.type);
452 } 455 }
453 updateLocal() { 456 updateLocal() {
454 T currentType = locals[local]; 457 T currentType = locals[local];
455 458
456 SendSet send = node != null ? node.asSendSet() : null; 459 SendSet send = node != null ? node.asSendSet() : null;
457 if (send != null && send.isIfNullAssignment && currentType != null) { 460 if (send != null && send.isIfNullAssignment && currentType != null) {
458 // If-null assignments may return either the new or the original value 461 // If-null assignments may return either the new or the original value
459 // narrowed to non-null. 462 // narrowed to non-null.
460 type = types.addPhiInput( 463 type = types.addPhiInput(
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 this.locals = handler { 742 this.locals = handler {
740 if (handler != null) return; 743 if (handler != null) return;
741 Node node; 744 Node node;
742 if (resolvedAst.kind == ResolvedAstKind.PARSED) { 745 if (resolvedAst.kind == ResolvedAstKind.PARSED) {
743 node = resolvedAst.node; 746 node = resolvedAst.node;
744 } 747 }
745 FieldInitializationScope<T> fieldScope = 748 FieldInitializationScope<T> fieldScope =
746 analyzedElement.isGenerativeConstructor 749 analyzedElement.isGenerativeConstructor
747 ? new FieldInitializationScope<T>(types) 750 ? new FieldInitializationScope<T>(types)
748 : null; 751 : null;
749 locals = new LocalsHandler<T>(inferrer, types, compiler, node, fieldScope); 752 locals = new LocalsHandler<T>(
753 inferrer, types, compiler.options, node, fieldScope);
750 } 754 }
751 755
752 DiagnosticReporter get reporter => compiler.reporter; 756 DiagnosticReporter get reporter => compiler.reporter;
753 757
754 ClosedWorld get closedWorld => compiler.closedWorld; 758 ClosedWorld get closedWorld => inferrer.closedWorld;
755 759
756 @override 760 @override
757 SemanticSendVisitor get sendVisitor => this; 761 SemanticSendVisitor get sendVisitor => this;
758 762
759 @override 763 @override
760 T apply(Node node, _) => visit(node); 764 T apply(Node node, _) => visit(node);
761 765
762 T handleSendSet(SendSet node); 766 T handleSendSet(SendSet node);
763 767
764 T handleDynamicInvoke(Send node); 768 T handleDynamicInvoke(Send node);
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
880 } 884 }
881 885
882 T visitLiteralNull(LiteralNull node) { 886 T visitLiteralNull(LiteralNull node) {
883 return types.nullType; 887 return types.nullType;
884 } 888 }
885 889
886 T visitLiteralSymbol(LiteralSymbol node) { 890 T visitLiteralSymbol(LiteralSymbol node) {
887 // TODO(kasperl): We should be able to tell that the type of a literal 891 // TODO(kasperl): We should be able to tell that the type of a literal
888 // symbol is always a non-null exact symbol implementation -- not just 892 // symbol is always a non-null exact symbol implementation -- not just
889 // any non-null subtype of the symbol interface. 893 // any non-null subtype of the symbol interface.
890 return types.nonNullSubtype(compiler.coreClasses.symbolClass); 894 return types.nonNullSubtype(closedWorld.coreClasses.symbolClass);
891 } 895 }
892 896
893 @override 897 @override
894 void previsitDeferredAccess(Send node, PrefixElement prefix, _) { 898 void previsitDeferredAccess(Send node, PrefixElement prefix, _) {
895 // Deferred access does not affect inference. 899 // Deferred access does not affect inference.
896 } 900 }
897 901
898 T handleTypeLiteralGet() { 902 T handleTypeLiteralGet() {
899 return types.typeType; 903 return types.typeType;
900 } 904 }
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1031 (operator == '!=' && !usePositive)) { 1035 (operator == '!=' && !usePositive)) {
1032 // Type the elements as null. 1036 // Type the elements as null.
1033 if (Elements.isLocal(receiverElement)) { 1037 if (Elements.isLocal(receiverElement)) {
1034 locals.update(receiverElement, types.nullType, node); 1038 locals.update(receiverElement, types.nullType, node);
1035 } 1039 }
1036 if (Elements.isLocal(argumentElement)) { 1040 if (Elements.isLocal(argumentElement)) {
1037 locals.update(argumentElement, types.nullType, node); 1041 locals.update(argumentElement, types.nullType, node);
1038 } 1042 }
1039 } else { 1043 } else {
1040 // Narrow the elements to a non-null type. 1044 // Narrow the elements to a non-null type.
1041 DartType objectType = compiler.coreTypes.objectType; 1045 DartType objectType = closedWorld.coreTypes.objectType;
1042 if (Elements.isLocal(receiverElement)) { 1046 if (Elements.isLocal(receiverElement)) {
1043 narrow(receiverElement, objectType, node); 1047 narrow(receiverElement, objectType, node);
1044 } 1048 }
1045 if (Elements.isLocal(argumentElement)) { 1049 if (Elements.isLocal(argumentElement)) {
1046 narrow(argumentElement, objectType, node); 1050 narrow(argumentElement, objectType, node);
1047 } 1051 }
1048 } 1052 }
1049 } 1053 }
1050 } 1054 }
1051 } 1055 }
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after
1491 return type; 1495 return type;
1492 } 1496 }
1493 1497
1494 T visitCascade(Cascade node) { 1498 T visitCascade(Cascade node) {
1495 // Ignore the result of the cascade send and return the type of the cascade 1499 // Ignore the result of the cascade send and return the type of the cascade
1496 // receiver. 1500 // receiver.
1497 visit(node.expression); 1501 visit(node.expression);
1498 return cascadeReceiverStack.removeLast(); 1502 return cascadeReceiverStack.removeLast();
1499 } 1503 }
1500 } 1504 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/elements/elements.dart ('k') | pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698