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

Unified Diff: editor/tools/plugins/com.google.dart.engine/src/com/google/dart/engine/internal/verifier/ConstantVerifier.java

Issue 397823004: Detect invalid const constructor due to non-const initializer in field declaration. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Comment fix Created 6 years, 5 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/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.
*

Powered by Google App Engine
This is Rietveld 408576698