Merge pull request #656 from dart-lang/master

Merge master into SDK_AT_HEAD
diff --git a/CHANGELOG.md b/CHANGELOG.md
index c9a401a..05dbb5e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,6 @@
 ## Unpublished
 
+- Refactored how `exports` are handled in a fairly major way.
 - Typecheck the results and input of pipe expressions and the existence of a
   matching pipe. Optional arguments are not yet typechecked.
 - Add typechecking support for `[attr.foo.if]`, and ensure that a corresponding
@@ -7,6 +8,8 @@
 - Fixed issues with `<ng-container>`, which resulted in the inner content simply
   being ignored instead of being validated (and also caused some problems
   with finding inner `<ng-content>` tags).
+- More checks for rejected operators like `+=`, `++` other unary operators and
+  compound assignments.
 
 ## 0.0.17+3
 
diff --git a/README.md b/README.md
index 2b3ed1c..0f5e5e4 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[![Build Status](https://travis-ci.org/dart-lang/angular_analyzer_plugin.svg?branch=master)](https://travis-ci.org/dart-lang/angular_analyzer_plugin)
+[![Build Status](https://travis-ci.org/dart-lang/angular_analyzer_plugin.svg?branch=master)](https://travis-ci.org/dart-lang/angular_analyzer_plugin) [![pub package](https://img.shields.io/pub/v/angular_analyzer_plugin.svg)](https://pub.dartlang.org/packages/angular_analyzer_plugin)
 
 **Requires angular-5.0.0\* and dart SDK 2.0.0-dev.31\*\* or higher to work.**
 
diff --git a/angular_analyzer_plugin/lib/errors.dart b/angular_analyzer_plugin/lib/errors.dart
index 50e964e..1626f97 100644
--- a/angular_analyzer_plugin/lib/errors.dart
+++ b/angular_analyzer_plugin/lib/errors.dart
@@ -56,6 +56,7 @@
   AngularWarningCode.MATCHED_LET_BINDING_HAS_WRONG_TYPE,
   AngularWarningCode.EXPORTS_MUST_BE_PLAIN_IDENTIFIERS,
   AngularWarningCode.DUPLICATE_EXPORT,
+  AngularWarningCode.IDENTIFIER_NOT_EXPORTED,
   AngularWarningCode.COMPONENTS_CANT_EXPORT_THEMSELVES,
   AngularWarningCode.PIPE_SINGLE_NAME_REQUIRED,
   AngularWarningCode.TYPE_IS_NOT_A_PIPE,
@@ -450,6 +451,14 @@
   static const DUPLICATE_EXPORT = const AngularWarningCode(
       'DUPLICATE_EXPORT', 'Duplicate export of identifier {0}');
 
+  /// An error code indicating that an identifier was used in a template, but
+  /// not exported in the component.
+  static const IDENTIFIER_NOT_EXPORTED = const AngularWarningCode(
+      'IDENTIFIER_NOT_EXPORTED',
+      'Identifier {0} was not exported by the component and therefore cannot be'
+      ' used in its template. Add it to the exports property on the component'
+      ' definition to use it here.');
+
   /// An error code indicating component Foo exports Foo, which is unnecessary
   static const COMPONENTS_CANT_EXPORT_THEMSELVES = const AngularWarningCode(
       'COMPONENTS_CANT_EXPORT_THEMSELVES',
diff --git a/angular_analyzer_plugin/lib/src/completion.dart b/angular_analyzer_plugin/lib/src/completion.dart
index c31fedf..124700a 100644
--- a/angular_analyzer_plugin/lib/src/completion.dart
+++ b/angular_analyzer_plugin/lib/src/completion.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/type_system.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart'
     hide AnalysisError;
 import 'package:analyzer_plugin/src/utilities/completion/completion_core.dart';
@@ -179,8 +180,10 @@
     final templates = request.templates;
 
     for (final template in templates) {
-      final typeProvider = template.view.component.classElement.enclosingElement
-          .enclosingElement.context.typeProvider;
+      final context = template.view.component.classElement.enclosingElement
+          .enclosingElement.context;
+      final typeProvider = context.typeProvider;
+      final typeSystem = context.typeSystem;
       final dartSnippet = request.dartSnippet;
 
       if (dartSnippet != null) {
@@ -193,7 +196,9 @@
         final libraryElement = classElement.library;
 
         final dartResolveResult = new _ResolveResultShell(request.path,
-            libraryElement: libraryElement, typeProvider: typeProvider);
+            libraryElement: libraryElement,
+            typeProvider: typeProvider,
+            typeSystem: typeSystem);
         final dartRequest = new DartCompletionRequestImpl(
             request.resourceProvider, request.offset, dartResolveResult);
         await _inheritedReferenceContributor.computeSuggestionsForClass(
@@ -1190,9 +1195,13 @@
   TypeProvider typeProvider;
 
   @override
+  TypeSystem typeSystem;
+
+  @override
   final String path;
 
-  _ResolveResultShell(this.path, {this.libraryElement, this.typeProvider});
+  _ResolveResultShell(this.path,
+      {this.libraryElement, this.typeProvider, this.typeSystem});
 
   @override
   String get content => null;
diff --git a/angular_analyzer_plugin/lib/src/facade/exports_compilation_unit_element.dart b/angular_analyzer_plugin/lib/src/facade/exports_compilation_unit_element.dart
deleted file mode 100644
index 752e6ff..0000000
--- a/angular_analyzer_plugin/lib/src/facade/exports_compilation_unit_element.dart
+++ /dev/null
@@ -1,72 +0,0 @@
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/wrapped.dart';
-import 'package:angular_analyzer_plugin/src/model.dart';
-
-/// A facade for a [CompilationUnitElement] which consists only of a component's
-/// exports, and the component itself.
-class ExportsLimitedCompilationUnitFacade
-    extends WrappedCompilationUnitElement {
-  final Component _component;
-  LibraryElement libraryFacade;
-
-  ExportsLimitedCompilationUnitFacade(
-      CompilationUnitElement wrappedUnit, this._component,
-      {this.libraryFacade})
-      : super(wrappedUnit);
-
-  @override
-  List<PropertyAccessorElement> get accessors =>
-      new List<PropertyAccessorElement>.from(_component.exports
-          .where(_fromThisUnit)
-          .map((export) => export.element)
-          .where((element) => element is PropertyAccessorElement));
-
-  @override
-  LibraryElement get enclosingElement => libraryFacade;
-
-  @override
-  List<ClassElement> get enums => new List<ClassElement>.from(_component.exports
-      .where(_fromThisUnit)
-      .map((export) => export.element)
-      .where((element) => element is ClassElement && element.isEnum));
-
-  @override
-  List<FunctionElement> get functions =>
-      new List<FunctionElement>.from(_component.exports
-          .where(_fromThisUnit)
-          .map((export) => export.element)
-          .where((element) => element is FunctionElement));
-
-  @override
-  List<FunctionTypeAliasElement> get functionTypeAliases => [];
-
-  @override
-  bool get hasJS => false;
-
-  @override
-  bool get isJS => false;
-
-  @override
-  LibraryElement get library => libraryFacade;
-
-  @override
-  List<TopLevelVariableElement> get topLevelVariables => [];
-
-  @override
-  List<ClassElement> get types => new List<ClassElement>.from(_component.exports
-      .where(_fromThisUnit)
-      .map((export) => export.element)
-      .where((element) => element is ClassElement))
-    ..add(_component.classElement);
-
-  @override
-  ClassElement getEnum(String name) =>
-      enums.firstWhere((_enum) => _enum.name == name, orElse: () => null);
-
-  @override
-  ClassElement getType(String className) =>
-      types.firstWhere((type) => type.name == name, orElse: () => null);
-
-  // CompilationUnitFacade's are not used for imports, which have prefixes
-  bool _fromThisUnit(ExportedIdentifier export) => export.prefix == '';
-}
diff --git a/angular_analyzer_plugin/lib/src/facade/exports_import_element.dart b/angular_analyzer_plugin/lib/src/facade/exports_import_element.dart
deleted file mode 100644
index b75876f..0000000
--- a/angular_analyzer_plugin/lib/src/facade/exports_import_element.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/wrapped.dart';
-import 'package:angular_analyzer_plugin/src/facade/exports_library_element.dart';
-import 'package:angular_analyzer_plugin/src/model.dart';
-
-/// A facade for a [ImportElement] which consists only of a component's
-/// exports
-class ExportsImportElementFacade extends WrappedImportElement {
-  final Component _component;
-  LibraryElement libraryFacade;
-
-  ExportsImportElementFacade(ImportElement wrappedImport, this._component,
-      {this.libraryFacade})
-      : super(wrappedImport);
-
-  @override
-  LibraryElement get enclosingElement => libraryFacade;
-
-  @override
-  bool get hasJS => false;
-
-  @override
-  LibraryElement get importedLibrary => wrappedImport.importedLibrary == null
-      ? null
-      : new ExportsLibraryFacade(wrappedImport.importedLibrary, _component,
-          prefix: prefix?.name);
-
-  @override
-  bool get isJS => false;
-
-  @override
-  LibraryElement get library => libraryFacade;
-}
diff --git a/angular_analyzer_plugin/lib/src/facade/exports_library_element.dart b/angular_analyzer_plugin/lib/src/facade/exports_library_element.dart
deleted file mode 100644
index b682329..0000000
--- a/angular_analyzer_plugin/lib/src/facade/exports_library_element.dart
+++ /dev/null
@@ -1,108 +0,0 @@
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/wrapped.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-import 'package:angular_analyzer_plugin/src/facade/exports_compilation_unit_element.dart';
-import 'package:angular_analyzer_plugin/src/facade/exports_import_element.dart';
-import 'package:angular_analyzer_plugin/src/model.dart';
-
-/// A facade for a [Library] which consists only of a components' exports, and
-/// the component itself.
-class ExportsLibraryFacade extends WrappedLibraryElement {
-  final ExportsLimitedCompilationUnitFacade _definingUnit;
-  final Component _owningComponent;
-
-  factory ExportsLibraryFacade(
-      LibraryElement wrappedLib, Component owningComponent,
-      {String prefix}) {
-    if (prefix != null) {
-      return new _PrefixedExportsLibraryFacade(
-          wrappedLib, owningComponent, prefix);
-    }
-    return new ExportsLibraryFacade._(wrappedLib, owningComponent);
-  }
-
-  ExportsLibraryFacade._(LibraryElement wrappedLib, this._owningComponent)
-      : _definingUnit = new ExportsLimitedCompilationUnitFacade(
-            wrappedLib.definingCompilationUnit, _owningComponent),
-        super(wrappedLib) {
-    _definingUnit.libraryFacade = this;
-  }
-
-  @override
-  CompilationUnitElement get definingCompilationUnit => _definingUnit;
-
-  @override
-  bool get hasJS => false;
-
-  @override
-  List<ImportElement> get imports => wrappedLib.imports
-      .map((import) => new ExportsImportElementFacade(import, _owningComponent,
-          libraryFacade: this))
-      .toList();
-
-  @override
-  bool get isDartAsync => false;
-
-  @override
-  bool get isDartCore => false;
-
-  @override
-  bool get isInSdk => false;
-
-  @override
-  bool get isJS => false;
-
-  @override
-  LibraryElement get library => this;
-
-  @override
-  List<LibraryElement> get libraryCycle => wrappedLib.libraryCycle
-      .map((lib) => new ExportsLibraryFacade(lib, _owningComponent))
-      .toList();
-
-  @override
-  List<CompilationUnitElement> get parts => wrappedLib.parts
-      .map((part) => new ExportsLimitedCompilationUnitFacade(
-          part, _owningComponent,
-          libraryFacade: this))
-      .toList();
-
-  @override
-  List<PrefixElement> get prefixes => wrappedLib.prefixes
-      .where((prefix) => _owningComponent.exports
-          .any((export) => export.prefix == prefix.name))
-      .toList();
-
-  @override
-  List<CompilationUnitElement> get units => wrappedLib.units
-      .map((unit) => new ExportsLimitedCompilationUnitFacade(
-          unit, _owningComponent,
-          libraryFacade: this))
-      .toList();
-
-  @override
-  List<ImportElement> getImportsWithPrefix(PrefixElement prefix) => wrappedLib
-      .getImportsWithPrefix(prefix)
-      .map((lib) => new ExportsImportElementFacade(lib, _owningComponent,
-          libraryFacade: this))
-      .toList();
-
-  @override
-  ClassElement getType(String className) => wrappedLib.getType(className);
-}
-
-class _PrefixedExportsLibraryFacade extends ExportsLibraryFacade {
-  final String _prefix;
-  _PrefixedExportsLibraryFacade(
-      LibraryElement wrappedLib, Component owningComponent, this._prefix)
-      : super._(wrappedLib, owningComponent);
-
-  @override
-  Namespace get exportNamespace {
-    final map = <String, Element>{};
-    _owningComponent.exports
-        .where((export) => export.prefix == _prefix)
-        .forEach((export) => map[export.identifier] = export.element);
-    return new Namespace(map);
-  }
-}
diff --git a/angular_analyzer_plugin/lib/src/resolver.dart b/angular_analyzer_plugin/lib/src/resolver.dart
index 4817483..86df668 100644
--- a/angular_analyzer_plugin/lib/src/resolver.dart
+++ b/angular_analyzer_plugin/lib/src/resolver.dart
@@ -15,7 +15,6 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:angular_analyzer_plugin/ast.dart';
 import 'package:angular_analyzer_plugin/errors.dart';
-import 'package:angular_analyzer_plugin/src/facade/exports_library_element.dart';
 import 'package:angular_analyzer_plugin/src/model.dart';
 import 'package:angular_analyzer_plugin/src/options.dart';
 import 'package:angular_analyzer_plugin/src/selector.dart';
@@ -33,80 +32,29 @@
   return parent is ElementInfo && parent.tagMatchedAsCustomTag;
 }
 
-/// Override the standard [ErrorVerifier] class to report unacceptable nodes,
-/// while suppressing secondary errors that would have been raised by
-/// [ErrorVerifier] if we let it see the bogus definitions.
-class AngularErrorVerifier extends _IntermediateErrorVerifier
-    with ReportUnacceptableNodesMixin {
-  final bool acceptAssignment;
+/// Overrides standard [ErrorVerifier] to prevent issues with analyzing dangling
+/// angular nodes. Not intended as a long-term solution.
+class AngularErrorVerifier extends ErrorVerifier {
+  AngularErrorVerifier(
+      ErrorReporter errorReporter,
+      LibraryElement currentLibrary,
+      TypeProvider typeProvider,
+      InheritanceManager2 inheritanceManager,
+      {@required bool enableSuperMixins})
+      : super(errorReporter, currentLibrary, typeProvider, inheritanceManager,
+            enableSuperMixins);
 
   @override
-  ErrorReporter errorReporter;
-  @override
-  TypeProvider typeProvider;
-
-  AngularErrorVerifier(ErrorReporter errorReporter, LibraryElement library,
-      TypeProvider typeProvider, InheritanceManager2 inheritanceManager2,
-      {@required this.acceptAssignment})
-      : errorReporter = errorReporter,
-        typeProvider = typeProvider,
-        super(errorReporter, library, typeProvider, inheritanceManager2);
-
-  @override
-  void visitAssignmentExpression(AssignmentExpression exp) {
-    final variableElement = ErrorVerifier.getVariableElement(exp.leftHandSide);
-    if ((variableElement == null ||
-            variableElement is PropertyInducingElement) &&
-        acceptAssignment) {
-      super.visitAssignmentExpression(exp);
-    } else {
-      exp.visitChildren(this);
-    }
+  void visitFunctionExpression(FunctionExpression func) {
+    // Stop resolving or analyzer will crash.
+    // TODO(mfairhurst): fix the analyzer crash and remove this.
   }
-
-  @override
-  void visitFunctionExpression(FunctionExpression exp) {
-    // error reported in [AngularResolverVisitor] but [ErrorVerifier] crashes
-    // because it isn't resolved
-  }
-
-  @override
-  void visitInstanceCreationExpression(InstanceCreationExpression exp) =>
-      _reportUnacceptableNode(exp, "Usage of new");
-
-  @override
-  void visitListLiteral(ListLiteral list) {
-    if (list.typeArguments != null) {
-      _reportUnacceptableNode(list, "Typed list literals");
-    } else {
-      super.visitListLiteral(list);
-    }
-  }
-
-  @override
-  void visitMapLiteral(MapLiteral map) {
-    if (map.typeArguments != null) {
-      _reportUnacceptableNode(map, "Typed map literals");
-    } else {
-      super.visitMapLiteral(map);
-    }
-  }
-
-  @override
-  void visitRethrowExpression(RethrowExpression exp) =>
-      _reportUnacceptableNode(exp, "Rethrow");
-
-  @override
-  void visitThisExpression(ThisExpression exp) =>
-      _reportUnacceptableNode(exp, "This references");
 }
 
-/// Override the standard [ResolverVisitor] class to report unacceptable nodes,
-/// while suppressing secondary errors that would have been raised by
-/// [ResolverVisitor] if we let it see the bogus definitions.
-class AngularResolverVisitor extends _IntermediateResolverVisitor
-    with ReportUnacceptableNodesMixin {
-  final bool acceptAssignment;
+/// Overrides standard [ResolverVisitor] to prevent issues with analyzing
+/// dangling angular nodes, while also allowing custom resolution of pipes. Not
+/// intended as a long-term solution.
+class AngularResolverVisitor extends _IntermediateResolverVisitor {
   final List<Pipe> pipes;
 
   AngularResolverVisitor(
@@ -115,14 +63,14 @@
       Source source,
       TypeProvider typeProvider,
       AnalysisErrorListener errorListener,
-      {@required this.acceptAssignment,
-      @required this.pipes})
+      {@required this.pipes})
       : super(
             inheritanceManager2, library, source, typeProvider, errorListener);
 
   @override
   void visitAsExpression(AsExpression exp) {
     // This means we generated this in a pipe, and its OK.
+    // TODO(mfairhurst): figure out an alternative approach to this.
     if (exp.asOperator.offset == 0) {
       super.visitAsExpression(exp);
       final pipeName = exp.getProperty<SimpleIdentifier>('_ng_pipeName');
@@ -146,60 +94,14 @@
               [exp.expression.staticType, matchingPipe.requiredArgumentType]);
         }
       }
-    } else {
-      _reportUnacceptableNode(exp, "As expression");
     }
   }
 
   @override
-  void visitAssignmentExpression(AssignmentExpression exp) {
-    // Only block reassignment of locals, not poperties. Resolve elements to
-    // check that.
-    exp.leftHandSide.accept(elementResolver);
-    final variableElement = ErrorVerifier.getVariableElement(exp.leftHandSide);
-    if ((variableElement == null ||
-            variableElement is PropertyInducingElement) &&
-        acceptAssignment) {
-      super.visitAssignmentExpression(exp);
-    } else {
-      _reportUnacceptableNode(exp, "Assignment of locals");
-    }
+  void visitFunctionExpression(FunctionExpression func) {
+    // Stop resolving or analyzer will crash.
+    // TODO(mfairhurst): fix the analyzer crash and remove this.
   }
-
-  @override
-  void visitAwaitExpression(AwaitExpression exp) =>
-      _reportUnacceptableNode(exp, "Await");
-
-  @override
-  void visitCascadeExpression(CascadeExpression exp) {
-    _reportUnacceptableNode(exp, "Cascades", false);
-    // Only resolve the target, not the cascade sections.
-    exp.target.accept(this);
-  }
-
-  @override
-  void visitFunctionExpression(FunctionExpression exp) =>
-      _reportUnacceptableNode(exp, "Anonymous functions", false);
-
-  @override
-  void visitIsExpression(IsExpression exp) =>
-      _reportUnacceptableNode(exp, "Is expression");
-
-  @override
-  void visitNamedExpression(NamedExpression exp) =>
-      _reportUnacceptableNode(exp, "Named arguments");
-
-  @override
-  void visitSuperExpression(SuperExpression exp) =>
-      _reportUnacceptableNode(exp, "Super references");
-
-  @override
-  void visitSymbolLiteral(SymbolLiteral exp) =>
-      _reportUnacceptableNode(exp, "Symbol literal");
-
-  @override
-  void visitThrowExpression(ThrowExpression exp) =>
-      _reportUnacceptableNode(exp, "Throw");
 }
 
 /// Probably the most important visitor to understand in how we process angular
@@ -296,6 +198,230 @@
   }
 }
 
+/// Find nodes which are not supported in angular (such as compound assignment
+/// and function expressions etc.), as well as terms used in the template that
+/// weren't exported by the component.
+class AngularSubsetVisitor extends RecursiveAstVisitor<Object> {
+  final bool acceptAssignment;
+  final Component owningComponent;
+
+  final ErrorReporter errorReporter;
+
+  AngularSubsetVisitor(
+      {@required this.errorReporter,
+      @required this.owningComponent,
+      @required this.acceptAssignment});
+
+  @override
+  void visitAsExpression(AsExpression exp) {
+    if (exp.asOperator.offset == 0) {
+      // This means we generated this in a pipe, and its OK.
+    } else {
+      _reportDisallowedExpression(exp, "As expression", visitChildren: false);
+    }
+
+    // Don't visit the TypeName or it may suggest exporting it, which is not
+    // possible.
+    exp.expression.accept(this);
+  }
+
+  @override
+  void visitAssignmentExpression(AssignmentExpression exp) {
+    if (exp.operator.type != TokenType.EQ) {
+      _reportDisallowedExpression(exp, 'Compound assignment',
+          visitChildren: false);
+    }
+    // Only block reassignment of locals, not poperties. Resolve elements to
+    // check that.
+    final variableElement = ErrorVerifier.getVariableElement(exp.leftHandSide);
+    final isLocal =
+        variableElement != null && variableElement is! PropertyInducingElement;
+    if (!acceptAssignment || isLocal) {
+      _reportDisallowedExpression(exp, 'Assignment of locals',
+          visitChildren: false);
+    }
+
+    super.visitAssignmentExpression(exp);
+  }
+
+  @override
+  void visitAwaitExpression(AwaitExpression exp) =>
+      _reportDisallowedExpression(exp, "Await");
+
+  @override
+  void visitCascadeExpression(CascadeExpression exp) =>
+      _reportDisallowedExpression(exp, "Cascades");
+
+  @override
+  void visitFunctionExpression(FunctionExpression exp) =>
+      _reportDisallowedExpression(exp, "Anonymous functions");
+
+  /// Only allow access to:
+  /// * current class members
+  /// * inherited class members
+  /// * methods
+  /// * angular references (ie `<h1 #ref id="foo"></h1> {{h1.id}}`)
+  /// * exported members
+  ///
+  /// Flag the rest and give the hint that they should be exported.
+  void visitIdentifier(Identifier id) {
+    final element = id.staticElement;
+    if (id is PrefixedIdentifier && id.prefix.staticElement is! PrefixElement) {
+      // Static methods, enums, etc. Check the LHS.
+      visitIdentifier(id.prefix);
+      return;
+    }
+    if (id.parent is PropertyAccess &&
+        identical(id, (id.parent as PropertyAccess).propertyName)) {
+      // Accessors are always allowed.
+      return;
+    }
+    if (element is PrefixElement) {
+      // Prefixes can't be exported, and analyzer reports a warning for dangling
+      // prefixes.
+      return;
+    }
+    if (element is MethodElement) {
+      // All methods are OK, as in `x.y()`. It's only `x` that may be hidden.
+      return;
+    }
+    if (element is ClassElement && element == owningComponent.classElement) {
+      // Static method calls on the current class are allowed
+      return;
+    }
+    if (element is DynamicElementImpl) {
+      // Usually indicates a resolution error, so don't double report it.
+      return;
+    }
+    if (element == null) {
+      // Also usually indicates an error, don't double report.
+      return;
+    }
+    if (element is LocalVariableElement) {
+      // `$event` variables, `ngFor` variables, these are OK.
+      return;
+    }
+    if (element is ParameterElement) {
+      // Named parameters: not allowed, but flagged in [visitNamedExpression].
+      return;
+    }
+    if (element is AngularElement) {
+      // Variables local to the template
+      return;
+    }
+    if ((element is PropertyInducingElement ||
+            element is PropertyAccessorElement) &&
+        (owningComponent.classElement.lookUpGetter(id.name, null) != null ||
+            owningComponent.classElement.lookUpSetter(id.name, null) != null)) {
+      // Part of the component interface.
+      return;
+    }
+
+    if (id is PrefixedIdentifier) {
+      if (owningComponent.exports.any((export) =>
+          export.prefix == id.prefix.name && id.name == export.identifier)) {
+        // Correct reference to exported prefix identifier
+        return;
+      }
+    } else {
+      if (owningComponent.exports.any(
+          (export) => export.prefix == null && id.name == export.identifier)) {
+        // Correct reference to exported simple identifier
+        return;
+      }
+    }
+
+    errorReporter.reportErrorForNode(
+        AngularWarningCode.IDENTIFIER_NOT_EXPORTED, id, [id]);
+  }
+
+  @override
+  void visitInstanceCreationExpression(InstanceCreationExpression exp) {
+    _reportDisallowedExpression(exp, "Usage of new", visitChildren: false);
+    // Don't visit the TypeName or it may suggest exporting it, which is not
+    // possible.
+
+    exp.argumentList.accept(this);
+  }
+
+  @override
+  void visitIsExpression(IsExpression exp) {
+    _reportDisallowedExpression(exp, "Is expression", visitChildren: false);
+    // Don't visit the TypeName or it may suggest exporting it, which is not
+    // possible.
+
+    exp.expression.accept(this);
+  }
+
+  @override
+  void visitListLiteral(ListLiteral list) {
+    if (list.typeArguments != null) {
+      _reportDisallowedExpression(list, "Typed list literals",
+          visitChildren: false);
+      // Don't visit the TypeName or it may suggest exporting it, which is not
+      // possible.e.
+
+      list.elements.accept(this);
+    } else {
+      super.visitListLiteral(list);
+    }
+  }
+
+  @override
+  void visitMapLiteral(MapLiteral map) {
+    if (map.typeArguments != null) {
+      _reportDisallowedExpression(map, "Typed map literals",
+          visitChildren: false);
+      // Don't visit the TypeName or it may suggest exporting it, which is not
+      // possible.e.
+
+      map.entries.accept(this);
+    } else {
+      super.visitMapLiteral(map);
+    }
+  }
+
+  @override
+  void visitNamedExpression(NamedExpression exp) =>
+      _reportDisallowedExpression(exp, "Named arguments");
+
+  @override
+  void visitPostfixExpression(PostfixExpression exp) {
+    _reportDisallowedExpression(exp, exp.operator.lexeme);
+  }
+
+  @override
+  void visitPrefixedIdentifier(PrefixedIdentifier id) => visitIdentifier(id);
+
+  @override
+  void visitPrefixExpression(PrefixExpression exp) {
+    if (exp.operator.type != TokenType.MINUS) {
+      _reportDisallowedExpression(exp, exp.operator.lexeme);
+    }
+  }
+
+  @override
+  void visitSimpleIdentifier(SimpleIdentifier id) => visitIdentifier(id);
+
+  @override
+  void visitSymbolLiteral(SymbolLiteral exp) =>
+      _reportDisallowedExpression(exp, "Symbol literal");
+
+  @override
+  void visitThrowExpression(ThrowExpression exp) =>
+      _reportDisallowedExpression(exp, "Throw");
+
+  void _reportDisallowedExpression(Expression node, String description,
+      {bool visitChildren = true}) {
+    errorReporter.reportErrorForNode(
+        AngularWarningCode.DISALLOWED_EXPRESSION, node, [description]);
+
+    if (visitChildren) {
+      node.visitChildren(this);
+    }
+  }
+}
+
 class ComponentContentResolver extends AngularAstVisitor {
   final Source templateSource;
   final Template template;
@@ -1172,23 +1298,6 @@
       type.lookUpInheritedGetter(name)?.returnType;
 }
 
-abstract class ReportUnacceptableNodesMixin
-    implements RecursiveAstVisitor<Object> {
-  ErrorReporter get errorReporter;
-  TypeProvider get typeProvider;
-  void _reportUnacceptableNode(Expression node, String description,
-      [bool visitChildren = true]) {
-    errorReporter.reportErrorForNode(
-        AngularWarningCode.DISALLOWED_EXPRESSION, node, [description]);
-
-    // "resolve" the node, a null type causes later errors.
-    node.propagatedType = node.staticType = typeProvider.dynamicType;
-    if (visitChildren) {
-      node.visitChildren(this);
-    }
-  }
-}
-
 /// Once all the scopes for all the expressions & statements are prepared, we're
 /// ready to resolve all the expressions inside and typecheck everything.
 ///
@@ -1539,8 +1648,7 @@
   /// Resolve the given [AstNode] ([expression] or [statement]) and report errors.
   void _resolveDartAstNode(AstNode astNode, bool acceptAssignment) {
     final classElement = view.classElement;
-    final library =
-        new ExportsLibraryFacade(classElement.library, view.component);
+    final library = classElement.library;
     {
       final visitor = new TypeResolverVisitor(
           library, view.source, typeProvider, errorListener);
@@ -1550,7 +1658,7 @@
         new InheritanceManager2(typeSystem as StrongTypeSystemImpl);
     final resolver = new AngularResolverVisitor(inheritanceManager2, library,
         templateSource, typeProvider, errorListener,
-        acceptAssignment: acceptAssignment, pipes: pipes);
+        pipes: pipes);
     // fill the name scope
     final classScope = new ClassScope(resolver.nameScope, classElement);
     final localScope = new EnclosedScope(classScope);
@@ -1564,9 +1672,15 @@
     // verify
     final verifier = new AngularErrorVerifier(
         errorReporter, library, typeProvider, inheritanceManager2,
-        acceptAssignment: acceptAssignment)
+        enableSuperMixins: true)
       ..enclosingClass = classElement;
     astNode.accept(verifier);
+    // Check for concepts illegal to templates (for instance function literals).
+    final angularSubsetChecker = new AngularSubsetVisitor(
+        errorReporter: errorReporter,
+        acceptAssignment: acceptAssignment,
+        owningComponent: view.component);
+    astNode.accept(angularSubsetChecker);
   }
 
   /// Resolve the Dart expression with the given [code] at [offset].
@@ -1914,20 +2028,6 @@
 }
 
 /// Workaround for "This mixin application is invalid because all of the
-/// constructors in the base class 'ErrorVerifier' have optional parameters."
-/// in the definition of [AngularErrorVerifier].
-///
-/// See https://github.com/dart-lang/sdk/issues/15101 for details
-class _IntermediateErrorVerifier extends ErrorVerifier {
-  _IntermediateErrorVerifier(
-    ErrorReporter errorReporter,
-    LibraryElement library,
-    TypeProvider typeProvider,
-    InheritanceManager2 inheritanceManager2,
-  ) : super(errorReporter, library, typeProvider, inheritanceManager2, false);
-}
-
-/// Workaround for "This mixin application is invalid because all of the
 /// constructors in the base class 'ResolverVisitor' have optional parameters."
 /// in the definition of [AngularResolverVisitor].
 ///
diff --git a/angular_analyzer_plugin/pubspec.yaml b/angular_analyzer_plugin/pubspec.yaml
index 69865cc..d9681cc 100644
--- a/angular_analyzer_plugin/pubspec.yaml
+++ b/angular_analyzer_plugin/pubspec.yaml
@@ -9,10 +9,10 @@
 environment:
   sdk: '>=2.0.0-dev.0.0 <3.0.0'
 dependencies:
-  analyzer: '0.32.4'
+  analyzer: '0.33.1'
   plugin: '^0.2.0'
   #  tuple: '^1.0.1' Does not yet support Dart 2
-  analyzer_plugin: '0.0.1-alpha.4'
+  analyzer_plugin: '0.0.1-alpha.5'
   angular_ast: '^0.5.0'
   meta: ^1.0.2
   yaml: ^2.1.2
diff --git a/angular_analyzer_plugin/test/abstract_angular.dart b/angular_analyzer_plugin/test/abstract_angular.dart
index 0901d0e..b9573ce 100644
--- a/angular_analyzer_plugin/test/abstract_angular.dart
+++ b/angular_analyzer_plugin/test/abstract_angular.dart
@@ -116,16 +116,22 @@
   AbstractAngularTest() : includeQueryList = true;
   AbstractAngularTest.future() : includeQueryList = false;
 
-  /// Assert that the [errCode] is reported for [code], highlighting the [snippet].
+  /// Assert that the [errCode] is reported for [code], highlighting the
+  /// [snippet]. Optionally, expect [additionalErrorCodes] to appear at any
+  /// location.
   void assertErrorInCodeAtPosition(
-      ErrorCode errCode, String code, String snippet) {
+      ErrorCode errCode, String code, String snippet,
+      {List<ErrorCode> additionalErrorCodes}) {
     final snippetIndex = code.indexOf(snippet);
     expect(snippetIndex, greaterThan(-1),
         reason: 'Error in test: snippet $snippet not part of code $code');
-    errorListener.assertErrorsWithCodes(<ErrorCode>[errCode]);
-    final error = errorListener.errors.single;
+    final expectedErrorCodes = (additionalErrorCodes ?? <ErrorCode>[])
+      ..add(errCode);
+    errorListener.assertErrorsWithCodes(expectedErrorCodes);
+    final error =
+        errorListener.errors.singleWhere((e) => e.errorCode == errCode);
     expect(error.offset, snippetIndex);
-    expect(errorListener.errors.single.length, snippet.length);
+    expect(error.length, snippet.length);
   }
 
   /// For [expectedErrors], it is a List of Tuple4 (1 per error):
diff --git a/angular_analyzer_plugin/test/resolver_test.dart b/angular_analyzer_plugin/test/resolver_test.dart
index a668aea..c6fa8ba 100644
--- a/angular_analyzer_plugin/test/resolver_test.dart
+++ b/angular_analyzer_plugin/test/resolver_test.dart
@@ -143,6 +143,7 @@
 
   // ignore: non_constant_identifier_names
   Future test_catchPkgHtmlGithubBug44() async {
+    // see https://github.com/dart-lang/html/issues/44
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
 class TestPanel {
@@ -284,40 +285,6 @@
   }
 
   // ignore: non_constant_identifier_names
-  Future test_expression_as_not_allowed() async {
-    _addDartSource(r'''
-@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
-class TestPanel {
-  String str;
-}
-''');
-    final code = r"""
-<h1>{{str as String}}</h1>
-""";
-    _addHtmlSource(code);
-    await _resolveSingleTemplate(dartSource);
-    assertErrorInCodeAtPosition(
-        AngularWarningCode.DISALLOWED_EXPRESSION, code, "str as String");
-  }
-
-  // ignore: non_constant_identifier_names
-  Future test_expression_assignment_not_allowed() async {
-    _addDartSource(r'''
-@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
-class TestPanel {
-  String str;
-}
-''');
-    final code = r"""
-<h1 #h1 [hidden]="h1 = 4"></h1>
-""";
-    _addHtmlSource(code);
-    await _resolveSingleTemplate(dartSource);
-    assertErrorInCodeAtPosition(
-        AngularWarningCode.DISALLOWED_EXPRESSION, code, "h1 = 4");
-  }
-
-  // ignore: non_constant_identifier_names
   Future test_expression_attrBinding_expressionTypeError() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -437,43 +404,6 @@
   }
 
   // ignore: non_constant_identifier_names
-  Future test_expression_await_not_allowed() async {
-    _addDartSource(r'''
-@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
-class TestPanel {
-  String str;
-}
-''');
-    final code = r"""
-<h1 [hidden]="await str"></h1>
-""";
-    _addHtmlSource(code);
-    await _resolveSingleTemplate(dartSource);
-    //This actually gets parsed as an identifier, which is OK. Still fails!
-    errorListener.assertErrorsWithCodes([
-      StaticWarningCode.UNDEFINED_IDENTIFIER,
-      AngularWarningCode.TRAILING_EXPRESSION
-    ]);
-  }
-
-  // ignore: non_constant_identifier_names
-  Future test_expression_cascade_not_allowed() async {
-    _addDartSource(r'''
-@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
-class TestPanel {
-  String str;
-}
-''');
-    final code = r"""
-<h1 [hidden]="str..x"></h1>
-""";
-    _addHtmlSource(code);
-    await _resolveSingleTemplate(dartSource);
-    assertErrorInCodeAtPosition(
-        AngularWarningCode.DISALLOWED_EXPRESSION, code, "str..x");
-  }
-
-  // ignore: non_constant_identifier_names
   Future test_expression_classBinding_invalidClassName() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -641,41 +571,6 @@
     _assertElement('handleClick()').dart.method.at('handleClick(MouseEvent');
   }
 
-  // ignore: non_constant_identifier_names
-  Future test_expression_func2_not_allowed() async {
-    _addDartSource(r'''
-@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
-class TestPanel {
-  String str;
-}
-''');
-    final code = r"""
-<h1 [hidden]="()=>x"></h1>
-""";
-    _addHtmlSource(code);
-    await _resolveSingleTemplate(dartSource);
-    assertErrorInCodeAtPosition(
-        AngularWarningCode.DISALLOWED_EXPRESSION, code, "()=>x");
-  }
-
-  // ignore: non_constant_identifier_names
-  Future test_expression_func_not_allowed() async {
-    _addDartSource(r'''
-@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
-class TestPanel {
-  String str;
-}
-''');
-    final code = r"""
-<h1 [hidden]="(){}"></h1>
-""";
-    _addHtmlSource(code);
-    await _resolveSingleTemplate(dartSource);
-    assertErrorInCodeAtPosition(
-        AngularWarningCode.DISALLOWED_EXPRESSION, code, "(){}");
-  }
-
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_expression_input_genericDirective_lowerBoundChainTypeError() async {
@@ -699,7 +594,6 @@
         AngularWarningCode.INPUT_BINDING_TYPE_ERROR, code, "notString");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_expression_input_genericDirective_lowerBoundNestedTypeError() async {
@@ -723,7 +617,6 @@
         AngularWarningCode.INPUT_BINDING_TYPE_ERROR, code, "notStringList");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_expression_inputAndOutputBinding_extendGenericUnbounded_ok() async {
@@ -753,7 +646,6 @@
     errorListener.assertNoErrors();
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_expression_inputAndOutputBinding_genericDirective_chain_ok() async {
@@ -780,7 +672,6 @@
     errorListener.assertNoErrors();
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_expression_inputAndOutputBinding_genericDirective_nested_ok() async {
@@ -832,7 +723,6 @@
     errorListener.assertNoErrors();
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_expression_inputAndOutputBinding_genericDirectiveChild_ok() async {
@@ -1101,7 +991,6 @@
         AngularWarningCode.EMPTY_BINDING, code, "[title]");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_expression_inputBinding_genericDirective_lowerBoundTypeError() async {
@@ -1370,23 +1259,6 @@
   }
 
   // ignore: non_constant_identifier_names
-  Future test_expression_is_not_allowed() async {
-    _addDartSource(r'''
-@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
-class TestPanel {
-  String str;
-}
-''');
-    final code = r"""
-<h1 [hidden]="str is int"></h1>
-""";
-    _addHtmlSource(code);
-    await _resolveSingleTemplate(dartSource);
-    assertErrorInCodeAtPosition(
-        AngularWarningCode.DISALLOWED_EXPRESSION, code, "str is int");
-  }
-
-  // ignore: non_constant_identifier_names
   Future test_expression_keyupdownWithKeysOk() async {
     _addDartSource(r'''
 import 'dart:html';
@@ -1438,23 +1310,6 @@
   }
 
   // ignore: non_constant_identifier_names
-  Future test_expression_named_args_not_allowed() async {
-    _addDartSource(r'''
-@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
-class TestPanel {
-  bool callMe({String arg}) => true;
-}
-''');
-    final code = r"""
-<h1 [hidden]="callMe(arg: 'bob')"></h1>
-""";
-    _addHtmlSource(code);
-    await _resolveSingleTemplate(dartSource);
-    assertErrorInCodeAtPosition(
-        AngularWarningCode.DISALLOWED_EXPRESSION, code, "arg: 'bob'");
-  }
-
-  // ignore: non_constant_identifier_names
   Future test_expression_nativeEventBindingOnComponent() async {
     _addDartSource(r'''
 import 'dart:html';
@@ -1501,40 +1356,6 @@
   }
 
   // ignore: non_constant_identifier_names
-  Future test_expression_nested_as_not_allowed() async {
-    _addDartSource(r'''
-@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
-class TestPanel {
-  String str;
-}
-''');
-    final code = r"""
-<h1>{{(str.isEmpty as String).isEmpty}}</h1>
-""";
-    _addHtmlSource(code);
-    await _resolveSingleTemplate(dartSource);
-    assertErrorInCodeAtPosition(AngularWarningCode.DISALLOWED_EXPRESSION, code,
-        "str.isEmpty as String");
-  }
-
-  // ignore: non_constant_identifier_names
-  Future test_expression_new_not_allowed() async {
-    _addDartSource(r'''
-@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
-class TestPanel {
-  String str;
-}
-''');
-    final code = r"""
-<h1 [hidden]="new String().isEmpty"></h1>
-""";
-    _addHtmlSource(code);
-    await _resolveSingleTemplate(dartSource);
-    assertErrorInCodeAtPosition(
-        AngularWarningCode.DISALLOWED_EXPRESSION, code, "new String()");
-  }
-
-  // ignore: non_constant_identifier_names
   Future test_expression_outputBinding_boundToNothing() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -1551,7 +1372,6 @@
         AngularWarningCode.NONEXIST_OUTPUT_BOUND, code, "title");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_expression_outputBinding_genericDirective_lowerBoundTypeError() async {
@@ -1689,8 +1509,8 @@
         AngularWarningCode.AMBIGUOUS_PIPE, code, 'ambiguous');
   }
 
-  // ignore: non_constant_identifier_names
   @failingTest
+  // ignore: non_constant_identifier_names
   Future test_expression_pipe_in_moustache_extraArg() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -1710,8 +1530,8 @@
         StaticWarningCode.EXTRA_POSITIONAL_ARGUMENTS, code, '"extra"');
   }
 
-  // ignore: non_constant_identifier_names
   @failingTest
+  // ignore: non_constant_identifier_names
   Future test_expression_pipe_in_moustache_extraExtraArg() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -1767,8 +1587,8 @@
         StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, code, '1');
   }
 
-  // ignore: non_constant_identifier_names
   @failingTest
+  // ignore: non_constant_identifier_names
   Future test_expression_pipe_in_moustache_typeErrorOptionalArg() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html', pipes: [StringPipe])
@@ -1830,8 +1650,8 @@
         StaticWarningCode.UNDEFINED_IDENTIFIER, code, "error1");
   }
 
-  // ignore: non_constant_identifier_names
   @failingTest
+  // ignore: non_constant_identifier_names
   Future test_expression_pipe_in_moustache_with_error_inArg() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html', pipes: [Pipe1])
@@ -1893,40 +1713,6 @@
   }
 
   // ignore: non_constant_identifier_names
-  Future test_expression_rethrow_not_allowed() async {
-    _addDartSource(r'''
-@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
-class TestPanel {
-  String str;
-}
-''');
-    final code = r"""
-<h1 [hidden]="rethrow"></h1>
-""";
-    _addHtmlSource(code);
-    await _resolveSingleTemplate(dartSource);
-    assertErrorInCodeAtPosition(
-        AngularWarningCode.DISALLOWED_EXPRESSION, code, "rethrow");
-  }
-
-  // ignore: non_constant_identifier_names
-  Future test_expression_setter_not_allowed() async {
-    _addDartSource(r'''
-@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
-class TestPanel {
-  String str;
-}
-''');
-    final code = r"""
-<h1 [hidden]="str = 'hey'"></h1>
-""";
-    _addHtmlSource(code);
-    await _resolveSingleTemplate(dartSource);
-    assertErrorInCodeAtPosition(
-        AngularWarningCode.DISALLOWED_EXPRESSION, code, "str = 'hey'");
-  }
-
-  // ignore: non_constant_identifier_names
   Future test_expression_styleBinding_noUnit_expressionTypeError() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -1997,6 +1783,7 @@
     errorListener.assertNoErrors();
   }
 
+  // ignore: non_constant_identifier_names
   Future test_expression_styleBinding_withUnit_invalidPropertyName() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -2019,6 +1806,7 @@
     ]);
   }
 
+  // ignore: non_constant_identifier_names
   Future test_expression_styleBinding_withUnit_invalidUnitName() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -2041,6 +1829,7 @@
     ]);
   }
 
+  // ignore: non_constant_identifier_names
   Future test_expression_styleBinding_withUnit_nonWidthOrHeightPercent() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -2057,6 +1846,7 @@
         AngularWarningCode.INVALID_CSS_UNIT_NAME, code, "%");
   }
 
+  // ignore: non_constant_identifier_names
   Future test_expression_styleBinding_withUnit_typeError() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -2073,6 +1863,7 @@
         AngularWarningCode.CSS_UNIT_BINDING_NOT_NUMBER, code, "notNumber");
   }
 
+  // ignore: non_constant_identifier_names
   Future test_expression_styleBinding_withUnit_widthPercent() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -2088,22 +1879,7 @@
     errorListener.assertNoErrors();
   }
 
-  Future test_expression_super_not_allowed() async {
-    _addDartSource(r'''
-@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
-class TestPanel {
-  String str;
-}
-''');
-    final code = r"""
-<h1 [hidden]="super.x"></h1>
-""";
-    _addHtmlSource(code);
-    await _resolveSingleTemplate(dartSource);
-    assertErrorInCodeAtPosition(
-        AngularWarningCode.DISALLOWED_EXPRESSION, code, "super");
-  }
-
+  // ignore: non_constant_identifier_names
   Future test_expression_symbol_invoked_noCrash() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -2117,59 +1893,12 @@
     _addHtmlSource(code);
     await _resolveSingleTemplate(dartSource);
     assertErrorInCodeAtPosition(
-        AngularWarningCode.DISALLOWED_EXPRESSION, code, "#symbol");
+        AngularWarningCode.DISALLOWED_EXPRESSION, code, "#symbol",
+        additionalErrorCodes: [
+          StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION
+        ]);
   }
 
-  Future test_expression_symbol_not_allowed() async {
-    _addDartSource(r'''
-@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
-class TestPanel {
-  String str;
-}
-''');
-    final code = r"""
-<h1 [hidden]="#symbol"></h1>
-""";
-    _addHtmlSource(code);
-    await _resolveSingleTemplate(dartSource);
-    assertErrorInCodeAtPosition(
-        AngularWarningCode.DISALLOWED_EXPRESSION, code, "#symbol");
-  }
-
-  Future test_expression_this_not_allowed() async {
-    _addDartSource(r'''
-@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
-class TestPanel {
-  String str;
-}
-''');
-    final code = r"""
-<h1 [hidden]="this"></h1>
-""";
-    _addHtmlSource(code);
-    await _resolveSingleTemplate(dartSource);
-    assertErrorInCodeAtPosition(
-        AngularWarningCode.DISALLOWED_EXPRESSION, code, "this");
-  }
-
-  // ignore: non_constant_identifier_names
-  Future test_expression_throw_not_allowed() async {
-    _addDartSource(r'''
-@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
-class TestPanel {
-  String str;
-}
-''');
-    final code = r"""
-<h1 [hidden]="throw str"></h1>
-""";
-    _addHtmlSource(code);
-    await _resolveSingleTemplate(dartSource);
-    assertErrorInCodeAtPosition(
-        AngularWarningCode.DISALLOWED_EXPRESSION, code, "throw str");
-  }
-
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_expression_twoWayBinding_genericDirective_lowerBoundTypeError() async {
@@ -2240,6 +1969,7 @@
         AngularWarningCode.EMPTY_BINDING, code, "[(twoWay)]");
   }
 
+  // ignore: non_constant_identifier_names
   Future test_expression_twoWayBinding_noInputToBind() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', directives: const [TitleComponent],
@@ -2283,6 +2013,7 @@
         AngularWarningCode.NONEXIST_TWO_WAY_OUTPUT_BOUND, code, "inputOnly");
   }
 
+  // ignore: non_constant_identifier_names
   Future test_expression_twoWayBinding_notAssignableError() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel',
@@ -2362,7 +2093,415 @@
   }
 
   // ignore: non_constant_identifier_names
-  Future test_expression_typed_list_not_allowed() async {
+  Future test_expression_unaryMinus_allowed() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  int x;
+}
+''');
+    final code = r"""
+{{-x}}
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    errorListener.assertNoErrors();
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_as() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  String str;
+}
+''');
+    final code = r"""
+<h1>{{str as String}}</h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        AngularWarningCode.DISALLOWED_EXPRESSION, code, "str as String");
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_await() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  String str;
+}
+''');
+    final code = r"""
+<h1 [hidden]="await str"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    //This actually gets parsed as an identifier, which is OK. Still fails!
+    errorListener.assertErrorsWithCodes([
+      StaticWarningCode.UNDEFINED_IDENTIFIER,
+      AngularWarningCode.TRAILING_EXPRESSION
+    ]);
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_cascade() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  bool val;
+}
+''');
+    final code = r"""
+<h1 [hidden]="val..toString"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        AngularWarningCode.DISALLOWED_EXPRESSION, code, "val..toString");
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_func() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  String str;
+}
+''');
+    final code = r"""
+<h1 [hidden]="(){}"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        AngularWarningCode.DISALLOWED_EXPRESSION, code, "(){}");
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_func2() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  String str;
+}
+''');
+    final code = r"""
+<h1 [hidden]="()=>x"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        AngularWarningCode.DISALLOWED_EXPRESSION, code, "()=>x");
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_is() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  String str;
+}
+''');
+    final code = r"""
+<h1 [hidden]="str is int"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        AngularWarningCode.DISALLOWED_EXPRESSION, code, "str is int");
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_minusEq() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  int x;
+}
+''');
+    final code = r"""
+<h1 (click)="x -= 1"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        AngularWarningCode.DISALLOWED_EXPRESSION, code, 'x -= 1');
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_namedArgs() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  bool callMe({String arg}) => true;
+}
+''');
+    final code = r"""
+<h1 [hidden]="callMe(arg: 'bob')"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        AngularWarningCode.DISALLOWED_EXPRESSION, code, "arg: 'bob'");
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_nestedAs() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  String str;
+}
+''');
+    final code = r"""
+<h1>{{(str.isEmpty as String).isEmpty}}</h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(AngularWarningCode.DISALLOWED_EXPRESSION, code,
+        "str.isEmpty as String");
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_new() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  String str;
+}
+''');
+    final code = r"""
+<h1 [hidden]="new TestPanel() != null"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        AngularWarningCode.DISALLOWED_EXPRESSION, code, "new TestPanel()");
+  }
+
+  Future test_expressionNotAllowed_plusEq() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  int x;
+}
+''');
+    final code = r"""
+<h1 (click)="x += 1"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        AngularWarningCode.DISALLOWED_EXPRESSION, code, 'x += 1');
+  }
+
+  Future test_expressionNotAllowed_postfixMinusMinus() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  int x;
+}
+''');
+    final code = r"""
+<h1 (click)="x--"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        AngularWarningCode.DISALLOWED_EXPRESSION, code, 'x--');
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_postfixPlusPlus() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  int x;
+}
+''');
+    final code = r"""
+<h1 (click)="x++"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        AngularWarningCode.DISALLOWED_EXPRESSION, code, 'x++');
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_prefixMinusMinus() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  int x;
+}
+''');
+    final code = r"""
+<h1 (click)="--x"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        AngularWarningCode.DISALLOWED_EXPRESSION, code, '--x');
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_prefixPlusPlus() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  int x;
+}
+''');
+    final code = r"""
+<h1 (click)="++x"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        AngularWarningCode.DISALLOWED_EXPRESSION, code, '++x');
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_referenceAssignment() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  String str;
+}
+''');
+    final code = r"""
+    <h1 #h1 [hidden]="(h1 = null) == null"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        AngularWarningCode.DISALLOWED_EXPRESSION, code, "h1 = null");
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_rethrow() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  String str;
+}
+''');
+    final code = r"""
+<h1 [hidden]="rethrow"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        CompileTimeErrorCode.RETHROW_OUTSIDE_CATCH, code, "rethrow");
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_setter() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  String str;
+}
+''');
+    final code = r"""
+<h1 [hidden]="(str = 'hey') == null"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        AngularWarningCode.DISALLOWED_EXPRESSION, code, "str = 'hey'");
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_statementAssignment() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  String str;
+}
+''');
+    final code = r"""
+<h1 #h1 (click)="h1 = null"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        AngularWarningCode.DISALLOWED_EXPRESSION, code, "h1 = null");
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_super() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  String str;
+}
+''');
+    final code = r"""
+<h1 [hidden]="super.x"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        CompileTimeErrorCode.SUPER_IN_INVALID_CONTEXT, code, "super");
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_symbol() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  String str;
+}
+''');
+    final code = r"""
+<h1 [hidden]="#symbol == null"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        AngularWarningCode.DISALLOWED_EXPRESSION, code, "#symbol");
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_this() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  String str;
+}
+''');
+    final code = r"""
+<h1 [hidden]="this"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, code, "this");
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_throw() async {
+    _addDartSource(r'''
+@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
+class TestPanel {
+  String str;
+}
+''');
+    final code = r"""
+<h1 [hidden]="throw str"></h1>
+""";
+    _addHtmlSource(code);
+    await _resolveSingleTemplate(dartSource);
+    assertErrorInCodeAtPosition(
+        AngularWarningCode.DISALLOWED_EXPRESSION, code, "throw str");
+  }
+
+  // ignore: non_constant_identifier_names
+  Future test_expressionNotAllowed_typedList() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
 class TestPanel {
@@ -2379,7 +2518,7 @@
   }
 
   // ignore: non_constant_identifier_names
-  Future test_expression_typed_map_not_allowed() async {
+  Future test_expressionNotAllowed_typedMap() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
 class TestPanel {
@@ -2525,6 +2664,7 @@
     _assertElement("item").local.at('item [');
   }
 
+  // ignore: non_constant_identifier_names
   Future test_letVariable_in_nonTemplate() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -2539,6 +2679,7 @@
         'let-value');
   }
 
+  // ignore: non_constant_identifier_names
   Future test_localVariable_camelCaseName() async {
     _addDartSource(r'''
 import 'dart:html';
@@ -2563,6 +2704,7 @@
     _assertElement("myTargetElement.someString)").local.at("myTargetElement>");
   }
 
+  // ignore: non_constant_identifier_names
   Future test_localVariable_exportAs() async {
     _addDartSource(r'''
 @Directive(selector: '[myDirective]', exportAs: 'exportedValue')
@@ -3280,6 +3422,31 @@
   }
 
   // ignore: non_constant_identifier_names
+//  Future test_ngFor_variousKinds_useLowerIdentifier() async {
+//    _addDartSource(r'''
+//@Component(selector: 'test-panel')
+//@View(templateUrl: 'test_panel.html', directives: const [NgFor])
+//class TestPanel {
+//  List<String> items = [];
+//}
+//''');
+//    _addHtmlSource(r"""
+//<template ngFor let-item1 [ngForOf]='items' let-i='index' {{lowerEl}}>
+//  {{item1.length}}
+//</template>
+//<li template="ngFor let item2 of items; let i=index" {{lowerEl}}>
+//  {{item2.length}}
+//</li>
+//<li *ngFor="let item3 of items; let i=index" {{lowerEl}}>
+//  {{item3.length}}
+//</li>
+//<div #lowerEl></div>
+//""");
+//    await _resolveSingleTemplate(dartSource);
+//    errorListener.assertNoErrors();
+//  }
+
+  // ignore: non_constant_identifier_names
   Future test_resolveTemplate_customTagNames() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html',
@@ -3339,31 +3506,6 @@
   }
 
   // ignore: non_constant_identifier_names
-//  Future test_ngFor_variousKinds_useLowerIdentifier() async {
-//    _addDartSource(r'''
-//@Component(selector: 'test-panel')
-//@View(templateUrl: 'test_panel.html', directives: const [NgFor])
-//class TestPanel {
-//  List<String> items = [];
-//}
-//''');
-//    _addHtmlSource(r"""
-//<template ngFor let-item1 [ngForOf]='items' let-i='index' {{lowerEl}}>
-//  {{item1.length}}
-//</template>
-//<li template="ngFor let item2 of items; let i=index" {{lowerEl}}>
-//  {{item2.length}}
-//</li>
-//<li *ngFor="let item3 of items; let i=index" {{lowerEl}}>
-//  {{item3.length}}
-//</li>
-//<div #lowerEl></div>
-//""");
-//    await _resolveSingleTemplate(dartSource);
-//    errorListener.assertNoErrors();
-//  }
-
-  // ignore: non_constant_identifier_names
   Future test_resolveTemplate_exportsCantUsePrefixes() async {
     newSource('/prefixed.dart', 'const int prefixRequired = 1;');
     _addDartSource(r'''
@@ -3427,9 +3569,18 @@
 class TestPanel {
   static void componentStatic() {
   }
+  local();
+  int get getter => null;
+  set setter(int x) => null;
+  int field = null;
 }
 ''');
     final code = r'''
+methods/getters/setters on current class ok:
+{{local()}}
+{{getter}}
+{{field}}
+<div (click)="setter = null"></div>
 static on current class ok:
 {{TestPanel.componentStatic()}}
 exports ok:
@@ -3444,7 +3595,7 @@
 ''';
     _addHtmlSource(code);
     await _resolveSingleTemplate(dartSource);
-    expect(ranges, hasLength(18));
+    expect(ranges, hasLength(23));
     _assertElement('TestPanel').dart.at('TestPanel {');
     _assertElement('componentStatic').dart.method.at('componentStatic() {');
     _assertElement('myAccessor').dart.getter.at('myAccessor = 1');
@@ -3492,7 +3643,6 @@
     ]);
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_noDashesAroundTranscludedContent_stillError() async {
@@ -3514,7 +3664,6 @@
         code, "shouldn't be allowed");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_noDashesAroundTranscludedContent_stillMatchesTag() async {
@@ -3586,24 +3735,22 @@
 ''';
     _addHtmlSource(code);
     await _resolveSingleTemplate(dartSource);
-    expect(ranges, hasLength(0));
     errorListener.assertErrorsWithCodes([
-      StaticWarningCode.UNDEFINED_IDENTIFIER,
-      StaticWarningCode.UNDEFINED_IDENTIFIER,
-      StaticWarningCode.UNDEFINED_IDENTIFIER,
-      StaticTypeWarningCode.UNDEFINED_METHOD,
-      StaticWarningCode.UNDEFINED_IDENTIFIER,
-      StaticWarningCode.UNDEFINED_IDENTIFIER,
-      StaticWarningCode.UNDEFINED_IDENTIFIER,
-      StaticWarningCode.UNDEFINED_IDENTIFIER,
-      StaticWarningCode.UNDEFINED_IDENTIFIER,
-      StaticWarningCode.UNDEFINED_IDENTIFIER,
-      StaticWarningCode.UNDEFINED_IDENTIFIER,
-      StaticWarningCode.UNDEFINED_IDENTIFIER,
+      AngularWarningCode.IDENTIFIER_NOT_EXPORTED,
+      AngularWarningCode.IDENTIFIER_NOT_EXPORTED,
+      AngularWarningCode.IDENTIFIER_NOT_EXPORTED,
+      AngularWarningCode.IDENTIFIER_NOT_EXPORTED,
+      AngularWarningCode.IDENTIFIER_NOT_EXPORTED,
+      AngularWarningCode.IDENTIFIER_NOT_EXPORTED,
+      AngularWarningCode.IDENTIFIER_NOT_EXPORTED,
+      AngularWarningCode.IDENTIFIER_NOT_EXPORTED,
+      AngularWarningCode.IDENTIFIER_NOT_EXPORTED,
+      AngularWarningCode.IDENTIFIER_NOT_EXPORTED,
+      AngularWarningCode.IDENTIFIER_NOT_EXPORTED,
+      AngularWarningCode.IDENTIFIER_NOT_EXPORTED,
     ]);
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentChildLetBound_componentNotElement() async {
@@ -3633,7 +3780,6 @@
         "<some-component #contentChild></some-component>");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentChildLetBound_componentNotElementRef() async {
@@ -3662,7 +3808,6 @@
         "<some-component #contentChild></some-component>");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentChildLetBound_componentNotTemplateRef() async {
@@ -3691,7 +3836,6 @@
         "<some-component #contentChild></some-component>");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentChildLetBound_directiveNotElement() async {
@@ -3721,7 +3865,6 @@
         "<div some-directive #contentChild=\"theDirective\"></div>");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentChildLetBound_directiveNotElement_deeplyNested() async {
@@ -3759,7 +3902,6 @@
         "<div some-directive #contentChild=\"theDirective\"></div>");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentChildLetBound_directiveNotElementRef() async {
@@ -3788,7 +3930,6 @@
         "<div some-directive #contentChild=\"theDirective\"></div>");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentChildLetBound_directiveNotTemplateRef() async {
@@ -3817,7 +3958,6 @@
         "<div some-directive #contentChild></div>");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentChildLetBound_element_directiveNotExported() async {
@@ -3846,7 +3986,6 @@
         "<div some-directive #contentChild></div>");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentChildLetBound_elementNotComponent() async {
@@ -3875,7 +4014,6 @@
         "<div #contentChild></div>");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentChildLetBound_elementNotDirective() async {
@@ -3904,7 +4042,6 @@
         "<div #contentChild></div>");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentChildLetBound_elementNotTemplateRef() async {
@@ -3930,7 +4067,6 @@
         "<div #contentChild></div>");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentChildLetBound_readValueIsAlwaysOk() async {
@@ -3953,8 +4089,6 @@
     errorListener.assertNoErrors();
   }
 
-  // see https://github.com/dart-lang/html/issues/44
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentChildLetBound_templateNotComponent() async {
@@ -3983,7 +4117,6 @@
         "<template #contentChild></template>");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentChildLetBound_templateNotDirective() async {
@@ -4012,7 +4145,6 @@
         "<template #contentChild></template>");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentChildLetBound_templateNotElement() async {
@@ -4039,7 +4171,6 @@
         "<template #contentChild></template>");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentChildLetBound_templateNotElementRef() async {
@@ -4065,7 +4196,6 @@
         "<template #contentChild></template>");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentChildLetBound_wrongComponent() async {
@@ -4098,7 +4228,6 @@
         "<some-other-component #contentChild></some-other-component>");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentChildLetBound_wrongDirective() async {
@@ -4150,7 +4279,6 @@
     errorListener.assertNoErrors();
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentMatchingHigherComponentsIsStillNotTranscludedError() async {
@@ -4203,7 +4331,6 @@
     errorListener.assertNoErrors();
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentMatchingSelectorsAndAllKnowsTag() async {
@@ -4249,7 +4376,6 @@
     errorListener.assertNoErrors();
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentMatchingSelectorsReportsUnknownTag() async {
@@ -4332,7 +4458,6 @@
         AngularWarningCode.CONTENT_NOT_TRANSCLUDED, code, "<div></div>");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentNotMatchingSelectorsButMatchesContentChildElement() async {
@@ -4357,7 +4482,6 @@
     errorListener.assertNoErrors();
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentNotMatchingSelectorsButMatchesContentChildElementRef() async {
@@ -4477,7 +4601,6 @@
         code, "<template></template>");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentNotMatchingSelectorsOrContentChildTemplateRef() async {
@@ -4502,7 +4625,6 @@
         AngularWarningCode.CONTENT_NOT_TRANSCLUDED, code, "<div></div>");
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_resolveTemplate_provideContentNoTransclusionsButMatchesContentChildDirective() async {
@@ -4767,6 +4889,7 @@
         AngularWarningCode.CONTENT_NOT_TRANSCLUDED, code, "<div></div>");
   }
 
+  // ignore: non_constant_identifier_names
   Future test_resolveTemplate_provideContentWhereInvalid() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html',
@@ -4786,6 +4909,7 @@
         AngularWarningCode.CONTENT_NOT_TRANSCLUDED, code, "doesn't belong");
   }
 
+  // ignore: non_constant_identifier_names
   Future test_resolveTemplate_provideDuplicateContentChildError() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html',
@@ -4812,6 +4936,7 @@
         "<div second></div>");
   }
 
+  // ignore: non_constant_identifier_names
   Future test_resolveTemplate_provideDuplicateContentChildNestedOk() async {
     _addDartSource(r'''
 import 'dart:html';
@@ -4837,6 +4962,7 @@
     errorListener.assertNoErrors();
   }
 
+  // ignore: non_constant_identifier_names
   Future test_resolveTemplate_provideDuplicateContentChildrenOk() async {
     _addDartSource(r'''
 import 'dart:html';
@@ -4861,6 +4987,7 @@
     errorListener.assertNoErrors();
   }
 
+  // ignore: non_constant_identifier_names
   Future test_resolveTemplate_provideTextInfosDontMatchSelectors() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html',
@@ -4881,6 +5008,7 @@
         AngularWarningCode.CONTENT_NOT_TRANSCLUDED, code, "doesn't belong");
   }
 
+  // ignore: non_constant_identifier_names
   Future test_resolveTemplate_resolvingBogusImportDoesntCrash() async {
     _addDartSource(r'''
 import ; // synthetic import
@@ -4930,6 +5058,7 @@
         "<template second></template>");
   }
 
+  // ignore: non_constant_identifier_names
   Future test_resolveTemplateWithNgContent_emptySelectorError() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -4948,6 +5077,7 @@
         AngularWarningCode.CANNOT_PARSE_SELECTOR, code, "\"\"");
   }
 
+  // ignore: non_constant_identifier_names
   Future test_resolveTemplateWithNgContent_hasContentsError() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -4969,6 +5099,7 @@
     ]);
   }
 
+  // ignore: non_constant_identifier_names
   Future test_resolveTemplateWithNgContent_noSelectorIsNull() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -4986,6 +5117,7 @@
     expect(template.view.component.ngContents.first.selector, isNull);
   }
 
+  // ignore: non_constant_identifier_names
   Future test_resolveTemplateWithNgContent_noValueError() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -5004,6 +5136,7 @@
         AngularWarningCode.CANNOT_PARSE_SELECTOR, code, "select");
   }
 
+  // ignore: non_constant_identifier_names
   Future test_resolveTemplateWithNgContent_selectorParseError() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -5022,6 +5155,7 @@
         AngularWarningCode.CANNOT_PARSE_SELECTOR, code, "+");
   }
 
+  // ignore: non_constant_identifier_names
   Future test_resolveTemplateWithNgContentTracksSelectors() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -5038,6 +5172,7 @@
     expect(template.view.component.ngContents, hasLength(1));
   }
 
+  // ignore: non_constant_identifier_names
   Future test_standardHtmlComponent() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -5062,6 +5197,7 @@
     expect(ranges, hasLength(8));
   }
 
+  // ignore: non_constant_identifier_names
   Future test_standardHtmlComponentUsingRef() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -5086,6 +5222,7 @@
     expect(ranges, hasLength(8));
   }
 
+  // ignore: non_constant_identifier_names
   Future test_star_selectTemplateFunctionalDirectiveMatches() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html',
@@ -5103,6 +5240,7 @@
     errorListener.assertNoErrors();
   }
 
+  // ignore: non_constant_identifier_names
   Future test_star_selectTemplateMatches() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html',
@@ -5122,6 +5260,7 @@
     errorListener.assertNoErrors();
   }
 
+  // ignore: non_constant_identifier_names
   Future test_starNoDirectives() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html',
@@ -5138,6 +5277,7 @@
         AngularWarningCode.TEMPLATE_ATTR_NOT_USED, code, "*foo");
   }
 
+  // ignore: non_constant_identifier_names
   Future test_statement_eventBinding_all_semicolons() async {
     _addDartSource(r'''
 import 'dart:html';
@@ -5155,6 +5295,7 @@
     errorListener.assertNoErrors();
   }
 
+  // ignore: non_constant_identifier_names
   Future test_statement_eventBinding_double_statement() async {
     _addDartSource(r'''
 import 'dart:html';
@@ -5172,6 +5313,7 @@
     _assertElement('handleClick').dart.method.at('handleClick(MouseEvent');
   }
 
+  // ignore: non_constant_identifier_names
   Future test_statement_eventBinding_error_on_assignment_statement() async {
     _addDartSource(r'''
 import 'dart:html';
@@ -5192,6 +5334,7 @@
         "String s");
   }
 
+  // ignore: non_constant_identifier_names
   Future test_statement_eventBinding_error_on_second_statement() async {
     _addDartSource(r'''
 import 'dart:html';
@@ -5210,6 +5353,7 @@
         StaticTypeWarningCode.UNDEFINED_METHOD, code, "unknownFunction");
   }
 
+  // ignore: non_constant_identifier_names
   Future test_statement_eventBinding_if_statement_with_semicolon() async {
     _addDartSource(r'''
 import 'dart:html';
@@ -5228,6 +5372,7 @@
         "if(true){}");
   }
 
+  // ignore: non_constant_identifier_names
   Future test_statement_eventBinding_if_statement_without_semicolon() async {
     _addDartSource(r'''
 import 'dart:html';
@@ -5246,6 +5391,7 @@
         "if(true){}");
   }
 
+  // ignore: non_constant_identifier_names
   Future test_statement_eventBinding_return_statement_with_semicolon() async {
     _addDartSource(r'''
 import 'dart:html';
@@ -5284,6 +5430,7 @@
         "return 5");
   }
 
+  // ignore: non_constant_identifier_names
   Future test_statement_eventBinding_single_statement_with_semicolon() async {
     _addDartSource(r'''
 import 'dart:html';
@@ -5301,7 +5448,6 @@
     errorListener.assertNoErrors();
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_statement_eventBinding_single_statement_without_semicolon() async {
@@ -5340,7 +5486,6 @@
     errorListener.assertNoErrors();
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_statement_eventBinding_typechecking_after_unexpected_bracket() async {
@@ -5364,6 +5509,7 @@
     ]);
   }
 
+  // ignore: non_constant_identifier_names
   Future test_statement_eventBinding_typeError() async {
     _addDartSource(r'''
 import 'dart:html';
@@ -5382,7 +5528,6 @@
         StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, code, '"asdf"');
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_statement_eventBinding_unexpected_closing_brackets_at_end() async {
@@ -5402,7 +5547,6 @@
     assertErrorInCodeAtPosition(ParserErrorCode.UNEXPECTED_TOKEN, code, '}}}}');
   }
 
-  // ignore: non_constant_identifier_names
   Future
       // ignore: non_constant_identifier_names
       test_statement_eventBinding_unexpected_closing_brackets_at_start() async {
@@ -5423,23 +5567,6 @@
   }
 
   // ignore: non_constant_identifier_names
-  Future test_statements_assignment_not_allowed() async {
-    _addDartSource(r'''
-@Component(selector: 'test-panel', templateUrl: 'test_panel.html')
-class TestPanel {
-  String str;
-}
-''');
-    final code = r"""
-<h1 #h1 (click)="h1 = 4"></h1>
-""";
-    _addHtmlSource(code);
-    await _resolveSingleTemplate(dartSource);
-    assertErrorInCodeAtPosition(
-        AngularWarningCode.DISALLOWED_EXPRESSION, code, "h1 = 4");
-  }
-
-  // ignore: non_constant_identifier_names
   Future test_statements_setter_allowed() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel', templateUrl: 'test_panel.html')
@@ -5565,6 +5692,7 @@
         AngularWarningCode.TEMPLATE_ATTR_NOT_USED, code, 'template');
   }
 
+  // ignore: non_constant_identifier_names
   Future test_templateTag_selectTemplateMatches() async {
     _addDartSource(r'''
 @Component(selector: 'test-panel' templateUrl: 'test_panel.html',