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

Unified Diff: editor/tools/plugins/com.google.dart.engine_test/src/com/google/dart/engine/internal/constant/ConstantVisitorTest.java

Issue 261403004: In constant evaluation, properly handle redirecting factory constructors. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 7 months 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 side-by-side diff with in-line comments
Download patch
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);
+ }
}

Powered by Google App Engine
This is Rietveld 408576698