MCPcopy Index your code
hub / github.com/angular/angular / TcbExpressionTranslator

Class TcbExpressionTranslator

packages/compiler/src/typecheck/ops/expression.ts:102–282  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

100}
101
102export class TcbExpressionTranslator {
103 constructor(
104 protected tcb: Context,
105 protected scope: Scope,
106 ) {}
107
108 translate(ast: AST): TcbExpr {
109 // `astToTcbExpr` actually does the conversion. A special resolver `tcbResolve` is passed
110 // which interprets specific expression nodes that interact with the `ImplicitReceiver`. These
111 // nodes actually refer to identifiers within the current scope.
112 return astToTcbExpr(ast, (ast: AST) => this.resolve(ast), this.tcb.env.config);
113 }
114
115 /**
116 * Resolve an `AST` expression within the given scope.
117 *
118 * Some `AST` expressions refer to top-level concepts (references, variables, the component
119 * context). This method assists in resolving those.
120 */
121 protected resolve(ast: AST): TcbExpr | null {
122 if (ast instanceof PropertyRead && ast.receiver instanceof ImplicitReceiver) {
123 // Try to resolve a bound target for this expression. If no such target is available, then
124 // the expression is referencing the top-level component context. In that case, `null` is
125 // returned here to let it fall through resolution so it will be caught when the
126 // `ImplicitReceiver` is resolved in the branch below.
127 const target = this.tcb.boundTarget.getExpressionTarget(ast);
128 const targetExpression = target === null ? null : this.getTargetNodeExpression(target, ast);
129 if (target instanceof LetDeclaration && !this.isValidLetDeclarationAccess(target, ast)) {
130 this.tcb.oobRecorder.letUsedBeforeDefinition(this.tcb.id, ast, target);
131 // Cast the expression to `any` so we don't produce additional diagnostics.
132 // We don't use `markIgnoreForDiagnostics` here, because it won't prevent duplicate
133 // diagnostics for nested accesses in cases like `@let value = value.foo.bar.baz`.
134 if (targetExpression !== null) {
135 return new TcbExpr(`${targetExpression.print()} as any`);
136 }
137 }
138 return targetExpression;
139 } else if (
140 ast instanceof Binary &&
141 Binary.isAssignmentOperation(ast.operation) &&
142 ast.left instanceof PropertyRead &&
143 (ast.left.receiver instanceof ImplicitReceiver || ast.left.receiver instanceof ThisReceiver)
144 ) {
145 const read = ast.left;
146 const target = this.tcb.boundTarget.getExpressionTarget(read);
147 if (target === null) {
148 return null;
149 }
150
151 const targetExpression = this.getTargetNodeExpression(target, read);
152 const expr = this.translate(ast.right);
153 const result = new TcbExpr(`(${targetExpression.print()} = ${expr.print()})`);
154 result.addParseSpanInfo(read.sourceSpan);
155
156 // Ignore diagnostics from TS produced for writes to `@let` and re-report them using
157 // our own infrastructure. We can't rely on the TS reporting, because it includes
158 // the name of the auto-generated TCB variable name.
159 if (target instanceof LetDeclaration) {

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…