refactor(ngcc): rename `ExportStatement` to `ExportsStatement` (#38959)

This clarifies that this is specifically about statements of the form
`exports.<name> = <declaration>`, rather than a general export
statement such as `export class <ClassName> { ... }`.

PR Close #38959
This commit is contained in:
Pete Bacon Darwin 2020-09-27 11:29:58 +01:00 committed by atscott
parent a5a7845593
commit 87274e3eec
3 changed files with 69 additions and 28 deletions

View File

@ -14,7 +14,7 @@ import {Declaration, Import} from '../../../src/ngtsc/reflection';
import {BundleProgram} from '../packages/bundle_program';
import {FactoryMap, isDefined} from '../utils';
import {DefinePropertyReexportStatement, ExportDeclaration, ExportStatement, extractGetterFnExpression, findNamespaceOfIdentifier, findRequireCallReference, isDefinePropertyReexportStatement, isExportStatement, isExternalImport, isRequireCall, isWildcardReexportStatement, RequireCall, WildcardReexportStatement} from './commonjs_umd_utils';
import {DefinePropertyReexportStatement, ExportDeclaration, ExportsStatement, extractGetterFnExpression, findNamespaceOfIdentifier, findRequireCallReference, isDefinePropertyReexportStatement, isExportsStatement, isExternalImport, isRequireCall, isWildcardReexportStatement, RequireCall, WildcardReexportStatement} from './commonjs_umd_utils';
import {Esm5ReflectionHost} from './esm5_host';
import {NgccClassSymbol} from './ngcc_host';
@ -98,7 +98,7 @@ export class CommonJsReflectionHost extends Esm5ReflectionHost {
private computeExportsOfCommonJsModule(sourceFile: ts.SourceFile): Map<string, Declaration> {
const moduleMap = new Map<string, Declaration>();
for (const statement of this.getModuleStatements(sourceFile)) {
if (isExportStatement(statement)) {
if (isExportsStatement(statement)) {
const exportDeclaration = this.extractBasicCommonJsExportDeclaration(statement);
moduleMap.set(exportDeclaration.name, exportDeclaration.declaration);
} else if (isWildcardReexportStatement(statement)) {
@ -116,7 +116,7 @@ export class CommonJsReflectionHost extends Esm5ReflectionHost {
return moduleMap;
}
private extractBasicCommonJsExportDeclaration(statement: ExportStatement): ExportDeclaration {
private extractBasicCommonJsExportDeclaration(statement: ExportsStatement): ExportDeclaration {
const exportExpression = statement.expression.right;
const name = statement.expression.left.name.text;
return this.extractCommonJsExportDeclaration(name, exportExpression);

View File

@ -8,22 +8,13 @@
import * as ts from 'typescript';
import {Declaration} from '../../../src/ngtsc/reflection';
import {isAssignment} from '../../../src/ngtsc/util/src/typescript';
export interface ExportDeclaration {
name: string;
declaration: Declaration;
}
export interface ExportStatement extends ts.ExpressionStatement {
expression: ts.BinaryExpression&{
left: ts.PropertyAccessExpression &
{
expression: ts.Identifier
}
};
}
/**
* A CommonJS or UMD wildcard re-export statement.
*
@ -59,6 +50,9 @@ export interface DefinePropertyReexportStatement extends ts.ExpressionStatement
{arguments: [ts.Identifier, ts.StringLiteral, ts.ObjectLiteralExpression]};
}
/**
* A call expression that has a string literal for its first argument.
*/
export interface RequireCall extends ts.CallExpression {
arguments: ts.CallExpression['arguments']&[ts.StringLiteral];
}
@ -90,18 +84,6 @@ export function findRequireCallReference(id: ts.Identifier, checker: ts.TypeChec
return initializer && isRequireCall(initializer) ? initializer : null;
}
/**
* Check whether the specified `ts.Statement` is an export statement, i.e. an expression statement
* of the form: `exports.<foo> = <bar>`
*/
export function isExportStatement(stmt: ts.Statement): stmt is ExportStatement {
return ts.isExpressionStatement(stmt) && ts.isBinaryExpression(stmt.expression) &&
(stmt.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken) &&
ts.isPropertyAccessExpression(stmt.expression.left) &&
ts.isIdentifier(stmt.expression.left.expression) &&
stmt.expression.left.expression.text === 'exports';
}
/**
* Check whether the specified `ts.Statement` is a wildcard re-export statement.
* I.E. an expression statement of one of the following forms:
@ -194,6 +176,12 @@ export function isDefinePropertyReexportStatement(stmt: ts.Statement):
prop => prop.name !== undefined && ts.isIdentifier(prop.name) && prop.name.text === 'get'));
}
/**
* Extract the "value" of the getter in a `defineProperty` statement.
*
* This will return the `ts.Expression` value of a single `return` statement in the `get` method
* of the property definition object, or `null` if that is not possible.
*/
export function extractGetterFnExpression(statement: DefinePropertyReexportStatement):
ts.Expression|null {
const args = statement.expression.arguments;
@ -220,6 +208,59 @@ export function isRequireCall(node: ts.Node): node is RequireCall {
ts.isStringLiteral(node.arguments[0]);
}
/**
* Check whether the specified `path` is an "external" import.
* In other words, that it comes from a entry-point outside the current one.
*/
export function isExternalImport(path: string): boolean {
return !/^\.\.?(\/|$)/.test(path);
}
/**
* A UMD/CommonJS style export declaration of the form `exports.<name>`.
*/
export interface ExportsDeclaration extends ts.PropertyAccessExpression {
name: ts.Identifier;
expression: ts.Identifier;
parent: ExportsAssignment;
}
/**
* Check whether the specified `node` is a property access expression of the form
* `exports.<foo>`.
*/
export function isExportsDeclaration(expr: ts.Node): expr is ExportsDeclaration {
return expr.parent && isExportsAssignment(expr.parent);
}
/**
* A UMD/CommonJS style export assignment of the form `exports.<foo> = <bar>`.
*/
export interface ExportsAssignment extends ts.BinaryExpression {
left: ExportsDeclaration;
}
/**
* Check whether the specified `node` is an assignment expression of the form
* `exports.<foo> = <bar>`.
*/
export function isExportsAssignment(expr: ts.Node): expr is ExportsAssignment {
return isAssignment(expr) && ts.isPropertyAccessExpression(expr.left) &&
ts.isIdentifier(expr.left.expression) && expr.left.expression.text === 'exports' &&
ts.isIdentifier(expr.left.name);
}
/**
* An expression statement of the form `exports.<foo> = <bar>;`.
*/
export interface ExportsStatement extends ts.ExpressionStatement {
expression: ExportsAssignment;
}
/**
* Check whether the specified `stmt` is an expression statement of the form
* `exports.<foo> = <bar>;`.
*/
export function isExportsStatement(stmt: ts.Node): stmt is ExportsStatement {
return ts.isExpressionStatement(stmt) && isExportsAssignment(stmt.expression);
}

View File

@ -14,7 +14,7 @@ import {Declaration, Import} from '../../../src/ngtsc/reflection';
import {BundleProgram} from '../packages/bundle_program';
import {FactoryMap, getTsHelperFnFromIdentifier, stripExtension} from '../utils';
import {DefinePropertyReexportStatement, ExportDeclaration, ExportStatement, extractGetterFnExpression, findNamespaceOfIdentifier, findRequireCallReference, isDefinePropertyReexportStatement, isExportStatement, isExternalImport, isRequireCall, isWildcardReexportStatement, WildcardReexportStatement} from './commonjs_umd_utils';
import {DefinePropertyReexportStatement, ExportDeclaration, ExportsStatement, extractGetterFnExpression, findNamespaceOfIdentifier, findRequireCallReference, isDefinePropertyReexportStatement, isExportsStatement, isExternalImport, isRequireCall, isWildcardReexportStatement, WildcardReexportStatement} from './commonjs_umd_utils';
import {Esm5ReflectionHost} from './esm5_host';
import {stripParentheses} from './utils';
@ -90,7 +90,7 @@ export class UmdReflectionHost extends Esm5ReflectionHost {
private computeExportsOfUmdModule(sourceFile: ts.SourceFile): Map<string, Declaration>|null {
const moduleMap = new Map<string, Declaration>();
for (const statement of this.getModuleStatements(sourceFile)) {
if (isExportStatement(statement)) {
if (isExportsStatement(statement)) {
const exportDeclaration = this.extractBasicUmdExportDeclaration(statement);
moduleMap.set(exportDeclaration.name, exportDeclaration.declaration);
} else if (isWildcardReexportStatement(statement)) {
@ -132,7 +132,7 @@ export class UmdReflectionHost extends Esm5ReflectionHost {
return importPath;
}
private extractBasicUmdExportDeclaration(statement: ExportStatement): ExportDeclaration {
private extractBasicUmdExportDeclaration(statement: ExportsStatement): ExportDeclaration {
const name = statement.expression.left.name.text;
const exportExpression = statement.expression.right;
return this.extractUmdExportDeclaration(name, exportExpression);