@ngtools/webpack 9.0.0-rc.7 → 9.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -4
- package/src/angular_compiler_plugin.d.ts +5 -5
- package/src/angular_compiler_plugin.js +16 -3
- package/src/compiler_host.d.ts +2 -2
- package/src/diagnostics.js +2 -2
- package/src/interfaces.d.ts +2 -0
- package/src/loader.js +3 -2
- package/src/refactor.d.ts +2 -2
- package/src/resource_loader.d.ts +2 -2
- package/src/resource_loader.js +6 -4
- package/src/transformers/ast_helpers.d.ts +7 -6
- package/src/transformers/ast_helpers.js +0 -77
- package/src/transformers/elide_imports.d.ts +1 -1
- package/src/transformers/elide_imports.js +45 -12
- package/src/transformers/make_transform.js +1 -1
- package/src/transformers/remove-ivy-jit-support-calls.d.ts +9 -0
- package/src/transformers/remove-ivy-jit-support-calls.js +73 -0
- package/src/transformers/spec_helpers.d.ts +7 -0
- package/src/transformers/spec_helpers.js +106 -0
- package/src/webpack-input-host.d.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ngtools/webpack",
|
|
3
|
-
"version": "9.0.
|
|
3
|
+
"version": "9.0.1",
|
|
4
4
|
"description": "Webpack plugin that AoT compiles your Angular components and modules.",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"typings": "src/index.d.ts",
|
|
@@ -25,20 +25,19 @@
|
|
|
25
25
|
},
|
|
26
26
|
"homepage": "https://github.com/angular/angular-cli",
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@angular-devkit/core": "9.0.
|
|
28
|
+
"@angular-devkit/core": "9.0.1",
|
|
29
29
|
"enhanced-resolve": "4.1.1",
|
|
30
30
|
"rxjs": "6.5.3",
|
|
31
31
|
"webpack-sources": "1.4.3"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"@angular/compiler-cli": ">=9.0.0-beta < 10",
|
|
35
|
-
"typescript": ">=3.6 < 3.
|
|
35
|
+
"typescript": ">=3.6 < 3.8",
|
|
36
36
|
"webpack": "^4.0.0"
|
|
37
37
|
},
|
|
38
38
|
"engines": {
|
|
39
39
|
"node": ">= 10.13.0",
|
|
40
40
|
"npm": ">= 6.11.0",
|
|
41
|
-
"pnpm": ">= 3.2.0",
|
|
42
41
|
"yarn": ">= 1.13.0"
|
|
43
42
|
},
|
|
44
43
|
"husky": {
|
|
@@ -38,13 +38,13 @@ export declare class AngularCompilerPlugin {
|
|
|
38
38
|
private _logger;
|
|
39
39
|
private _mainFields;
|
|
40
40
|
constructor(options: AngularCompilerPluginOptions);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
get options(): AngularCompilerPluginOptions;
|
|
42
|
+
get done(): Promise<void> | null;
|
|
43
|
+
get entryModule(): {
|
|
44
44
|
path: string;
|
|
45
45
|
className: string;
|
|
46
46
|
} | null;
|
|
47
|
-
|
|
47
|
+
get typeChecker(): ts.TypeChecker | null;
|
|
48
48
|
/** @deprecated From 8.0.2 */
|
|
49
49
|
static isSupported(): boolean;
|
|
50
50
|
private _setupOptions;
|
|
@@ -75,7 +75,7 @@ export declare class AngularCompilerPlugin {
|
|
|
75
75
|
errorDependencies: string[];
|
|
76
76
|
};
|
|
77
77
|
getDependencies(fileName: string, includeResources?: boolean): string[];
|
|
78
|
-
getResourceDependencies(fileName: string):
|
|
78
|
+
getResourceDependencies(fileName: string): never[] | Set<string>;
|
|
79
79
|
getTypeDependencies(fileName: string): string[];
|
|
80
80
|
private _emit;
|
|
81
81
|
private _validateLocale;
|
|
@@ -26,6 +26,7 @@ const resource_loader_1 = require("./resource_loader");
|
|
|
26
26
|
const transformers_1 = require("./transformers");
|
|
27
27
|
const ast_helpers_1 = require("./transformers/ast_helpers");
|
|
28
28
|
const ctor_parameters_1 = require("./transformers/ctor-parameters");
|
|
29
|
+
const remove_ivy_jit_support_calls_1 = require("./transformers/remove-ivy-jit-support-calls");
|
|
29
30
|
const type_checker_1 = require("./type_checker");
|
|
30
31
|
const type_checker_messages_1 = require("./type_checker_messages");
|
|
31
32
|
const utils_1 = require("./utils");
|
|
@@ -757,6 +758,14 @@ class AngularCompilerPlugin {
|
|
|
757
758
|
// In Ivy they are removed in ngc directly.
|
|
758
759
|
this._transformers.push(transformers_1.removeDecorators(isAppPath, getTypeChecker));
|
|
759
760
|
}
|
|
761
|
+
else {
|
|
762
|
+
// Default for both options is to emit (undefined means true)
|
|
763
|
+
const removeClassMetadata = this._options.emitClassMetadata === false;
|
|
764
|
+
const removeNgModuleScope = this._options.emitNgModuleScope === false;
|
|
765
|
+
if (removeClassMetadata || removeNgModuleScope) {
|
|
766
|
+
this._transformers.push(remove_ivy_jit_support_calls_1.removeIvyJitSupportCalls(removeClassMetadata, removeNgModuleScope, getTypeChecker));
|
|
767
|
+
}
|
|
768
|
+
}
|
|
760
769
|
// Import ngfactory in loadChildren import syntax
|
|
761
770
|
if (this._useFactories) {
|
|
762
771
|
// Only transform imports to use factories with View Engine.
|
|
@@ -931,12 +940,16 @@ class AngularCompilerPlugin {
|
|
|
931
940
|
}
|
|
932
941
|
})
|
|
933
942
|
.filter(x => x);
|
|
934
|
-
let resourceImports = []
|
|
943
|
+
let resourceImports = [];
|
|
944
|
+
const resourceDependencies = [];
|
|
935
945
|
if (includeResources) {
|
|
936
946
|
resourceImports = transformers_1.findResources(sourceFile)
|
|
937
947
|
.map(resourcePath => core_1.resolve(core_1.dirname(resolvedFileName), core_1.normalize(resourcePath)));
|
|
938
|
-
|
|
939
|
-
this.getResourceDependencies(this._compilerHost.denormalizePath(
|
|
948
|
+
for (const resource of resourceImports) {
|
|
949
|
+
for (const dep of this.getResourceDependencies(this._compilerHost.denormalizePath(resource))) {
|
|
950
|
+
resourceDependencies.push(dep);
|
|
951
|
+
}
|
|
952
|
+
}
|
|
940
953
|
}
|
|
941
954
|
// These paths are meant to be used by the loader so we must denormalize them.
|
|
942
955
|
const uniqueDependencies = new Set([
|
package/src/compiler_host.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ export declare class WebpackCompilerHost implements ts.CompilerHost {
|
|
|
31
31
|
private _virtualFileExtensions;
|
|
32
32
|
private _virtualStyleFileExtensions;
|
|
33
33
|
constructor(_options: ts.CompilerOptions, basePath: string, host: virtualFs.Host, cacheSourceFiles: boolean, directTemplateLoading?: boolean, ngccProcessor?: NgccProcessor | undefined, moduleResolutionCache?: ts.ModuleResolutionCache | undefined);
|
|
34
|
-
private
|
|
34
|
+
private get virtualFiles();
|
|
35
35
|
reset(): void;
|
|
36
36
|
denormalizePath(path: string): string;
|
|
37
37
|
resolve(path: string): Path;
|
|
@@ -48,7 +48,7 @@ export declare class WebpackCompilerHost implements ts.CompilerHost {
|
|
|
48
48
|
getDirectories(path: string): string[];
|
|
49
49
|
getSourceFile(fileName: string, languageVersion: ts.ScriptTarget, onError?: OnErrorFn): ts.SourceFile | undefined;
|
|
50
50
|
getDefaultLibFileName(options: ts.CompilerOptions): string;
|
|
51
|
-
|
|
51
|
+
get writeFile(): (fileName: string, data: string, _writeByteOrderMark: boolean, onError?: ((message: string) => void) | undefined, _sourceFiles?: readonly ts.SourceFile[] | undefined) => void;
|
|
52
52
|
getCurrentDirectory(): string;
|
|
53
53
|
getCanonicalFileName(fileName: string): string;
|
|
54
54
|
useCaseSensitiveFileNames(): boolean;
|
package/src/diagnostics.js
CHANGED
|
@@ -118,11 +118,11 @@ function reportDiagnostics(diagnostics, compilerHost, reportError, reportWarning
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
if (tsErrors.length > 0) {
|
|
121
|
-
const message =
|
|
121
|
+
const message = compiler_cli_1.formatDiagnostics(tsErrors);
|
|
122
122
|
reportError(message);
|
|
123
123
|
}
|
|
124
124
|
if (tsWarnings.length > 0) {
|
|
125
|
-
const message =
|
|
125
|
+
const message = compiler_cli_1.formatDiagnostics(tsWarnings);
|
|
126
126
|
reportWarning(message);
|
|
127
127
|
}
|
|
128
128
|
if (ngErrors.length > 0) {
|
package/src/interfaces.d.ts
CHANGED
|
@@ -43,6 +43,8 @@ export interface AngularCompilerPluginOptions {
|
|
|
43
43
|
nameLazyFiles?: boolean;
|
|
44
44
|
logger?: logging.Logger;
|
|
45
45
|
directTemplateLoading?: boolean;
|
|
46
|
+
emitClassMetadata?: boolean;
|
|
47
|
+
emitNgModuleScope?: boolean;
|
|
46
48
|
/**
|
|
47
49
|
* When using the loadChildren string syntax, @ngtools/webpack must query @angular/compiler-cli
|
|
48
50
|
* via a private API to know which lazy routes exist. This increases build and rebuild time.
|
package/src/loader.js
CHANGED
|
@@ -83,8 +83,9 @@ function ngcLoader() {
|
|
|
83
83
|
const ngStyleRe = /(?:\.shim)?\.ngstyle\.js$/;
|
|
84
84
|
if (ngStyleRe.test(sourceFileName)) {
|
|
85
85
|
const styleFile = sourceFileName.replace(ngStyleRe, '');
|
|
86
|
-
const
|
|
87
|
-
|
|
86
|
+
for (const dep of plugin.getResourceDependencies(styleFile)) {
|
|
87
|
+
this.addDependency(dep);
|
|
88
|
+
}
|
|
88
89
|
}
|
|
89
90
|
// Add type-only dependencies that should trigger a rebuild when they change.
|
|
90
91
|
const typeDependencies = plugin.getTypeDependencies(sourceFileName);
|
package/src/refactor.d.ts
CHANGED
|
@@ -13,8 +13,8 @@ export declare function resolve(filePath: string, _host: ts.CompilerHost, compil
|
|
|
13
13
|
export declare class TypeScriptFileRefactor {
|
|
14
14
|
private _fileName;
|
|
15
15
|
private _sourceFile;
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
get fileName(): string;
|
|
17
|
+
get sourceFile(): ts.SourceFile;
|
|
18
18
|
constructor(fileName: string, _host: ts.CompilerHost, _program?: ts.Program, source?: string | null);
|
|
19
19
|
/**
|
|
20
20
|
* Find all nodes from the AST in the subtree of node of SyntaxKind kind.
|
package/src/resource_loader.d.ts
CHANGED
|
@@ -7,8 +7,8 @@ export declare class WebpackResourceLoader {
|
|
|
7
7
|
private _cachedEvaluatedSources;
|
|
8
8
|
constructor();
|
|
9
9
|
update(parentCompilation: any): void;
|
|
10
|
-
getResourceDependencies(filePath: string):
|
|
11
|
-
getAffectedResources(file: string):
|
|
10
|
+
getResourceDependencies(filePath: string): never[] | Set<string>;
|
|
11
|
+
getAffectedResources(file: string): never[] | Set<string>;
|
|
12
12
|
private _compile;
|
|
13
13
|
private _evaluate;
|
|
14
14
|
get(filePath: string): Promise<string>;
|
package/src/resource_loader.js
CHANGED
|
@@ -13,6 +13,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
13
13
|
const path = require("path");
|
|
14
14
|
const vm = require("vm");
|
|
15
15
|
const webpack_sources_1 = require("webpack-sources");
|
|
16
|
+
const utils_1 = require("./utils");
|
|
16
17
|
const NodeTemplatePlugin = require('webpack/lib/node/NodeTemplatePlugin');
|
|
17
18
|
const NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin');
|
|
18
19
|
const LoaderTargetPlugin = require('webpack/lib/LoaderTargetPlugin');
|
|
@@ -103,14 +104,15 @@ class WebpackResourceLoader {
|
|
|
103
104
|
}
|
|
104
105
|
});
|
|
105
106
|
// Save the dependencies for this resource.
|
|
106
|
-
this._fileDependencies.set(filePath, childCompilation.fileDependencies);
|
|
107
|
+
this._fileDependencies.set(filePath, new Set(childCompilation.fileDependencies));
|
|
107
108
|
for (const file of childCompilation.fileDependencies) {
|
|
108
|
-
const
|
|
109
|
+
const resolvedFile = utils_1.forwardSlashPath(file);
|
|
110
|
+
const entry = this._reverseDependencies.get(resolvedFile);
|
|
109
111
|
if (entry) {
|
|
110
|
-
entry.
|
|
112
|
+
entry.add(filePath);
|
|
111
113
|
}
|
|
112
114
|
else {
|
|
113
|
-
this._reverseDependencies.set(
|
|
115
|
+
this._reverseDependencies.set(resolvedFile, new Set([filePath]));
|
|
114
116
|
}
|
|
115
117
|
}
|
|
116
118
|
const compilationHash = childCompilation.fullHash;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google Inc. All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
1
8
|
import * as ts from 'typescript';
|
|
2
|
-
import { WebpackCompilerHost } from '../compiler_host';
|
|
3
9
|
export declare function collectDeepNodes<T extends ts.Node>(node: ts.Node, kind: ts.SyntaxKind | ts.SyntaxKind[]): T[];
|
|
4
10
|
export declare function getFirstNode(sourceFile: ts.SourceFile): ts.Node;
|
|
5
11
|
export declare function getLastNode(sourceFile: ts.SourceFile): ts.Node | null;
|
|
6
|
-
export declare function createTypescriptContext(content: string, additionalFiles?: Record<string, string>, useLibs?: boolean, importHelpers?: boolean): {
|
|
7
|
-
compilerHost: WebpackCompilerHost;
|
|
8
|
-
program: ts.Program;
|
|
9
|
-
};
|
|
10
|
-
export declare function transformTypescript(content: string | undefined, transformers: ts.TransformerFactory<ts.SourceFile>[], program?: ts.Program, compilerHost?: WebpackCompilerHost): string | undefined;
|
|
@@ -7,11 +7,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
* Use of this source code is governed by an MIT-style license that can be
|
|
8
8
|
* found in the LICENSE file at https://angular.io/license
|
|
9
9
|
*/
|
|
10
|
-
const core_1 = require("@angular-devkit/core");
|
|
11
|
-
const fs_1 = require("fs");
|
|
12
|
-
const path_1 = require("path");
|
|
13
10
|
const ts = require("typescript");
|
|
14
|
-
const compiler_host_1 = require("../compiler_host");
|
|
15
11
|
// Find all nodes from the AST in the subtree of node of SyntaxKind kind.
|
|
16
12
|
function collectDeepNodes(node, kind) {
|
|
17
13
|
const kinds = Array.isArray(kind) ? kind : [kind];
|
|
@@ -40,76 +36,3 @@ function getLastNode(sourceFile) {
|
|
|
40
36
|
return null;
|
|
41
37
|
}
|
|
42
38
|
exports.getLastNode = getLastNode;
|
|
43
|
-
// Test transform helpers.
|
|
44
|
-
const basePath = '/project/src/';
|
|
45
|
-
const fileName = basePath + 'test-file.ts';
|
|
46
|
-
const tsLibFiles = loadTsLibFiles();
|
|
47
|
-
function createTypescriptContext(content, additionalFiles, useLibs = false, importHelpers = true) {
|
|
48
|
-
// Set compiler options.
|
|
49
|
-
const compilerOptions = {
|
|
50
|
-
noEmitOnError: useLibs,
|
|
51
|
-
allowJs: true,
|
|
52
|
-
newLine: ts.NewLineKind.LineFeed,
|
|
53
|
-
moduleResolution: ts.ModuleResolutionKind.NodeJs,
|
|
54
|
-
module: ts.ModuleKind.ESNext,
|
|
55
|
-
target: ts.ScriptTarget.ESNext,
|
|
56
|
-
skipLibCheck: true,
|
|
57
|
-
sourceMap: false,
|
|
58
|
-
importHelpers,
|
|
59
|
-
};
|
|
60
|
-
// Create compiler host.
|
|
61
|
-
const compilerHost = new compiler_host_1.WebpackCompilerHost(compilerOptions, basePath, new core_1.virtualFs.SimpleMemoryHost(), false);
|
|
62
|
-
// Add a dummy file to host content.
|
|
63
|
-
compilerHost.writeFile(fileName, content, false);
|
|
64
|
-
if (useLibs) {
|
|
65
|
-
// Write the default libs.
|
|
66
|
-
// These are needed for tests that use import(), because it relies on a Promise being there.
|
|
67
|
-
const compilerLibFolder = path_1.dirname(compilerHost.getDefaultLibFileName(compilerOptions));
|
|
68
|
-
for (const [k, v] of Object.entries(tsLibFiles)) {
|
|
69
|
-
compilerHost.writeFile(path_1.join(compilerLibFolder, k), v, false);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (additionalFiles) {
|
|
73
|
-
for (const key in additionalFiles) {
|
|
74
|
-
compilerHost.writeFile(basePath + key, additionalFiles[key], false);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
// Create the TypeScript program.
|
|
78
|
-
const program = ts.createProgram([fileName], compilerOptions, compilerHost);
|
|
79
|
-
return { compilerHost, program };
|
|
80
|
-
}
|
|
81
|
-
exports.createTypescriptContext = createTypescriptContext;
|
|
82
|
-
function transformTypescript(content, transformers, program, compilerHost) {
|
|
83
|
-
// Use given context or create a new one.
|
|
84
|
-
if (content !== undefined) {
|
|
85
|
-
const typescriptContext = createTypescriptContext(content);
|
|
86
|
-
if (!program) {
|
|
87
|
-
program = typescriptContext.program;
|
|
88
|
-
}
|
|
89
|
-
if (!compilerHost) {
|
|
90
|
-
compilerHost = typescriptContext.compilerHost;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
else if (!program || !compilerHost) {
|
|
94
|
-
throw new Error('transformTypescript needs either `content` or a `program` and `compilerHost');
|
|
95
|
-
}
|
|
96
|
-
// Emit.
|
|
97
|
-
const { emitSkipped, diagnostics } = program.emit(undefined, undefined, undefined, undefined, { before: transformers });
|
|
98
|
-
// Throw error with diagnostics if emit wasn't successfull.
|
|
99
|
-
if (emitSkipped) {
|
|
100
|
-
throw new Error(ts.formatDiagnostics(diagnostics, compilerHost));
|
|
101
|
-
}
|
|
102
|
-
// Return the transpiled js.
|
|
103
|
-
return compilerHost.readFile(fileName.replace(/\.tsx?$/, '.js'));
|
|
104
|
-
}
|
|
105
|
-
exports.transformTypescript = transformTypescript;
|
|
106
|
-
function loadTsLibFiles() {
|
|
107
|
-
const libFolderPath = path_1.dirname(require.resolve('typescript/lib/lib.d.ts'));
|
|
108
|
-
const libFolderFiles = fs_1.readdirSync(libFolderPath);
|
|
109
|
-
const libFileNames = libFolderFiles.filter(f => f.startsWith('lib.') && f.endsWith('.d.ts'));
|
|
110
|
-
// Return a map of the lib names to their content.
|
|
111
|
-
return libFileNames.reduce((map, f) => {
|
|
112
|
-
map[f] = fs_1.readFileSync(path_1.join(libFolderPath, f), 'utf-8');
|
|
113
|
-
return map;
|
|
114
|
-
}, {});
|
|
115
|
-
}
|
|
@@ -7,4 +7,4 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import * as ts from 'typescript';
|
|
9
9
|
import { TransformOperation } from './interfaces';
|
|
10
|
-
export declare function elideImports(sourceFile: ts.SourceFile, removedNodes: ts.Node[], getTypeChecker: () => ts.TypeChecker): TransformOperation[];
|
|
10
|
+
export declare function elideImports(sourceFile: ts.SourceFile, removedNodes: ts.Node[], getTypeChecker: () => ts.TypeChecker, compilerOptions: ts.CompilerOptions): TransformOperation[];
|
|
@@ -15,7 +15,7 @@ const interfaces_1 = require("./interfaces");
|
|
|
15
15
|
// Doesn't use the `symbol.declarations` because that previous transforms might have removed nodes
|
|
16
16
|
// but the type checker doesn't know.
|
|
17
17
|
// See https://github.com/Microsoft/TypeScript/issues/17552 for more information.
|
|
18
|
-
function elideImports(sourceFile, removedNodes, getTypeChecker) {
|
|
18
|
+
function elideImports(sourceFile, removedNodes, getTypeChecker, compilerOptions) {
|
|
19
19
|
const ops = [];
|
|
20
20
|
if (removedNodes.length === 0) {
|
|
21
21
|
return [];
|
|
@@ -25,8 +25,9 @@ function elideImports(sourceFile, removedNodes, getTypeChecker) {
|
|
|
25
25
|
const usedSymbols = new Set();
|
|
26
26
|
const imports = [];
|
|
27
27
|
ts.forEachChild(sourceFile, function visit(node) {
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
var _a, _b, _c, _d;
|
|
29
|
+
// Skip removed nodes.
|
|
30
|
+
if (removedNodes.includes(node)) {
|
|
30
31
|
return;
|
|
31
32
|
}
|
|
32
33
|
// Record import and skip
|
|
@@ -35,16 +36,48 @@ function elideImports(sourceFile, removedNodes, getTypeChecker) {
|
|
|
35
36
|
return;
|
|
36
37
|
}
|
|
37
38
|
let symbol;
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
if (ts.isTypeReferenceNode(node)) {
|
|
40
|
+
if (!compilerOptions.emitDecoratorMetadata) {
|
|
41
|
+
// Skip and mark as unused if emitDecoratorMetadata is disabled.
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const parent = node.parent;
|
|
45
|
+
let isTypeReferenceForDecoratoredNode = false;
|
|
46
|
+
switch (parent.kind) {
|
|
47
|
+
case ts.SyntaxKind.GetAccessor:
|
|
48
|
+
case ts.SyntaxKind.PropertyDeclaration:
|
|
49
|
+
case ts.SyntaxKind.MethodDeclaration:
|
|
50
|
+
isTypeReferenceForDecoratoredNode = !!((_a = parent.decorators) === null || _a === void 0 ? void 0 : _a.length);
|
|
51
|
+
break;
|
|
52
|
+
case ts.SyntaxKind.Parameter:
|
|
53
|
+
// - A constructor parameter can be decorated or the class itself is decorated.
|
|
54
|
+
// - The parent of the parameter is decorated example a method declaration or a set accessor.
|
|
55
|
+
// In all cases we need the type reference not to be elided.
|
|
56
|
+
isTypeReferenceForDecoratoredNode = !!(((_b = parent.decorators) === null || _b === void 0 ? void 0 : _b.length) ||
|
|
57
|
+
(ts.isSetAccessor(parent.parent) && !!((_c = parent.parent.decorators) === null || _c === void 0 ? void 0 : _c.length)) ||
|
|
58
|
+
(ts.isConstructorDeclaration(parent.parent) && !!((_d = parent.parent.parent.decorators) === null || _d === void 0 ? void 0 : _d.length)));
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
if (isTypeReferenceForDecoratoredNode) {
|
|
40
62
|
symbol = typeChecker.getSymbolAtLocation(node);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// If type reference is not for Decorator skip and marked as unused.
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
switch (node.kind) {
|
|
71
|
+
case ts.SyntaxKind.Identifier:
|
|
72
|
+
symbol = typeChecker.getSymbolAtLocation(node);
|
|
73
|
+
break;
|
|
74
|
+
case ts.SyntaxKind.ExportSpecifier:
|
|
75
|
+
symbol = typeChecker.getExportSpecifierLocalTargetSymbol(node);
|
|
76
|
+
break;
|
|
77
|
+
case ts.SyntaxKind.ShorthandPropertyAssignment:
|
|
78
|
+
symbol = typeChecker.getShorthandAssignmentValueSymbol(node);
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
48
81
|
}
|
|
49
82
|
if (symbol) {
|
|
50
83
|
usedSymbols.add(symbol);
|
|
@@ -24,7 +24,7 @@ function makeTransform(standardTransform, getTypeChecker) {
|
|
|
24
24
|
// replace_resources), but may not be true for new transforms.
|
|
25
25
|
if (getTypeChecker && removeOps.length + replaceOps.length > 0) {
|
|
26
26
|
const removedNodes = removeOps.concat(replaceOps).map(op => op.target);
|
|
27
|
-
removeOps.push(...elide_imports_1.elideImports(sf, removedNodes, getTypeChecker));
|
|
27
|
+
removeOps.push(...elide_imports_1.elideImports(sf, removedNodes, getTypeChecker, context.getCompilerOptions()));
|
|
28
28
|
}
|
|
29
29
|
const visitor = node => {
|
|
30
30
|
let modified = false;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google Inc. All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
import * as ts from 'typescript';
|
|
9
|
+
export declare function removeIvyJitSupportCalls(classMetadata: boolean, ngModuleScope: boolean, getTypeChecker: () => ts.TypeChecker): ts.TransformerFactory<ts.SourceFile>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* @license
|
|
5
|
+
* Copyright Google Inc. All Rights Reserved.
|
|
6
|
+
*
|
|
7
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
8
|
+
* found in the LICENSE file at https://angular.io/license
|
|
9
|
+
*/
|
|
10
|
+
const ts = require("typescript");
|
|
11
|
+
const ast_helpers_1 = require("./ast_helpers");
|
|
12
|
+
const interfaces_1 = require("./interfaces");
|
|
13
|
+
const make_transform_1 = require("./make_transform");
|
|
14
|
+
function removeIvyJitSupportCalls(classMetadata, ngModuleScope, getTypeChecker) {
|
|
15
|
+
const standardTransform = function (sourceFile) {
|
|
16
|
+
const ops = [];
|
|
17
|
+
ast_helpers_1.collectDeepNodes(sourceFile, ts.SyntaxKind.ExpressionStatement)
|
|
18
|
+
.filter(statement => {
|
|
19
|
+
const innerStatement = getIifeStatement(statement);
|
|
20
|
+
if (!innerStatement) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
if (ngModuleScope && ts.isBinaryExpression(innerStatement.expression)) {
|
|
24
|
+
return isIvyPrivateCallExpression(innerStatement.expression.right, 'ɵɵsetNgModuleScope');
|
|
25
|
+
}
|
|
26
|
+
return (classMetadata &&
|
|
27
|
+
isIvyPrivateCallExpression(innerStatement.expression, 'ɵsetClassMetadata'));
|
|
28
|
+
})
|
|
29
|
+
.forEach(statement => ops.push(new interfaces_1.RemoveNodeOperation(sourceFile, statement)));
|
|
30
|
+
return ops;
|
|
31
|
+
};
|
|
32
|
+
return make_transform_1.makeTransform(standardTransform, getTypeChecker);
|
|
33
|
+
}
|
|
34
|
+
exports.removeIvyJitSupportCalls = removeIvyJitSupportCalls;
|
|
35
|
+
// Each Ivy private call expression is inside an IIFE
|
|
36
|
+
function getIifeStatement(exprStmt) {
|
|
37
|
+
const expression = exprStmt.expression;
|
|
38
|
+
if (!expression || !ts.isCallExpression(expression) || expression.arguments.length !== 0) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const parenExpr = expression;
|
|
42
|
+
if (!ts.isParenthesizedExpression(parenExpr.expression)) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
const funExpr = parenExpr.expression.expression;
|
|
46
|
+
if (!ts.isFunctionExpression(funExpr)) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
const innerStmts = funExpr.body.statements;
|
|
50
|
+
if (innerStmts.length !== 1) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
const innerExprStmt = innerStmts[0];
|
|
54
|
+
if (!ts.isExpressionStatement(innerExprStmt)) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
return innerExprStmt;
|
|
58
|
+
}
|
|
59
|
+
function isIvyPrivateCallExpression(expression, name) {
|
|
60
|
+
// Now we're in the IIFE and have the inner expression statement. We can check if it matches
|
|
61
|
+
// a private Ivy call.
|
|
62
|
+
if (!ts.isCallExpression(expression)) {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
const propAccExpr = expression.expression;
|
|
66
|
+
if (!ts.isPropertyAccessExpression(propAccExpr)) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
if (propAccExpr.name.text != name) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as ts from 'typescript';
|
|
2
|
+
import { WebpackCompilerHost } from '../compiler_host';
|
|
3
|
+
export declare function createTypescriptContext(content: string, additionalFiles?: Record<string, string>, useLibs?: boolean, extraCompilerOptions?: ts.CompilerOptions): {
|
|
4
|
+
compilerHost: WebpackCompilerHost;
|
|
5
|
+
program: ts.Program;
|
|
6
|
+
};
|
|
7
|
+
export declare function transformTypescript(content: string | undefined, transformers: ts.TransformerFactory<ts.SourceFile>[], program?: ts.Program, compilerHost?: WebpackCompilerHost): string | undefined;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
/**
|
|
4
|
+
* @license
|
|
5
|
+
* Copyright Google Inc. All Rights Reserved.
|
|
6
|
+
*
|
|
7
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
8
|
+
* found in the LICENSE file at https://angular.io/license
|
|
9
|
+
*/
|
|
10
|
+
const core_1 = require("@angular-devkit/core");
|
|
11
|
+
const fs_1 = require("fs");
|
|
12
|
+
const path_1 = require("path");
|
|
13
|
+
const ts = require("typescript");
|
|
14
|
+
const compiler_host_1 = require("../compiler_host");
|
|
15
|
+
// Test transform helpers.
|
|
16
|
+
const basePath = '/project/src/';
|
|
17
|
+
const fileName = basePath + 'test-file.ts';
|
|
18
|
+
const typeScriptLibFiles = loadTypeScriptLibFiles();
|
|
19
|
+
const tsLibFiles = loadTsLibFiles();
|
|
20
|
+
function createTypescriptContext(content, additionalFiles, useLibs = false, extraCompilerOptions = {}) {
|
|
21
|
+
// Set compiler options.
|
|
22
|
+
const compilerOptions = {
|
|
23
|
+
noEmitOnError: useLibs,
|
|
24
|
+
allowJs: true,
|
|
25
|
+
newLine: ts.NewLineKind.LineFeed,
|
|
26
|
+
moduleResolution: ts.ModuleResolutionKind.NodeJs,
|
|
27
|
+
module: ts.ModuleKind.ESNext,
|
|
28
|
+
target: ts.ScriptTarget.ESNext,
|
|
29
|
+
skipLibCheck: true,
|
|
30
|
+
sourceMap: false,
|
|
31
|
+
importHelpers: true,
|
|
32
|
+
experimentalDecorators: true,
|
|
33
|
+
...extraCompilerOptions,
|
|
34
|
+
};
|
|
35
|
+
// Create compiler host.
|
|
36
|
+
const compilerHost = new compiler_host_1.WebpackCompilerHost(compilerOptions, basePath, new core_1.virtualFs.SimpleMemoryHost(), false);
|
|
37
|
+
// Add a dummy file to host content.
|
|
38
|
+
compilerHost.writeFile(fileName, content, false);
|
|
39
|
+
if (useLibs) {
|
|
40
|
+
// Write the default libs.
|
|
41
|
+
// These are needed for tests that use import(), because it relies on a Promise being there.
|
|
42
|
+
const compilerLibFolder = path_1.dirname(compilerHost.getDefaultLibFileName(compilerOptions));
|
|
43
|
+
for (const [k, v] of Object.entries(typeScriptLibFiles)) {
|
|
44
|
+
compilerHost.writeFile(path_1.join(compilerLibFolder, k), v, false);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (compilerOptions.importHelpers) {
|
|
48
|
+
for (const [k, v] of Object.entries(tsLibFiles)) {
|
|
49
|
+
compilerHost.writeFile(k, v, false);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (additionalFiles) {
|
|
53
|
+
for (const key in additionalFiles) {
|
|
54
|
+
compilerHost.writeFile(basePath + key, additionalFiles[key], false);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Create the TypeScript program.
|
|
58
|
+
const program = ts.createProgram([fileName], compilerOptions, compilerHost);
|
|
59
|
+
return { compilerHost, program };
|
|
60
|
+
}
|
|
61
|
+
exports.createTypescriptContext = createTypescriptContext;
|
|
62
|
+
function transformTypescript(content, transformers, program, compilerHost) {
|
|
63
|
+
// Use given context or create a new one.
|
|
64
|
+
if (content !== undefined) {
|
|
65
|
+
const typescriptContext = createTypescriptContext(content);
|
|
66
|
+
if (!program) {
|
|
67
|
+
program = typescriptContext.program;
|
|
68
|
+
}
|
|
69
|
+
if (!compilerHost) {
|
|
70
|
+
compilerHost = typescriptContext.compilerHost;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
else if (!program || !compilerHost) {
|
|
74
|
+
throw new Error('transformTypescript needs either `content` or a `program` and `compilerHost');
|
|
75
|
+
}
|
|
76
|
+
// Emit.
|
|
77
|
+
const { emitSkipped, diagnostics } = program.emit(undefined, undefined, undefined, undefined, { before: transformers });
|
|
78
|
+
// Throw error with diagnostics if emit wasn't successfull.
|
|
79
|
+
if (emitSkipped) {
|
|
80
|
+
throw new Error(ts.formatDiagnostics(diagnostics, compilerHost));
|
|
81
|
+
}
|
|
82
|
+
// Return the transpiled js.
|
|
83
|
+
return compilerHost.readFile(fileName.replace(/\.tsx?$/, '.js'));
|
|
84
|
+
}
|
|
85
|
+
exports.transformTypescript = transformTypescript;
|
|
86
|
+
function loadTypeScriptLibFiles() {
|
|
87
|
+
const libFolderPath = path_1.dirname(require.resolve('typescript/lib/lib.d.ts'));
|
|
88
|
+
const libFolderFiles = fs_1.readdirSync(libFolderPath);
|
|
89
|
+
const libFileNames = libFolderFiles.filter(f => f.startsWith('lib.') && f.endsWith('.d.ts'));
|
|
90
|
+
// Return a map of the lib names to their content.
|
|
91
|
+
const libs = {};
|
|
92
|
+
for (const f of libFileNames) {
|
|
93
|
+
libs[f] = fs_1.readFileSync(path_1.join(libFolderPath, f), 'utf-8');
|
|
94
|
+
}
|
|
95
|
+
return libs;
|
|
96
|
+
}
|
|
97
|
+
function loadTsLibFiles() {
|
|
98
|
+
const libFolderPath = path_1.dirname(require.resolve('tslib/package.json'));
|
|
99
|
+
const libFolderFiles = fs_1.readdirSync(libFolderPath);
|
|
100
|
+
// Return a map of the lib names to their content.
|
|
101
|
+
const libs = {};
|
|
102
|
+
for (const f of libFolderFiles) {
|
|
103
|
+
libs[path_1.join('node_modules/tslib', f)] = fs_1.readFileSync(path_1.join(libFolderPath, f), 'utf-8');
|
|
104
|
+
}
|
|
105
|
+
return libs;
|
|
106
|
+
}
|
|
@@ -13,7 +13,7 @@ import { InputFileSystem } from 'webpack';
|
|
|
13
13
|
export declare class WebpackInputHost implements virtualFs.Host<Stats> {
|
|
14
14
|
readonly inputFileSystem: InputFileSystem;
|
|
15
15
|
constructor(inputFileSystem: InputFileSystem);
|
|
16
|
-
|
|
16
|
+
get capabilities(): virtualFs.HostCapabilities;
|
|
17
17
|
write(_path: Path, _content: virtualFs.FileBufferLike): Observable<never>;
|
|
18
18
|
delete(_path: Path): Observable<never>;
|
|
19
19
|
rename(_from: Path, _to: Path): Observable<never>;
|