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
This commit is contained in:
scheglov@google.com
2012-11-13 21:12:48 +00:00
parent ebc3402925
commit dd172d631d
4 changed files with 69 additions and 28 deletions
@@ -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) {
@@ -714,6 +714,9 @@ public class Types {
if (type.getQuality().ordinal() > quality.ordinal()) {
return type;
}
if (quality == TypeQuality.EXACT) {
return type;
}
Set<Class<?>> interfaceSet = getAllImplementedInterfaces(type.getClass());
if (!interfaceSet.isEmpty()) {
Class<?>[] interfaces = (Class[]) interfaceSet.toArray(new Class[interfaceSet.size()]);
@@ -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());
}
}
@@ -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<String, int>", 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<A> 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<A>", EXACT);
}
assertInferredElementTypeString(testUnit, "v1", "List<A>", 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);
}
/**