Index: editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/verifier/ConstantVerifier.java |
diff --git a/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/verifier/ConstantVerifier.java b/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/verifier/ConstantVerifier.java |
index 7459a5f644faf18ae5c87c8881c3578cfdbf72bf..fc802c39baa40b41c98b1f4bb596f86dc86762b3 100644 |
--- a/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/verifier/ConstantVerifier.java |
+++ b/editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/verifier/ConstantVerifier.java |
@@ -15,11 +15,14 @@ package com.google.dart.engine.internal.verifier; |
import com.google.dart.engine.ast.Annotation; |
import com.google.dart.engine.ast.ArgumentList; |
+import com.google.dart.engine.ast.ClassDeclaration; |
+import com.google.dart.engine.ast.ClassMember; |
import com.google.dart.engine.ast.ConstructorDeclaration; |
import com.google.dart.engine.ast.ConstructorFieldInitializer; |
import com.google.dart.engine.ast.ConstructorInitializer; |
import com.google.dart.engine.ast.DefaultFormalParameter; |
import com.google.dart.engine.ast.Expression; |
+import com.google.dart.engine.ast.FieldDeclaration; |
import com.google.dart.engine.ast.FormalParameter; |
import com.google.dart.engine.ast.FormalParameterList; |
import com.google.dart.engine.ast.FunctionExpression; |
@@ -161,7 +164,8 @@ public class ConstantVerifier extends RecursiveAstVisitor<Void> { |
@Override |
public Void visitConstructorDeclaration(ConstructorDeclaration node) { |
if (node.getConstKeyword() != null) { |
- validateInitializers(node); |
+ validateConstructorInitializers(node); |
+ validateFieldInitializers(node.getAncestor(ClassDeclaration.class), node); |
scheglov
2014/07/20 18:55:16
Can it be anything other than node.getParent() ?
Paul Berry
2014/07/21 15:52:14
Good point. It will always be the parent. Change
|
} |
validateDefaultValues(node.getParameters()); |
return super.visitConstructorDeclaration(node); |
@@ -459,6 +463,31 @@ public class ConstantVerifier extends RecursiveAstVisitor<Void> { |
} |
/** |
+ * Validates that the expressions of the given initializers (of a constant constructor) are all |
+ * compile time constants. |
+ * |
+ * @param constructor the constant constructor declaration to validate |
+ */ |
+ private void validateConstructorInitializers(ConstructorDeclaration constructor) { |
+ ParameterElement[] parameterElements = constructor.getParameters().getParameterElements(); |
+ NodeList<ConstructorInitializer> initializers = constructor.getInitializers(); |
+ for (ConstructorInitializer initializer : initializers) { |
+ if (initializer instanceof ConstructorFieldInitializer) { |
+ ConstructorFieldInitializer fieldInitializer = (ConstructorFieldInitializer) initializer; |
+ validateInitializerExpression(parameterElements, fieldInitializer.getExpression()); |
+ } |
+ if (initializer instanceof RedirectingConstructorInvocation) { |
+ RedirectingConstructorInvocation invocation = (RedirectingConstructorInvocation) initializer; |
+ validateInitializerInvocationArguments(parameterElements, invocation.getArgumentList()); |
+ } |
+ if (initializer instanceof SuperConstructorInvocation) { |
+ SuperConstructorInvocation invocation = (SuperConstructorInvocation) initializer; |
+ validateInitializerInvocationArguments(parameterElements, invocation.getArgumentList()); |
+ } |
+ } |
+ } |
+ |
+ /** |
* Validate that the default value associated with each of the parameters in the given list is a |
* compile time constant. |
* |
@@ -489,6 +518,38 @@ public class ConstantVerifier extends RecursiveAstVisitor<Void> { |
} |
/** |
+ * Validates that the expressions of any field initializers in the class declaration are all |
+ * compile time constants. Since this is only required if the class has a constant constructor, |
+ * the error is reported at the constructor site. |
+ * |
+ * @param classDeclaration the class which should be validated |
+ * @param errorSite the site at which errors should be reported. |
+ */ |
+ private void validateFieldInitializers(ClassDeclaration classDeclaration, |
+ ConstructorDeclaration errorSite) { |
+ NodeList<ClassMember> members = classDeclaration.getMembers(); |
+ for (ClassMember member : members) { |
+ if (member instanceof FieldDeclaration) { |
+ FieldDeclaration fieldDeclaration = (FieldDeclaration) member; |
+ if (!fieldDeclaration.isStatic()) { |
+ for (VariableDeclaration variableDeclaration : fieldDeclaration.getFields().getVariables()) { |
+ Expression initializer = variableDeclaration.getInitializer(); |
+ if (initializer != null) { |
+ EvaluationResultImpl result = initializer.accept(new ConstantVisitor(typeProvider)); |
+ if (!(result instanceof ValidResult)) { |
+ errorReporter.reportErrorForNode( |
+ CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST, |
+ errorSite, |
+ variableDeclaration.getName().getName()); |
+ } |
+ } |
+ } |
+ } |
+ } |
+ } |
+ } |
+ |
+ /** |
* Validates that the given expression is a compile time constant. |
* |
* @param parameterElements the elements of parameters of constant constructor, they are |
@@ -559,31 +620,6 @@ public class ConstantVerifier extends RecursiveAstVisitor<Void> { |
} |
/** |
- * Validates that the expressions of the given initializers (of a constant constructor) are all |
- * compile time constants. |
- * |
- * @param constructor the constant constructor declaration to validate |
- */ |
- private void validateInitializers(ConstructorDeclaration constructor) { |
- ParameterElement[] parameterElements = constructor.getParameters().getParameterElements(); |
- NodeList<ConstructorInitializer> initializers = constructor.getInitializers(); |
- for (ConstructorInitializer initializer : initializers) { |
- if (initializer instanceof ConstructorFieldInitializer) { |
- ConstructorFieldInitializer fieldInitializer = (ConstructorFieldInitializer) initializer; |
- validateInitializerExpression(parameterElements, fieldInitializer.getExpression()); |
- } |
- if (initializer instanceof RedirectingConstructorInvocation) { |
- RedirectingConstructorInvocation invocation = (RedirectingConstructorInvocation) initializer; |
- validateInitializerInvocationArguments(parameterElements, invocation.getArgumentList()); |
- } |
- if (initializer instanceof SuperConstructorInvocation) { |
- SuperConstructorInvocation invocation = (SuperConstructorInvocation) initializer; |
- validateInitializerInvocationArguments(parameterElements, invocation.getArgumentList()); |
- } |
- } |
- } |
- |
- /** |
* Validate that if the passed instance creation is 'const' then all its arguments are constant |
* expressions. |
* |