Index: editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/internal/constant/ConstantVisitorTest.java |
diff --git a/editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/internal/constant/ConstantVisitorTest.java b/editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/internal/constant/ConstantVisitorTest.java |
index af286f60f3b8e146893d60f4fb9b1d83296d82a3..14e511e6f0b5efd973cadbfc19d8e8c4138eda6a 100644 |
--- a/editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/internal/constant/ConstantVisitorTest.java |
+++ b/editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/internal/constant/ConstantVisitorTest.java |
@@ -13,11 +13,16 @@ |
*/ |
package com.google.dart.engine.internal.constant; |
-import com.google.dart.engine.EngineTestCase; |
+import com.google.dart.engine.ast.CompilationUnit; |
+import com.google.dart.engine.ast.CompilationUnitMember; |
import com.google.dart.engine.ast.ConditionalExpression; |
import com.google.dart.engine.ast.Expression; |
import com.google.dart.engine.ast.InstanceCreationExpression; |
+import com.google.dart.engine.ast.TopLevelVariableDeclaration; |
+import com.google.dart.engine.ast.VariableDeclaration; |
+import com.google.dart.engine.context.AnalysisException; |
import com.google.dart.engine.element.ClassElement; |
+import com.google.dart.engine.element.LibraryElement; |
import com.google.dart.engine.internal.element.ClassElementImpl; |
import com.google.dart.engine.internal.element.CompilationUnitElementImpl; |
import com.google.dart.engine.internal.element.ConstructorElementImpl; |
@@ -25,7 +30,9 @@ import com.google.dart.engine.internal.element.FieldFormalParameterElementImpl; |
import com.google.dart.engine.internal.element.LibraryElementImpl; |
import com.google.dart.engine.internal.object.DartObjectImpl; |
import com.google.dart.engine.internal.resolver.TestTypeProvider; |
+import com.google.dart.engine.resolver.ResolverTestCase; |
import com.google.dart.engine.scanner.Keyword; |
+import com.google.dart.engine.source.Source; |
import static com.google.dart.engine.ast.AstFactory.booleanLiteral; |
import static com.google.dart.engine.ast.AstFactory.conditionalExpression; |
@@ -38,7 +45,7 @@ import static com.google.dart.engine.element.ElementFactory.classElement; |
import static com.google.dart.engine.element.ElementFactory.constructorElement; |
import static com.google.dart.engine.element.ElementFactory.library; |
-public class ConstantVisitorTest extends EngineTestCase { |
+public class ConstantVisitorTest extends ResolverTestCase { |
public void test_visitConditionalExpression_false() { |
Expression thenExpression = integer(1L); |
Expression elseExpression = integer(0L); |
@@ -112,10 +119,101 @@ public class ConstantVisitorTest extends EngineTestCase { |
assertValue(1L, expression.accept(new ConstantVisitor(new TestTypeProvider()))); |
} |
+ public void test_visitInstanceCreationExpression_redirect() throws Exception { |
+ CompilationUnit compilationUnit = resolveSource(createSource(// |
+ "const foo = const A();", |
+ "class A {", |
+ " const factory A() = B;", |
+ "}", |
+ "class B implements A {", |
+ " const B();", |
+ "}")); |
+ assertType(evaluateConstant(compilationUnit, "foo"), "B"); |
+ } |
+ |
+ public void test_visitInstanceCreationExpression_redirect_cycle() throws Exception { |
+ // It is an error to have a cycle in factory redirects; however, we need |
+ // to make sure that even if the error occurs, attempting to evaluate the |
+ // constant will terminate. |
+ CompilationUnit compilationUnit = resolveSource(createSource(// |
+ "const foo = const A();", |
+ "class A {", |
+ " const factory A() = A.b;", |
+ " const factory A.b() = A;", |
+ "}")); |
+ assertError(evaluateConstant(compilationUnit, "foo")); |
+ } |
+ |
+ public void test_visitInstanceCreationExpression_redirect_extern() throws Exception { |
+ CompilationUnit compilationUnit = resolveSource(createSource(// |
+ "const foo = const A();", |
+ "class A {", |
+ " external const factory A();", |
+ "}")); |
+ assertError(evaluateConstant(compilationUnit, "foo")); |
+ } |
+ |
+ public void test_visitInstanceCreationExpression_redirect_nonConst() throws Exception { |
+ // It is an error for a const factory constructor redirect to a non-const |
+ // constructor; however, we need to make sure that even if the error |
+ // attempting to evaluate the constant won't cause a crash. |
+ CompilationUnit compilationUnit = resolveSource(createSource(// |
+ "const foo = const A();", |
+ "class A {", |
+ " const factory A() = A.b;", |
+ " A.b();", |
+ "}")); |
+ assertError(evaluateConstant(compilationUnit, "foo")); |
+ } |
+ |
+ public void test_visitInstanceCreationExpression_symbol() throws Exception { |
+ CompilationUnit compilationUnit = resolveSource(createSource("const foo = const Symbol('a');")); |
+ EvaluationResultImpl evaluationResult = evaluateConstant(compilationUnit, "foo"); |
+ assertInstanceOf(ValidResult.class, evaluationResult); |
+ DartObjectImpl value = ((ValidResult) evaluationResult).getValue(); |
+ assertEquals(getTypeProvider().getSymbolType(), value.getType()); |
+ assertEquals("a", value.getValue()); |
+ } |
+ |
+ private void assertError(EvaluationResultImpl result) { |
+ assertInstanceOf(ErrorResult.class, result); |
+ } |
+ |
+ private void assertType(EvaluationResultImpl result, String typeName) { |
+ assertInstanceOf(ValidResult.class, result); |
+ DartObjectImpl value = ((ValidResult) result).getValue(); |
+ assertEquals(typeName, value.getType().getName()); |
+ } |
+ |
private void assertValue(long expectedValue, EvaluationResultImpl result) { |
assertInstanceOf(ValidResult.class, result); |
DartObjectImpl value = ((ValidResult) result).getValue(); |
assertEquals("int", value.getType().getName()); |
assertEquals(expectedValue, value.getIntValue().longValue()); |
} |
+ |
+ private EvaluationResultImpl evaluateConstant(CompilationUnit compilationUnit, String name) |
+ throws AnalysisException { |
+ Expression expression = findTopLevelConstantExpression(compilationUnit, name); |
+ return expression.accept(new ConstantVisitor(getTypeProvider())); |
+ } |
+ |
+ private Expression findTopLevelConstantExpression(CompilationUnit compilationUnit, String name) { |
+ for (CompilationUnitMember member : compilationUnit.getDeclarations()) { |
+ if (member instanceof TopLevelVariableDeclaration) { |
+ for (VariableDeclaration variable : ((TopLevelVariableDeclaration) member).getVariables().getVariables()) { |
+ if (variable.getName().getName().equals(name)) { |
+ return variable.getInitializer(); |
+ } |
+ } |
+ } |
+ } |
+ return null; // Not found |
+ } |
+ |
+ private CompilationUnit resolveSource(String sourceText) throws AnalysisException { |
+ Source source = addSource(sourceText); |
+ LibraryElement library = getAnalysisContext().computeLibraryElement(source); |
+ return getAnalysisContext().resolveCompilationUnit(source, library); |
+ } |
} |