refactor(compiler-cli): use keySpan for output event lookup (#39515)
PR #39665 added the `keySpan` to the output field access so we no longer need to get there from the call expression and can instead just find the node we want directly. PR Close #39515
This commit is contained in:
parent
29298f4f3d
commit
702d6bfe8f
|
@ -18,7 +18,6 @@ import {DirectiveSymbol, DomBindingSymbol, ElementSymbol, ExpressionSymbol, Inpu
|
||||||
import {ExpressionIdentifier, findAllMatchingNodes, findFirstMatchingNode, hasExpressionIdentifier} from './comments';
|
import {ExpressionIdentifier, findAllMatchingNodes, findFirstMatchingNode, hasExpressionIdentifier} from './comments';
|
||||||
import {TemplateData} from './context';
|
import {TemplateData} from './context';
|
||||||
import {isAccessExpression} from './ts_util';
|
import {isAccessExpression} from './ts_util';
|
||||||
import {TcbDirectiveOutputsOp} from './type_check_block';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates and caches `Symbol`s for various template structures for a given component.
|
* Generates and caches `Symbol`s for various template structures for a given component.
|
||||||
|
@ -169,9 +168,9 @@ export class SymbolBuilder {
|
||||||
// Outputs are a `ts.CallExpression` that look like one of the two:
|
// Outputs are a `ts.CallExpression` that look like one of the two:
|
||||||
// * _outputHelper(_t1["outputField"]).subscribe(handler);
|
// * _outputHelper(_t1["outputField"]).subscribe(handler);
|
||||||
// * _t1.addEventListener(handler);
|
// * _t1.addEventListener(handler);
|
||||||
const node = findFirstMatchingNode(
|
const outputFieldAccess = findFirstMatchingNode(
|
||||||
this.typeCheckBlock, {withSpan: eventBinding.sourceSpan, filter: ts.isCallExpression});
|
this.typeCheckBlock, {withSpan: eventBinding.keySpan, filter: isAccessExpression});
|
||||||
if (node === null) {
|
if (outputFieldAccess === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,12 +180,12 @@ export class SymbolBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (consumer instanceof TmplAstTemplate || consumer instanceof TmplAstElement) {
|
if (consumer instanceof TmplAstTemplate || consumer instanceof TmplAstElement) {
|
||||||
if (!ts.isPropertyAccessExpression(node.expression) ||
|
if (!ts.isPropertyAccessExpression(outputFieldAccess) ||
|
||||||
node.expression.name.text !== 'addEventListener') {
|
outputFieldAccess.name.text !== 'addEventListener') {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const addEventListener = node.expression.name;
|
const addEventListener = outputFieldAccess.name;
|
||||||
const tsSymbol = this.getTypeChecker().getSymbolAtLocation(addEventListener);
|
const tsSymbol = this.getTypeChecker().getSymbolAtLocation(addEventListener);
|
||||||
const tsType = this.getTypeChecker().getTypeAtLocation(addEventListener);
|
const tsType = this.getTypeChecker().getTypeAtLocation(addEventListener);
|
||||||
const positionInShimFile = this.getShimPositionForNode(addEventListener);
|
const positionInShimFile = this.getShimPositionForNode(addEventListener);
|
||||||
|
@ -207,11 +206,9 @@ export class SymbolBuilder {
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
const outputFieldAccess = TcbDirectiveOutputsOp.decodeOutputCallExpression(node);
|
if (!ts.isElementAccessExpression(outputFieldAccess)) {
|
||||||
if (outputFieldAccess === null) {
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tsSymbol =
|
const tsSymbol =
|
||||||
this.getTypeChecker().getSymbolAtLocation(outputFieldAccess.argumentExpression);
|
this.getTypeChecker().getSymbolAtLocation(outputFieldAccess.argumentExpression);
|
||||||
if (tsSymbol === undefined) {
|
if (tsSymbol === undefined) {
|
||||||
|
@ -225,7 +222,7 @@ export class SymbolBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
const positionInShimFile = this.getShimPositionForNode(outputFieldAccess);
|
const positionInShimFile = this.getShimPositionForNode(outputFieldAccess);
|
||||||
const tsType = this.getTypeChecker().getTypeAtLocation(node);
|
const tsType = this.getTypeChecker().getTypeAtLocation(outputFieldAccess);
|
||||||
return {
|
return {
|
||||||
kind: SymbolKind.Output,
|
kind: SymbolKind.Output,
|
||||||
bindings: [{
|
bindings: [{
|
||||||
|
|
|
@ -902,39 +902,6 @@ export class TcbDirectiveOutputsOp extends TcbOp {
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Outputs are a `ts.CallExpression` that look like one of the two:
|
|
||||||
* - `_outputHelper(_t1["outputField"]).subscribe(handler);`
|
|
||||||
* - `_t1.addEventListener(handler);`
|
|
||||||
* This method reverses the operations to create a call expression for a directive output.
|
|
||||||
* It unpacks the given call expression and returns the original element access (i.e.
|
|
||||||
* `_t1["outputField"]` in the example above). Returns `null` if the given call expression is not
|
|
||||||
* the expected structure of an output binding
|
|
||||||
*/
|
|
||||||
static decodeOutputCallExpression(node: ts.CallExpression): ts.ElementAccessExpression|null {
|
|
||||||
// `node.expression` === `_outputHelper(_t1["outputField"]).subscribe` or `_t1.addEventListener`
|
|
||||||
if (!ts.isPropertyAccessExpression(node.expression) ||
|
|
||||||
node.expression.name.text === 'addEventListener') {
|
|
||||||
// `addEventListener` outputs do not have an `ElementAccessExpression` for the output field.
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ts.isCallExpression(node.expression.expression)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// `node.expression.expression` === `_outputHelper(_t1["outputField"])`
|
|
||||||
if (node.expression.expression.arguments.length === 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const [outputFieldAccess] = node.expression.expression.arguments;
|
|
||||||
if (!ts.isElementAccessExpression(outputFieldAccess)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return outputFieldAccess;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -984,8 +951,10 @@ class TcbUnclaimedOutputsOp extends TcbOp {
|
||||||
if (elId === null) {
|
if (elId === null) {
|
||||||
elId = this.scope.resolve(this.element);
|
elId = this.scope.resolve(this.element);
|
||||||
}
|
}
|
||||||
|
const propertyAccess = ts.createPropertyAccess(elId, 'addEventListener');
|
||||||
|
addParseSpanInfo(propertyAccess, output.keySpan);
|
||||||
const call = ts.createCall(
|
const call = ts.createCall(
|
||||||
/* expression */ ts.createPropertyAccess(elId, 'addEventListener'),
|
/* expression */ propertyAccess,
|
||||||
/* typeArguments */ undefined,
|
/* typeArguments */ undefined,
|
||||||
/* arguments */[ts.createStringLiteral(output.name), handler]);
|
/* arguments */[ts.createStringLiteral(output.name), handler]);
|
||||||
addParseSpanInfo(call, output.sourceSpan);
|
addParseSpanInfo(call, output.sourceSpan);
|
||||||
|
|
Loading…
Reference in New Issue