| 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"; | 
|  |