anchor.diff:  /// be needed to evaluate a single expression at runtime.
   class _SubExpressionVisitor extends pe.RecursiveVisitor {
     final SmokeCodeGenerator generator;
  +  final TransformLogger logger;
     bool _includeSetter;
  -
  -  _SubExpressionVisitor(this.generator);
  +  Span _currentSpan;
  +
  +  _SubExpressionVisitor(this.generator, this.logger);
   
     /// Visit [exp], and record getters and setters that are needed in order to
     /// evaluate it at runtime. [includeSetter] is only true if this expression
     /// occured in a context where it could be updated, for example in two-way
     /// bindings such as `<input value={{exp}}>`.
  -  void run(pe.Expression exp, bool includeSetter) {
  +  void run(pe.Expression exp, bool includeSetter, span) {
  +    _currentSpan = span;
       _includeSetter = includeSetter;
       visit(exp);
     }
   
     /// Adds a getter and symbol for [name], and optionally a setter.
     _add(String name) {
  +    if (name.startsWith('_')) {
  +      logger.warning('private symbols are not supported', span: _currentSpan);
  +      return;
  +    }
       generator.addGetter(name);
       generator.addSymbol(name);
       if (_includeSetter) generator.addSetter(name);
  
positive.code:   final TransformLogger logger;
    bool _inTemplate = false;
  
    _HtmlExtractor(this.logger, SmokeCodeGenerator generator,
        this.publishedAttributes)
        : generator = generator,
          visitor = new _SubExpressionVisitor(generator);
  
    void visitElement(Element node) {
      if (_inTemplate) _processNormalElement(node);
  
negative.code:       }
  
        if (stringExpression == '') return;
        if (stringExpression.startsWith('_')) {
          logger.warning('private symbols cannot be used in event handlers',
              span: span);
          return;
        }
        generator.addGetter(stringExpression);
        generator.addSymbol(stringExpression);
      }
      visitor.run(pe.parse(stringExpression), isTwoWay, span);
    }
  }
  
  