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

Unified Diff: compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java

Issue 10829292: Issue 4410. Infer types using 'assert' statement (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 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
« no previous file with comments | « no previous file | compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
diff --git a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
index 326ae8342c21a2c7eb351f642f6e1a1fbbc24d90..e42b75fbd84ee682dd6a43f1bf6905ba2650ddec 100644
--- a/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
+++ b/compiler/java/com/google/dart/compiler/type/TypeAnalyzer.java
@@ -182,6 +182,7 @@ public class TypeAnalyzer implements DartCompilationPhase {
private final boolean developerModeChecks;
private final boolean suppressSdkWarnings;
private final boolean memberWarningForInferredTypes;
+ private final Map<DartBlock, VariableElementsRestorer> restoreOnBlockExit = Maps.newHashMap();
/**
* Keeps track of the number of nested catches, used to detect re-throws
@@ -606,49 +607,58 @@ public class TypeAnalyzer implements DartCompilationPhase {
private void visitConditionalNode(DartExpression condition, DartNode node) {
final VariableElementsRestorer variableRestorer = new VariableElementsRestorer();
try {
- if (condition != null) {
- condition.accept(new ASTVisitor<Void>() {
- boolean negation = false;
- @Override
- public Void visitUnaryExpression(DartUnaryExpression node) {
- boolean negationOld = negation;
- try {
- if (node.getOperator() == Token.NOT) {
- negation = !negation;
- }
- return super.visitUnaryExpression(node);
- } finally {
- negation = negationOld;
+ inferVariableTypesFromIsConditions(condition, variableRestorer);
+ typeOf(node);
+ } finally {
+ variableRestorer.restore();
+ }
+ }
+
+ /**
+ * Helper for setting {@link Type}s of {@link VariableElement}s when given "condition" is
+ * satisfied.
+ */
+ private void inferVariableTypesFromIsConditions(DartExpression condition,
+ final VariableElementsRestorer variableRestorer) {
+ if (condition != null) {
+ condition.accept(new ASTVisitor<Void>() {
+ boolean negation = false;
+ @Override
+ public Void visitUnaryExpression(DartUnaryExpression node) {
+ boolean negationOld = negation;
+ try {
+ if (node.getOperator() == Token.NOT) {
+ negation = !negation;
}
+ return super.visitUnaryExpression(node);
+ } finally {
+ negation = negationOld;
}
+ }
- @Override
- public Void visitBinaryExpression(DartBinaryExpression node) {
- // apply "as" always
- // apply "is" only if not negated
- if (node.getOperator() == Token.AS || node.getOperator() == Token.IS && !negation) {
- DartExpression arg1 = node.getArg1();
- DartExpression arg2 = node.getArg2();
- if (arg1 instanceof DartIdentifier && arg1.getElement() instanceof VariableElement
- && arg2 instanceof DartTypeExpression) {
- VariableElement variableElement = (VariableElement) arg1.getElement();
- Type rhsType = arg2.getType();
- Type varType = Types.makeInferred(rhsType);
- variableRestorer.setType(variableElement, varType);
- }
- }
- // operator || means that we can not be sure about types
- if (node.getOperator() == Token.OR) {
- return null;
+ @Override
+ public Void visitBinaryExpression(DartBinaryExpression node) {
+ // apply "as" always
+ // apply "is" only if not negated
+ if (node.getOperator() == Token.AS || node.getOperator() == Token.IS && !negation) {
+ DartExpression arg1 = node.getArg1();
+ DartExpression arg2 = node.getArg2();
+ if (arg1 instanceof DartIdentifier && arg1.getElement() instanceof VariableElement
+ && arg2 instanceof DartTypeExpression) {
+ VariableElement variableElement = (VariableElement) arg1.getElement();
+ Type rhsType = arg2.getType();
+ Type varType = Types.makeInferred(rhsType);
+ variableRestorer.setType(variableElement, varType);
}
- // continue
- return super.visitBinaryExpression(node);
}
- });
- }
- typeOf(node);
- } finally {
- variableRestorer.restore();
+ // operator || means that we can not be sure about types
+ if (node.getOperator() == Token.OR) {
+ return null;
+ }
+ // continue
+ return super.visitBinaryExpression(node);
+ }
+ });
}
}
@@ -1204,7 +1214,14 @@ public class TypeAnalyzer implements DartCompilationPhase {
@Override
public Type visitBlock(DartBlock node) {
- return typeAsVoid(node);
+ try {
+ return typeAsVoid(node);
+ } finally {
+ VariableElementsRestorer variableRestorer = restoreOnBlockExit.remove(node);
+ if (variableRestorer != null) {
+ variableRestorer.restore();
+ }
+ }
}
@Override
@@ -2288,6 +2305,14 @@ public class TypeAnalyzer implements DartCompilationPhase {
if (node.getArguments().size() == 1) {
DartExpression condition = node.getArguments().get(0);
checkAssertCondition(condition);
+ // infer types, which are valid until the end of the enclosing control block
+ if (node.getParent() instanceof DartExprStmt
+ && node.getParent().getParent() instanceof DartBlock) {
+ DartBlock restoreBlock = getBlockForAssertTypesInference(node);
+ VariableElementsRestorer variableRestorer = new VariableElementsRestorer();
+ restoreOnBlockExit.put(restoreBlock, variableRestorer);
+ inferVariableTypesFromIsConditions(condition, variableRestorer);
+ }
} else {
onError(node, TypeErrorCode.ASSERT_NUMBER_ARGUMENTS);
}
@@ -2324,6 +2349,21 @@ public class TypeAnalyzer implements DartCompilationPhase {
return returnType;
}
+ private static DartBlock getBlockForAssertTypesInference(DartNode node) {
+ while (node != null) {
+ if (node instanceof DartBlock) {
+ DartBlock block = (DartBlock) node;
+ DartNode p = block.getParent();
+ if (p instanceof DartIfStatement || p instanceof DartForStatement
+ || p instanceof DartForInStatement || p instanceof DartDoWhileStatement) {
+ return block;
+ }
+ }
+ node = node.getParent();
+ }
+ return null;
+ }
+
/**
* Report warning if given {@link Element} is deprecated.
*/
« no previous file with comments | « no previous file | compiler/javatests/com/google/dart/compiler/type/TypeAnalyzerCompilerTest.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698