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

Unified Diff: compiler/java/com/google/dart/compiler/resolver/CompileTimeConstantResolver.java

Issue 8523034: Compile Time Constants cycle check (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Added new test to exercise code that was throwing ICE Created 9 years, 1 month 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: compiler/java/com/google/dart/compiler/resolver/CompileTimeConstantResolver.java
diff --git a/compiler/java/com/google/dart/compiler/resolver/CompileTimeConstantResolver.java b/compiler/java/com/google/dart/compiler/resolver/CompileTimeConstantResolver.java
new file mode 100644
index 0000000000000000000000000000000000000000..ffd895d8660700f14b36719992cf6eb5261d7aab
--- /dev/null
+++ b/compiler/java/com/google/dart/compiler/resolver/CompileTimeConstantResolver.java
@@ -0,0 +1,199 @@
+// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.google.dart.compiler.resolver;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.dart.compiler.DartCompilerContext;
+import com.google.dart.compiler.ast.DartClass;
+import com.google.dart.compiler.ast.DartExpression;
+import com.google.dart.compiler.ast.DartField;
+import com.google.dart.compiler.ast.DartFunction;
+import com.google.dart.compiler.ast.DartIdentifier;
+import com.google.dart.compiler.ast.DartMethodDefinition;
+import com.google.dart.compiler.ast.DartNewExpression;
+import com.google.dart.compiler.ast.DartNode;
+import com.google.dart.compiler.ast.DartNodeTraverser;
+import com.google.dart.compiler.ast.DartParameter;
+import com.google.dart.compiler.ast.DartPropertyAccess;
+import com.google.dart.compiler.ast.DartUnit;
+import com.google.dart.compiler.ast.DartVariable;
+import com.google.dart.compiler.ast.DartVariableStatement;
+import com.google.dart.compiler.ast.Modifiers;
+
+import java.util.List;
+
+
+/**
+ * Compile-time constants need to infer types, not just in the current units to be resolved, but
+ * in all units. This pass resolves the right hand side of compile-time constants for the later
+ * type analysis and cycle detection done in {@link CompileTimeConstantAnalyzer}.
+ */
+public class CompileTimeConstantResolver {
+
+ private class ConstResolveVisitor extends ResolveVisitor {
+ private class ConstExpressionVisitor extends DartNodeTraverser<Void> {
+
+ @Override
+ public Void visitPropertyAccess(DartPropertyAccess x) {
+ DartNode qualifierNode = x.getQualifier();
+ Element qualifier = null;
+ if (qualifierNode instanceof DartIdentifier) {
+ DartIdentifier qualifierIdent = (DartIdentifier) qualifierNode;
+ qualifier = getContext().getScope().findElement(libraryElement,
+ qualifierIdent
+ .getTargetName());
+ qualifierNode.setSymbol(qualifier);
+ }
+
+ if (qualifier != null) {
+ Element element = null;
+
+ switch (ElementKind.of(qualifier)) {
+ case CLASS:
+ // Must be a static field.
+ element = Elements.findElement(((ClassElement) qualifier), x
+ .getPropertyName());
+ break;
+
+ case LIBRARY:
+ // Library prefix, lookup the element in the reference library.
+ Scope scope = ((LibraryElement) qualifier).getScope();
+ element = scope
+ .findElement(scope.getLibrary(), x.getPropertyName());
+ break;
+
+ default:
+ break;
+ }
+ if (element != null) {
+ recordElement(x, element);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Void visitIdentifier(DartIdentifier x) {
+ x.visitChildren(this);
+
+ Element element = getContext().getScope()
+ .findElement(libraryElement, x.getTargetName());
+ if (element != null) {
+ recordElement(x, element);
+ }
+ return null;
+ }
+ }
+
+ private final LibraryElement libraryElement;
+ private EnclosingElement currentHolder;
+ private final ResolutionContext topLevelContext;
+ private ResolutionContext context;
+
+ private ConstResolveVisitor(DartUnit unit,
+ DartCompilerContext compilerContext, Scope scope,
+ CoreTypeProvider typeProvider) {
+ super(typeProvider);
+ this.libraryElement = unit.getLibrary() == null ? null : unit
+ .getLibrary().getElement();
+ this.topLevelContext = this.context = new ResolutionContext(scope,
+ compilerContext, typeProvider);
+ this.currentHolder = libraryElement;
+ }
+
+ private void beginClassContext(final DartClass node) {
+ assert !ElementKind.of(currentHolder).equals(ElementKind.CLASS) : "nested class?";
+ currentHolder = node.getSymbol();
+ context = context.extend((ClassElement) currentHolder);
+ }
+
+ private void endClassContext() {
+ currentHolder = libraryElement;
+ context = topLevelContext;
+ }
+
+ @Override
+ ResolutionContext getContext() {
+ return context;
+ }
+
+ @Override
+ boolean isStaticContext() {
+ return true;
+ }
+
+ private void resolveConstantExpression(DartExpression expression) {
+ if (expression != null) {
+ expression.accept(new ConstExpressionVisitor());
+ }
+ }
+
+ @Override
+ public Element visitClass(DartClass node) {
+ assert !ElementKind.of(currentHolder).equals(ElementKind.CLASS) : "nested class?";
+ beginClassContext(node);
+ this.visit(node.getMembers());
+ endClassContext();
+ return null;
+ }
+
+ @Override
+ public Element visitField(DartField node) {
+ resolveConstantExpression(node.getValue());
+ return null;
+ }
+
+ @Override
+ public Element visitMethodDefinition(DartMethodDefinition node) {
+ DartFunction functionNode = node.getFunction();
+ List<DartParameter> parameters = functionNode.getParams();
+ for (DartParameter parameter : parameters) {
+ // Then resolve the default values.
+ resolveConstantExpression(parameter.getDefaultExpr());
+ }
+ return null;
+ }
+
+ @Override
+ public Element visitNewExpression(DartNewExpression node) {
+ if (node.isConst()) {
+ for (DartExpression arg : node.getArgs()) {
+ resolveConstantExpression(arg);
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Element visitParameter(DartParameter node) {
+ resolveConstantExpression(node.getDefaultExpr());
+ return null;
+ }
+
+ @Override
+ public Element visitVariableStatement(DartVariableStatement node) {
+ for (DartVariable variable : node.getVariables()) {
+ Modifiers modifiers = node.getModifiers();
+ if (modifiers.isStatic() && modifiers.isFinal()
+ && variable.getValue() != null) {
+ resolveConstantExpression(variable.getValue());
+ }
+ }
+ return null;
+ }
+ }
+
+ public void exec(DartUnit unit,
+ DartCompilerContext compilerContext, CoreTypeProvider typeProvider) {
+ exec(unit, compilerContext, unit.getLibrary().getElement().getScope(), typeProvider);
+ }
+
+ @VisibleForTesting
+ public void exec(DartUnit unit, DartCompilerContext compilerContext,
+ Scope scope, CoreTypeProvider typeProvider) {
+ unit.accept(new ConstResolveVisitor(unit, compilerContext, scope,
+ typeProvider));
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698