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

Unified Diff: lib/compiler/implementation/resolver.dart

Issue 10915083: Change assert implementation to not depend on a top-level function called 'assert'. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address review comments. Created 8 years, 3 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 | « lib/compiler/implementation/lib/mock.dart ('k') | lib/compiler/implementation/ssa/codegen.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/compiler/implementation/resolver.dart
diff --git a/lib/compiler/implementation/resolver.dart b/lib/compiler/implementation/resolver.dart
index 13b6dd37e105e09a7127a838f7b5ce34f2e45b08..387f0e3dd5365fb1775731ce247807e380477f12 100644
--- a/lib/compiler/implementation/resolver.dart
+++ b/lib/compiler/implementation/resolver.dart
@@ -955,6 +955,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
bool inCheckContext;
Scope scope;
ClassElement currentClass;
+ ExpressionStatement currentExpressionStatement;
bool typeRequired = false;
StatementScope statementScope;
int allowedCategory = ElementCategory.VARIABLE | ElementCategory.FUNCTION;
@@ -1163,7 +1164,10 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
visitEmptyStatement(EmptyStatement node) { }
visitExpressionStatement(ExpressionStatement node) {
+ ExpressionStatement oldExpressionStatement = currentExpressionStatement;
+ currentExpressionStatement = node;
visit(node.expression);
+ currentExpressionStatement = oldExpressionStatement;
}
visitFor(For node) {
@@ -1217,10 +1221,35 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
return (str === '&&' || str == '||' || str == '!');
}
+ /**
+ * Check the lexical scope chain for a declaration with the name "assert".
+ *
+ * This is used to detect whether "assert(x)" is actually an assertion or
+ * just a call expression.
+ * It does not check fields inherited from a superclass.
+ */
+ bool isAssertInLexicalScope() {
+ return scope.lexicalLookup(const SourceString("assert")) !== null;
+ }
+
+ /** Check if [node] is the expression of the current expression statement. */
+ bool isExpressionStatementExpression(Node node) {
+ return currentExpressionStatement !== null &&
+ currentExpressionStatement.expression === node;
+ }
+
Element resolveSend(Send node) {
Selector selector = resolveSelector(node);
if (node.receiver === null) {
+ // If this send is the expression of an expression statement, and is on
+ // the form "assert(expr);", and there is no declaration with name
+ // "assert" in the lexical scope, then this is actually an assertion.
+ if (isExpressionStatementExpression(node) &&
+ selector.isAssertSyntax() &&
+ !isAssertInLexicalScope()) {
+ return compiler.assertMethod;
+ }
return node.selector.accept(this);
}
@@ -1408,16 +1437,6 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
world.registerDynamicInvocation(call.name, call);
}
- // TODO(ngeoffray): We should do the check in
- // visitExpressionStatement instead.
- if (target === compiler.assertMethod && !node.isCall) {
- // We can only use assert by calling it.
- if (!inInstanceContext) {
- error(node, MessageKind.MISSING_ARGUMENTS_TO_ASSERT, [node]);
- }
- target = null;
- }
-
// TODO(ngeoffray): Warn if target is null and the send is
// unqualified.
useElement(node, target);
@@ -1917,7 +1936,7 @@ class ResolverVisitor extends CommonResolverVisitor<Element> {
}
Scope blockScope = new BlockScope(scope);
- doInCheckContext(() => visitIn(node.type, blockScope));
+ doInCheckContext(() => visitIn(node.type, blockScope));
visitIn(node.formals, blockScope);
visitIn(node.block, blockScope);
}
@@ -2593,7 +2612,20 @@ class Scope {
Scope(this.parent, this.element);
abstract Element add(Element element);
- abstract Element lookup(SourceString name);
+
+ Element lookup(SourceString name) {
+ Element result = localLookup(name);
+ if (result != null) return result;
+ return parent.lookup(name);
+ }
+
+ Element lexicalLookup(SourceString name) {
+ Element result = localLookup(name);
+ if (result != null) return result;
+ return parent.lexicalLookup(name);
+ }
+
+ abstract Element localLookup(SourceString name);
}
class VariableScope extends Scope {
@@ -2627,7 +2659,7 @@ class TypeDeclarationScope extends Scope {
throw "Cannot add element to TypeDeclarationScope";
}
- Element lookup(SourceString name) {
+ Element localLookup(SourceString name) {
Link<DartType> typeVariableLink = element.typeVariables;
while (!typeVariableLink.isEmpty()) {
TypeVariableType typeVariable = typeVariableLink.head;
@@ -2636,8 +2668,7 @@ class TypeDeclarationScope extends Scope {
}
typeVariableLink = typeVariableLink.tail;
}
-
- return parent.lookup(name);
+ return null;
}
String toString() =>
@@ -2653,11 +2684,7 @@ class MethodScope extends Scope {
assert(parent !== null);
}
- Element lookup(SourceString name) {
- Element found = elements[name];
- if (found !== null) return found;
- return parent.lookup(name);
- }
+ Element localLookup(SourceString name) => elements[name];
Element add(Element newElement) {
if (elements.containsKey(newElement.name)) {
@@ -2687,7 +2714,7 @@ class ClassScope extends TypeDeclarationScope {
ClassScope(Scope parentScope, ClassElement element)
: super(parentScope, element);
- Element lookup(SourceString name) {
+ Element localLookup(SourceString name) {
ClassElement cls = element;
Element result = cls.lookupLocalMember(name);
if (result !== null) return result;
@@ -2695,11 +2722,15 @@ class ClassScope extends TypeDeclarationScope {
// If not in a static context, we can lookup in the
// TypeDeclaration scope, which contains the type variables of
// the class.
- result = super.lookup(name);
- } else {
- result = parent.lookup(name);
+ return super.localLookup(name);
}
- if (result != null) return result;
+ return null;
+ }
+
+ Element lookup(SourceString name) {
+ Element result = super.lookup(name);
+ if (result !== null) return result;
+ ClassElement cls = element;
return cls.lookupSuperMember(name);
}
@@ -2714,9 +2745,10 @@ class TopScope extends Scope {
LibraryElement get library => element;
TopScope(LibraryElement library) : super(null, library);
- Element lookup(SourceString name) {
- return library.find(name);
- }
+
+ Element localLookup(SourceString name) => library.find(name);
+ Element lookup(SourceString name) => localLookup(name);
+ Element lexicalLookup(SourceString name) => localLookup(name);
Element add(Element newElement) {
throw "Cannot add an element in the top scope";
« no previous file with comments | « lib/compiler/implementation/lib/mock.dart ('k') | lib/compiler/implementation/ssa/codegen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698