From dd172d631dd60ba714be22b3dc323c986c4056ae Mon Sep 17 00:00:00 2001 From: "scheglov@google.com" Date: Tue, 13 Nov 2012 21:12:48 +0000 Subject: [PATCH] Type quality of ArrayAccess is same as quality of target type. Also tweak using "inferred exact" only for places where we sure about type. R=brianwilkerson@google.com BUG= Review URL: https://codereview.chromium.org//11364211 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@14867 260f80e4-7a28-3924-810f-c04153c831b5 --- .../dart/compiler/type/TypeAnalyzer.java | 25 +++++++--- .../com/google/dart/compiler/type/Types.java | 3 ++ .../dart/compiler/CompilerTestCase.java | 21 ++++++-- .../type/TypeAnalyzerCompilerTest.java | 48 ++++++++++++------- 4 files changed, 69 insertions(+), 28 deletions(-) diff --git a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java index aea700e14a6..49694ff9d16 100644 --- a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java +++ b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java @@ -1398,7 +1398,8 @@ public class TypeAnalyzer implements DartCompilationPhase { } } // print( t[k] ) - return analyzeBinaryOperator(node, target, Token.INDEX, node, argKey); + Type result = analyzeBinaryOperator(node, target, Token.INDEX, node, argKey); + return Types.makeInferred(result, target.getQuality()); } /** @@ -3571,11 +3572,18 @@ public class TypeAnalyzer implements DartCompilationPhase { */ public static TypeQuality getTypeQuality(DartExpression expr) { if (expr != null) { - if (expr instanceof DartMethodInvocation) { - return TypeQuality.INFERRED; + if (expr instanceof DartIdentifier) { + Type varType = expr.getType(); + if (varType != null) { + TypeQuality varTypeQuality = varType.getQuality(); + if (varTypeQuality == TypeQuality.EXACT) { + varTypeQuality = TypeQuality.INFERRED_EXACT; + } + return varTypeQuality; + } } - if (expr instanceof DartUnqualifiedInvocation) { - return TypeQuality.INFERRED; + if (expr instanceof DartLiteral) { + return TypeQuality.INFERRED_EXACT; } if (expr instanceof DartUnaryExpression) { DartUnaryExpression unary = (DartUnaryExpression) expr; @@ -3592,10 +3600,15 @@ public class TypeAnalyzer implements DartCompilationPhase { return TypeQuality.INFERRED; } if (expr instanceof DartNewExpression) { + DartNewExpression newExpression = (DartNewExpression) expr; + ConstructorElement constructorElement = newExpression.getElement(); + if (constructorElement != null && !constructorElement.getModifiers().isFactory()) { + return TypeQuality.INFERRED_EXACT; + } return TypeQuality.INFERRED; } } - return TypeQuality.INFERRED_EXACT; + return TypeQuality.INFERRED; } private static boolean hasTypeBoolIntDouble(DartExpression expr) { diff --git a/compiler/java/com/google/dart/compiler/type/Types.java b/compiler/java/com/google/dart/compiler/type/Types.java index d825e85c2f0..8ec7a882e44 100644 --- a/compiler/java/com/google/dart/compiler/type/Types.java +++ b/compiler/java/com/google/dart/compiler/type/Types.java @@ -714,6 +714,9 @@ public class Types { if (type.getQuality().ordinal() > quality.ordinal()) { return type; } + if (quality == TypeQuality.EXACT) { + return type; + } Set> interfaceSet = getAllImplementedInterfaces(type.getClass()); if (!interfaceSet.isEmpty()) { Class[] interfaces = (Class[]) interfaceSet.toArray(new Class[interfaceSet.size()]); diff --git a/compiler/javatests/com/google/dart/compiler/CompilerTestCase.java b/compiler/javatests/com/google/dart/compiler/CompilerTestCase.java index a3cbffabc98..92247b15651 100644 --- a/compiler/javatests/com/google/dart/compiler/CompilerTestCase.java +++ b/compiler/javatests/com/google/dart/compiler/CompilerTestCase.java @@ -459,16 +459,27 @@ public abstract class CompilerTestCase extends TestCase { /** * Asserts that {@link Element} with given name has expected type. */ - protected static void assertInferredElementTypeString(DartUnit unit, String variableName, - String expectedType, TypeQuality exact) { + protected static void assertInferredElementTypeString( + DartUnit unit, + String variableName, + String expectedType, + TypeQuality quality) { // find element Element element = getNamedElement(unit, variableName); assertNotNull(element); // check type Type actualType = element.getType(); - assertEquals(element.getName(), expectedType, getTypeSource(actualType)); - if (exact != null) { - assertSame(exact, actualType.getQuality()); + assertInferredElementTypeString(actualType, element.getName(), expectedType, quality); + } + + protected static void assertInferredElementTypeString( + Type actualType, + String testName, + String expectedType, + TypeQuality quality) { + assertEquals(testName, expectedType, getTypeSource(actualType)); + if (quality != null) { + assertSame(quality, actualType.getQuality()); } } diff --git a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java index 1b95fa08f37..f1a8dcbaa70 100644 --- a/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java +++ b/compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java @@ -1889,17 +1889,13 @@ public class TypeAnalyzerCompilerTest extends CompilerTestCase { ""); assertErrors(result.getErrors()); } - + public void test_inferredTypes_noMemberWarnings() throws Exception { // disabled by default { AnalyzeLibraryResult result = analyzeLibrary( "// filler filler filler filler filler filler filler filler filler filler", "class A {}", - "class B extends A {", - " var f;", - " m() {}", - "}", "foo(A a) {", " var v = a;", " v.f = 0;", @@ -1919,10 +1915,6 @@ public class TypeAnalyzerCompilerTest extends CompilerTestCase { AnalyzeLibraryResult result = analyzeLibrary( "// filler filler filler filler filler filler filler filler filler filler", "class A {}", - "class B extends A {", - " var f;", - " m() {}", - "}", "foo(A a) {", " var v = a;", " v.f = 0;", @@ -1931,8 +1923,8 @@ public class TypeAnalyzerCompilerTest extends CompilerTestCase { ""); assertErrors( result.getErrors(), - errEx(TypeErrorCode.NOT_A_MEMBER_OF_INFERRED, 9, 5, 1), - errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED_INFERRED, 10, 5, 1)); + errEx(TypeErrorCode.NOT_A_MEMBER_OF_INFERRED, 5, 5, 1), + errEx(TypeErrorCode.INTERFACE_HAS_NO_METHOD_NAMED_INFERRED, 6, 5, 1)); } } @@ -2042,7 +2034,29 @@ public class TypeAnalyzerCompilerTest extends CompilerTestCase { assertInferredElementTypeString(testUnit, "v4", "double", INFERRED_EXACT); assertInferredElementTypeString(testUnit, "v5", "double", INFERRED_EXACT); assertInferredElementTypeString(testUnit, "v6", "Map", INFERRED); - assertInferredElementTypeString(testUnit, "v7", "int", INFERRED_EXACT); + assertInferredElementTypeString(testUnit, "v7", "int", INFERRED); + } + + public void test_typesPropagation_arrayAccess() throws Exception { + analyzeLibrary( + "class A {}", + "class B extends A {}", + "List list() => [new B()];", + "main() {", + " var v0 = list();", + " var v1 = list();", + " var v2 = v1[0];", + "}", + ""); + { + DartExpression expr = findNode(DartUnqualifiedInvocation.class, "list();"); + assertInferredElementTypeString(expr.getType(), "v0", "List", EXACT); + } + assertInferredElementTypeString(testUnit, "v1", "List", INFERRED); + { + DartExpression expr = findNode(DartArrayAccess.class, "v1[0]"); + assertInferredElementTypeString(expr.getType(), "v2", "A", INFERRED); + } } /** @@ -3201,8 +3215,8 @@ public class TypeAnalyzerCompilerTest extends CompilerTestCase { "}", ""); assertErrors(libraryResult.getErrors()); - assertInferredElementTypeString(testUnit, "v1", "int", INFERRED_EXACT); - assertInferredElementTypeString(testUnit, "v2", "bool", INFERRED_EXACT); + assertInferredElementTypeString(testUnit, "v1", "int", INFERRED); + assertInferredElementTypeString(testUnit, "v2", "bool", INFERRED); } public void test_getType_getterInNegation_generic() throws Exception { @@ -3226,8 +3240,8 @@ public class TypeAnalyzerCompilerTest extends CompilerTestCase { "}", ""); assertErrors(libraryResult.getErrors()); - assertInferredElementTypeString(testUnit, "v1", "bool", INFERRED_EXACT); - assertInferredElementTypeString(testUnit, "v2", "bool", INFERRED_EXACT); + assertInferredElementTypeString(testUnit, "v1", "bool", INFERRED); + assertInferredElementTypeString(testUnit, "v2", "bool", INFERRED); } public void test_getType_getterInSwitch_default() throws Exception { @@ -4351,7 +4365,7 @@ public class TypeAnalyzerCompilerTest extends CompilerTestCase { " var v = s..length;", "}", ""); - assertInferredElementTypeString(testUnit, "v", "String", INFERRED_EXACT); + assertInferredElementTypeString(testUnit, "v", "String", INFERRED); } /**