BREAKING CHANGE:
- Renderer:
  * renderComponent method is removed form `Renderer`, only present on `RootRenderer`
  * Renderer.setDebugInfo is removed. Renderer.createElement / createText / createTemplateAnchor
    now take the DebugInfo directly.
- Query semantics:
  * Queries don't work with dynamically loaded components.
  * e.g. for router-outlet: loaded components can't be queries via @ViewQuery,
    but router-outlet emits an event `activate` now that emits the activated component
- Exception classes and the context inside changed (renamed fields)
- DebugElement.attributes is an Object and not a Map in JS any more
- ChangeDetectorGenConfig was renamed into CompilerConfig
- AppViewManager.createEmbeddedViewInContainer / AppViewManager.createHostViewInContainer
  are removed, use the methods in ViewContainerRef instead
- Change detection order changed:
  * 1. dirty check component inputs
  * 2. dirty check content children
  * 3. update render nodes
Closes #6301
Closes #6567
		
	
			
		
			
				
	
	
		
			197 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			197 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import {
 | 
						|
  AST,
 | 
						|
  AstVisitor,
 | 
						|
  PropertyRead,
 | 
						|
  PropertyWrite,
 | 
						|
  Binary,
 | 
						|
  Chain,
 | 
						|
  Conditional,
 | 
						|
  EmptyExpr,
 | 
						|
  BindingPipe,
 | 
						|
  FunctionCall,
 | 
						|
  ImplicitReceiver,
 | 
						|
  Interpolation,
 | 
						|
  KeyedRead,
 | 
						|
  KeyedWrite,
 | 
						|
  LiteralArray,
 | 
						|
  LiteralMap,
 | 
						|
  LiteralPrimitive,
 | 
						|
  MethodCall,
 | 
						|
  PrefixNot,
 | 
						|
  Quote,
 | 
						|
  SafePropertyRead,
 | 
						|
  SafeMethodCall
 | 
						|
} from 'angular2/src/compiler/expression_parser/ast';
 | 
						|
 | 
						|
 | 
						|
import {StringWrapper, isPresent, isString} from 'angular2/src/facade/lang';
 | 
						|
 | 
						|
export class Unparser implements AstVisitor {
 | 
						|
  private static _quoteRegExp = /"/g;
 | 
						|
  private _expression: string;
 | 
						|
 | 
						|
  unparse(ast: AST) {
 | 
						|
    this._expression = '';
 | 
						|
    this._visit(ast);
 | 
						|
    return this._expression;
 | 
						|
  }
 | 
						|
 | 
						|
  visitPropertyRead(ast: PropertyRead, context: any) {
 | 
						|
    this._visit(ast.receiver);
 | 
						|
    this._expression += ast.receiver instanceof ImplicitReceiver ? `${ast.name}` : `.${ast.name}`;
 | 
						|
  }
 | 
						|
 | 
						|
  visitPropertyWrite(ast: PropertyWrite, context: any) {
 | 
						|
    this._visit(ast.receiver);
 | 
						|
    this._expression +=
 | 
						|
        ast.receiver instanceof ImplicitReceiver ? `${ast.name} = ` : `.${ast.name} = `;
 | 
						|
    this._visit(ast.value);
 | 
						|
  }
 | 
						|
 | 
						|
  visitBinary(ast: Binary, context: any) {
 | 
						|
    this._visit(ast.left);
 | 
						|
    this._expression += ` ${ast.operation} `;
 | 
						|
    this._visit(ast.right);
 | 
						|
  }
 | 
						|
 | 
						|
  visitChain(ast: Chain, context: any) {
 | 
						|
    var len = ast.expressions.length;
 | 
						|
    for (let i = 0; i < len; i++) {
 | 
						|
      this._visit(ast.expressions[i]);
 | 
						|
      this._expression += i == len - 1 ? ';' : '; ';
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  visitConditional(ast: Conditional, context: any) {
 | 
						|
    this._visit(ast.condition);
 | 
						|
    this._expression += ' ? ';
 | 
						|
    this._visit(ast.trueExp);
 | 
						|
    this._expression += ' : ';
 | 
						|
    this._visit(ast.falseExp);
 | 
						|
  }
 | 
						|
 | 
						|
  visitPipe(ast: BindingPipe, context: any) {
 | 
						|
    this._expression += '(';
 | 
						|
    this._visit(ast.exp);
 | 
						|
    this._expression += ` | ${ast.name}`;
 | 
						|
    ast.args.forEach(arg => {
 | 
						|
      this._expression += ':';
 | 
						|
      this._visit(arg);
 | 
						|
    });
 | 
						|
    this._expression += ')';
 | 
						|
  }
 | 
						|
 | 
						|
  visitFunctionCall(ast: FunctionCall, context: any) {
 | 
						|
    this._visit(ast.target);
 | 
						|
    this._expression += '(';
 | 
						|
    var isFirst = true;
 | 
						|
    ast.args.forEach(arg => {
 | 
						|
      if (!isFirst) this._expression += ', ';
 | 
						|
      isFirst = false;
 | 
						|
      this._visit(arg);
 | 
						|
    });
 | 
						|
    this._expression += ')';
 | 
						|
  }
 | 
						|
 | 
						|
  visitImplicitReceiver(ast: ImplicitReceiver, context: any) {}
 | 
						|
 | 
						|
  visitInterpolation(ast: Interpolation, context: any) {
 | 
						|
    for (let i = 0; i < ast.strings.length; i++) {
 | 
						|
      this._expression += ast.strings[i];
 | 
						|
      if (i < ast.expressions.length) {
 | 
						|
        this._expression += '{{ ';
 | 
						|
        this._visit(ast.expressions[i]);
 | 
						|
        this._expression += ' }}';
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  visitKeyedRead(ast: KeyedRead, context: any) {
 | 
						|
    this._visit(ast.obj);
 | 
						|
    this._expression += '[';
 | 
						|
    this._visit(ast.key);
 | 
						|
    this._expression += ']';
 | 
						|
  }
 | 
						|
 | 
						|
  visitKeyedWrite(ast: KeyedWrite, context: any) {
 | 
						|
    this._visit(ast.obj);
 | 
						|
    this._expression += '[';
 | 
						|
    this._visit(ast.key);
 | 
						|
    this._expression += '] = ';
 | 
						|
    this._visit(ast.value);
 | 
						|
  }
 | 
						|
 | 
						|
  visitLiteralArray(ast: LiteralArray, context: any) {
 | 
						|
    this._expression += '[';
 | 
						|
    var isFirst = true;
 | 
						|
    ast.expressions.forEach(expression => {
 | 
						|
      if (!isFirst) this._expression += ', ';
 | 
						|
      isFirst = false;
 | 
						|
      this._visit(expression);
 | 
						|
    });
 | 
						|
 | 
						|
    this._expression += ']';
 | 
						|
  }
 | 
						|
 | 
						|
  visitLiteralMap(ast: LiteralMap, context: any) {
 | 
						|
    this._expression += '{';
 | 
						|
    var isFirst = true;
 | 
						|
    for (let i = 0; i < ast.keys.length; i++) {
 | 
						|
      if (!isFirst) this._expression += ', ';
 | 
						|
      isFirst = false;
 | 
						|
      this._expression += `${ast.keys[i]}: `;
 | 
						|
      this._visit(ast.values[i]);
 | 
						|
    }
 | 
						|
 | 
						|
    this._expression += '}';
 | 
						|
  }
 | 
						|
 | 
						|
  visitLiteralPrimitive(ast: LiteralPrimitive, context: any) {
 | 
						|
    if (isString(ast.value)) {
 | 
						|
      this._expression += `"${StringWrapper.replaceAll(ast.value, Unparser._quoteRegExp, '\"')}"`;
 | 
						|
    } else {
 | 
						|
      this._expression += `${ast.value}`;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  visitMethodCall(ast: MethodCall, context: any) {
 | 
						|
    this._visit(ast.receiver);
 | 
						|
    this._expression += ast.receiver instanceof ImplicitReceiver ? `${ast.name}(` : `.${ast.name}(`;
 | 
						|
    var isFirst = true;
 | 
						|
    ast.args.forEach(arg => {
 | 
						|
      if (!isFirst) this._expression += ', ';
 | 
						|
      isFirst = false;
 | 
						|
      this._visit(arg);
 | 
						|
    });
 | 
						|
    this._expression += ')';
 | 
						|
  }
 | 
						|
 | 
						|
  visitPrefixNot(ast: PrefixNot, context: any) {
 | 
						|
    this._expression += '!';
 | 
						|
    this._visit(ast.expression);
 | 
						|
  }
 | 
						|
 | 
						|
  visitSafePropertyRead(ast: SafePropertyRead, context: any) {
 | 
						|
    this._visit(ast.receiver);
 | 
						|
    this._expression += `?.${ast.name}`;
 | 
						|
  }
 | 
						|
 | 
						|
  visitSafeMethodCall(ast: SafeMethodCall, context: any) {
 | 
						|
    this._visit(ast.receiver);
 | 
						|
    this._expression += `?.${ast.name}(`;
 | 
						|
    var isFirst = true;
 | 
						|
    ast.args.forEach(arg => {
 | 
						|
      if (!isFirst) this._expression += ', ';
 | 
						|
      isFirst = false;
 | 
						|
      this._visit(arg);
 | 
						|
    });
 | 
						|
    this._expression += ')';
 | 
						|
  }
 | 
						|
 | 
						|
  visitQuote(ast: Quote, context: any) {
 | 
						|
    this._expression += `${ast.prefix}:${ast.uninterpretedExpression}`;
 | 
						|
  }
 | 
						|
 | 
						|
  private _visit(ast: AST) { ast.visit(this); }
 | 
						|
}
 |