refactor(ngcc): allow look up of multiple helpers (#33689)
This change is a precursor to finding the end of a class, which needs to search for helpers of many different names. PR Close #33689
This commit is contained in:
parent
c6ebcd1eb9
commit
52d1500155
@ -63,14 +63,14 @@ export class CommonJsReflectionHost extends Esm5ReflectionHost {
|
|||||||
* @param helperName the name of the helper (e.g. `__decorate`) whose calls we are interested in.
|
* @param helperName the name of the helper (e.g. `__decorate`) whose calls we are interested in.
|
||||||
* @returns an array of nodes of calls to the helper with the given name.
|
* @returns an array of nodes of calls to the helper with the given name.
|
||||||
*/
|
*/
|
||||||
protected getHelperCallsForClass(classSymbol: NgccClassSymbol, helperName: string):
|
protected getHelperCallsForClass(classSymbol: NgccClassSymbol, helperNames: string[]):
|
||||||
ts.CallExpression[] {
|
ts.CallExpression[] {
|
||||||
const esm5HelperCalls = super.getHelperCallsForClass(classSymbol, helperName);
|
const esm5HelperCalls = super.getHelperCallsForClass(classSymbol, helperNames);
|
||||||
if (esm5HelperCalls.length > 0) {
|
if (esm5HelperCalls.length > 0) {
|
||||||
return esm5HelperCalls;
|
return esm5HelperCalls;
|
||||||
} else {
|
} else {
|
||||||
const sourceFile = classSymbol.declaration.valueDeclaration.getSourceFile();
|
const sourceFile = classSymbol.declaration.valueDeclaration.getSourceFile();
|
||||||
return this.getTopLevelHelperCalls(sourceFile, helperName);
|
return this.getTopLevelHelperCalls(sourceFile, helperNames);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,16 +81,21 @@ export class CommonJsReflectionHost extends Esm5ReflectionHost {
|
|||||||
* each class in a file.
|
* each class in a file.
|
||||||
*
|
*
|
||||||
* @param sourceFile the source who may contain helper calls.
|
* @param sourceFile the source who may contain helper calls.
|
||||||
* @param helperName the name of the helper (e.g. `__decorate`) whose calls we are interested in.
|
* @param helperNames the names of the helpers (e.g. `__decorate`) whose calls we are interested
|
||||||
|
* in.
|
||||||
* @returns an array of nodes of calls to the helper with the given name.
|
* @returns an array of nodes of calls to the helper with the given name.
|
||||||
*/
|
*/
|
||||||
private getTopLevelHelperCalls(sourceFile: ts.SourceFile, helperName: string):
|
private getTopLevelHelperCalls(sourceFile: ts.SourceFile, helperNames: string[]):
|
||||||
ts.CallExpression[] {
|
ts.CallExpression[] {
|
||||||
|
const calls: ts.CallExpression[] = [];
|
||||||
|
helperNames.forEach(helperName => {
|
||||||
const helperCallsMap = getOrDefault(this.topLevelHelperCalls, helperName, () => new Map());
|
const helperCallsMap = getOrDefault(this.topLevelHelperCalls, helperName, () => new Map());
|
||||||
return getOrDefault(
|
calls.push(...getOrDefault(
|
||||||
helperCallsMap, sourceFile,
|
helperCallsMap, sourceFile,
|
||||||
() => sourceFile.statements.map(statement => this.getHelperCall(statement, helperName))
|
() => sourceFile.statements.map(statement => this.getHelperCall(statement, helperNames))
|
||||||
.filter(isDefined));
|
.filter(isDefined)));
|
||||||
|
});
|
||||||
|
return calls;
|
||||||
}
|
}
|
||||||
|
|
||||||
private computeExportsOfCommonJsModule(sourceFile: ts.SourceFile): Map<string, Declaration> {
|
private computeExportsOfCommonJsModule(sourceFile: ts.SourceFile): Map<string, Declaration> {
|
||||||
|
@ -900,7 +900,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
|||||||
// Note that although the helper calls are retrieved using the class symbol, the result may
|
// Note that although the helper calls are retrieved using the class symbol, the result may
|
||||||
// contain helper calls corresponding with unrelated classes. Therefore, each helper call still
|
// contain helper calls corresponding with unrelated classes. Therefore, each helper call still
|
||||||
// has to be checked to actually correspond with the class symbol.
|
// has to be checked to actually correspond with the class symbol.
|
||||||
const helperCalls = this.getHelperCallsForClass(classSymbol, '__decorate');
|
const helperCalls = this.getHelperCallsForClass(classSymbol, ['__decorate']);
|
||||||
|
|
||||||
for (const helperCall of helperCalls) {
|
for (const helperCall of helperCalls) {
|
||||||
if (isClassDecorateCall(helperCall, classSymbol.name)) {
|
if (isClassDecorateCall(helperCall, classSymbol.name)) {
|
||||||
@ -1065,25 +1065,28 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check the given statement to see if it is a call to the specified helper function or null if
|
* Check the given statement to see if it is a call to any of the specified helper functions or
|
||||||
* not found.
|
* null if not found.
|
||||||
*
|
*
|
||||||
* Matching statements will look like: `tslib_1.__decorate(...);`.
|
* Matching statements will look like: `tslib_1.__decorate(...);`.
|
||||||
* @param statement the statement that may contain the call.
|
* @param statement the statement that may contain the call.
|
||||||
* @param helperName the name of the helper we are looking for.
|
* @param helperNames the names of the helper we are looking for.
|
||||||
* @returns the node that corresponds to the `__decorate(...)` call or null if the statement
|
* @returns the node that corresponds to the `__decorate(...)` call or null if the statement
|
||||||
* does not match.
|
* does not match.
|
||||||
*/
|
*/
|
||||||
protected getHelperCall(statement: ts.Statement, helperName: string): ts.CallExpression|null {
|
protected getHelperCall(statement: ts.Statement, helperNames: string[]): ts.CallExpression|null {
|
||||||
if (ts.isExpressionStatement(statement)) {
|
if (ts.isExpressionStatement(statement)) {
|
||||||
let expression = statement.expression;
|
let expression = statement.expression;
|
||||||
while (isAssignment(expression)) {
|
while (isAssignment(expression)) {
|
||||||
expression = expression.right;
|
expression = expression.right;
|
||||||
}
|
}
|
||||||
if (ts.isCallExpression(expression) && getCalleeName(expression) === helperName) {
|
if (ts.isCallExpression(expression)) {
|
||||||
|
const calleeName = getCalleeName(expression);
|
||||||
|
if (calleeName !== null && helperNames.includes(calleeName)) {
|
||||||
return expression;
|
return expression;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1326,8 +1329,8 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
|||||||
* Get the parameter type and decorators for the constructor of a class,
|
* Get the parameter type and decorators for the constructor of a class,
|
||||||
* where the information is stored on a static property of the class.
|
* where the information is stored on a static property of the class.
|
||||||
*
|
*
|
||||||
* Note that in ESM2015, the property is defined an array, or by an arrow function that returns an
|
* Note that in ESM2015, the property is defined an array, or by an arrow function that returns
|
||||||
* array, of decorator and type information.
|
* an array, of decorator and type information.
|
||||||
*
|
*
|
||||||
* For example,
|
* For example,
|
||||||
*
|
*
|
||||||
@ -1387,14 +1390,14 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
|||||||
/**
|
/**
|
||||||
* Search statements related to the given class for calls to the specified helper.
|
* Search statements related to the given class for calls to the specified helper.
|
||||||
* @param classSymbol the class whose helper calls we are interested in.
|
* @param classSymbol the class whose helper calls we are interested in.
|
||||||
* @param helperName the name of the helper (e.g. `__decorate`) whose calls we are interested
|
* @param helperNames the names of the helpers (e.g. `__decorate`) whose calls we are interested
|
||||||
* in.
|
* in.
|
||||||
* @returns an array of CallExpression nodes for each matching helper call.
|
* @returns an array of CallExpression nodes for each matching helper call.
|
||||||
*/
|
*/
|
||||||
protected getHelperCallsForClass(classSymbol: NgccClassSymbol, helperName: string):
|
protected getHelperCallsForClass(classSymbol: NgccClassSymbol, helperNames: string[]):
|
||||||
ts.CallExpression[] {
|
ts.CallExpression[] {
|
||||||
return this.getStatementsForClass(classSymbol)
|
return this.getStatementsForClass(classSymbol)
|
||||||
.map(statement => this.getHelperCall(statement, helperName))
|
.map(statement => this.getHelperCall(statement, helperNames))
|
||||||
.filter(isDefined);
|
.filter(isDefined);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1620,9 +1623,9 @@ interface DecoratorInfo {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the constructor parameter information, such as the type of a parameter and all
|
* Represents the constructor parameter information, such as the type of a parameter and all
|
||||||
* decorators for a certain parameter. Indices in this array correspond with the parameter's index
|
* decorators for a certain parameter. Indices in this array correspond with the parameter's
|
||||||
* in the constructor. Note that this array may be sparse, i.e. certain constructor parameters may
|
* index in the constructor. Note that this array may be sparse, i.e. certain constructor
|
||||||
* not have any info recorded.
|
* parameters may not have any info recorded.
|
||||||
*/
|
*/
|
||||||
constructorParamInfo: ParamInfo[];
|
constructorParamInfo: ParamInfo[];
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user