mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:27:17 +00:00
Revert "Compute propagated type for final instance fields (partially addresses issue 23001)"
R=paulberry@google.com Review URL: https://codereview.chromium.org/1428803004 .
This commit is contained in:
parent
677d4b5bbc
commit
a7f2f5b4e1
|
@ -10905,27 +10905,6 @@ class ResolverVisitor extends ScopedVisitor {
|
|||
node.accept(typeAnalyzer);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitClassMembersInScope(ClassDeclaration node) {
|
||||
safelyVisit(node.documentationComment);
|
||||
node.metadata.accept(this);
|
||||
//
|
||||
// Visit the fields before other members so that instance fields will have
|
||||
// propagated types associated with them before we see their use sites.
|
||||
//
|
||||
List<ClassMember> nonFields = <ClassMember>[];
|
||||
for (ClassMember member in node.members) {
|
||||
if (member is FieldDeclaration) {
|
||||
member.accept(this);
|
||||
} else {
|
||||
nonFields.add(member);
|
||||
}
|
||||
}
|
||||
for (ClassMember member in nonFields) {
|
||||
member.accept(this);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Object visitComment(Comment node) {
|
||||
if (node.parent is FunctionDeclaration ||
|
||||
|
@ -11538,30 +11517,9 @@ class ResolverVisitor extends ScopedVisitor {
|
|||
Object visitVariableDeclaration(VariableDeclaration node) {
|
||||
super.visitVariableDeclaration(node);
|
||||
VariableElement element = node.element;
|
||||
FunctionElement initializerElement = element.initializer;
|
||||
Expression initializer = node.initializer;
|
||||
if (initializerElement is FunctionElementImpl && initializer != null) {
|
||||
initializerElement.returnType = initializer.staticType;
|
||||
}
|
||||
//
|
||||
// Propagate types for instance fields. Top-level variables and static
|
||||
// fields are handled elsewhere.
|
||||
//
|
||||
// TODO(brianwilkerson) Instance field propagation should probably be moved
|
||||
// into the class InstanceMemberInferrer because we're already doing
|
||||
// something there for strong mode.
|
||||
//
|
||||
if (initializer != null &&
|
||||
element is FieldElementImpl &&
|
||||
!element.isStatic &&
|
||||
element.isFinal) {
|
||||
DartType staticType = element.type;
|
||||
DartType bestType = initializer.bestType;
|
||||
if (bestType != null &&
|
||||
bestType != staticType &&
|
||||
bestType.isMoreSpecificThan(staticType)) {
|
||||
element.propagatedType = bestType;
|
||||
}
|
||||
if (element.initializer != null && node.initializer != null) {
|
||||
(element.initializer as FunctionElementImpl).returnType =
|
||||
node.initializer.staticType;
|
||||
}
|
||||
// Note: in addition to cloning the initializers for const variables, we
|
||||
// have to clone the initializers for non-static final fields (because if
|
||||
|
@ -11571,9 +11529,9 @@ class ResolverVisitor extends ScopedVisitor {
|
|||
(element is FieldElement &&
|
||||
element.isFinal &&
|
||||
!element.isStatic)) &&
|
||||
initializer != null) {
|
||||
node.initializer != null) {
|
||||
(element as ConstVariableElement).constantInitializer =
|
||||
new ConstantAstCloner().cloneNode(initializer);
|
||||
new ConstantAstCloner().cloneNode(node.initializer);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -12731,6 +12731,70 @@ class TypeOverrideManagerTest extends EngineTestCase {
|
|||
|
||||
@reflectiveTest
|
||||
class TypePropagationTest extends ResolverTestCase {
|
||||
void fail_finalPropertyInducingVariable_classMember_instance() {
|
||||
addNamedSource(
|
||||
"/lib.dart",
|
||||
r'''
|
||||
class A {
|
||||
final v = 0;
|
||||
}''');
|
||||
String code = r'''
|
||||
import 'lib.dart';
|
||||
f(A a) {
|
||||
return a.v; // marker
|
||||
}''';
|
||||
_assertTypeOfMarkedExpression(
|
||||
code, typeProvider.dynamicType, typeProvider.intType);
|
||||
}
|
||||
|
||||
void fail_finalPropertyInducingVariable_classMember_instance_inherited() {
|
||||
addNamedSource(
|
||||
"/lib.dart",
|
||||
r'''
|
||||
class A {
|
||||
final v = 0;
|
||||
}''');
|
||||
String code = r'''
|
||||
import 'lib.dart';
|
||||
class B extends A {
|
||||
m() {
|
||||
return v; // marker
|
||||
}
|
||||
}''';
|
||||
_assertTypeOfMarkedExpression(
|
||||
code, typeProvider.dynamicType, typeProvider.intType);
|
||||
}
|
||||
|
||||
void fail_finalPropertyInducingVariable_classMember_instance_propagatedTarget() {
|
||||
addNamedSource(
|
||||
"/lib.dart",
|
||||
r'''
|
||||
class A {
|
||||
final v = 0;
|
||||
}''');
|
||||
String code = r'''
|
||||
import 'lib.dart';
|
||||
f(p) {
|
||||
if (p is A) {
|
||||
return p.v; // marker
|
||||
}
|
||||
}''';
|
||||
_assertTypeOfMarkedExpression(
|
||||
code, typeProvider.dynamicType, typeProvider.intType);
|
||||
}
|
||||
|
||||
void fail_finalPropertyInducingVariable_classMember_instance_unprefixed() {
|
||||
String code = r'''
|
||||
class A {
|
||||
final v = 0;
|
||||
m() {
|
||||
v; // marker
|
||||
}
|
||||
}''';
|
||||
_assertTypeOfMarkedExpression(
|
||||
code, typeProvider.dynamicType, typeProvider.intType);
|
||||
}
|
||||
|
||||
void fail_finalPropertyInducingVariable_classMember_static() {
|
||||
addNamedSource(
|
||||
"/lib.dart",
|
||||
|
@ -13053,70 +13117,6 @@ main(CanvasElement canvas) {
|
|||
expect(identifier.propagatedType.name, "CanvasRenderingContext2D");
|
||||
}
|
||||
|
||||
void test_finalPropertyInducingVariable_classMember_instance() {
|
||||
addNamedSource(
|
||||
"/lib.dart",
|
||||
r'''
|
||||
class A {
|
||||
final v = 0;
|
||||
}''');
|
||||
String code = r'''
|
||||
import 'lib.dart';
|
||||
f(A a) {
|
||||
return a.v; // marker
|
||||
}''';
|
||||
_assertTypeOfMarkedExpression(
|
||||
code, typeProvider.dynamicType, typeProvider.intType);
|
||||
}
|
||||
|
||||
void test_finalPropertyInducingVariable_classMember_instance_inherited() {
|
||||
addNamedSource(
|
||||
"/lib.dart",
|
||||
r'''
|
||||
class A {
|
||||
final v = 0;
|
||||
}''');
|
||||
String code = r'''
|
||||
import 'lib.dart';
|
||||
class B extends A {
|
||||
m() {
|
||||
return v; // marker
|
||||
}
|
||||
}''';
|
||||
_assertTypeOfMarkedExpression(
|
||||
code, typeProvider.dynamicType, typeProvider.intType);
|
||||
}
|
||||
|
||||
void test_finalPropertyInducingVariable_classMember_instance_propagatedTarget() {
|
||||
addNamedSource(
|
||||
"/lib.dart",
|
||||
r'''
|
||||
class A {
|
||||
final v = 0;
|
||||
}''');
|
||||
String code = r'''
|
||||
import 'lib.dart';
|
||||
f(p) {
|
||||
if (p is A) {
|
||||
return p.v; // marker
|
||||
}
|
||||
}''';
|
||||
_assertTypeOfMarkedExpression(
|
||||
code, typeProvider.dynamicType, typeProvider.intType);
|
||||
}
|
||||
|
||||
void test_finalPropertyInducingVariable_classMember_instance_unprefixed() {
|
||||
String code = r'''
|
||||
class A {
|
||||
final v = 0;
|
||||
m() {
|
||||
v; // marker
|
||||
}
|
||||
}''';
|
||||
_assertTypeOfMarkedExpression(
|
||||
code, typeProvider.dynamicType, typeProvider.intType);
|
||||
}
|
||||
|
||||
void test_forEach() {
|
||||
String code = r'''
|
||||
main() {
|
||||
|
|
Loading…
Reference in a new issue