mirror of https://github.com/microsoft/vscode.git
Load expensive node modules lazily
This commit is contained in:
parent
277a8262e0
commit
c1eb24b027
|
@ -16,8 +16,6 @@ const cp = require('child_process');
|
|||
const compilation = require('./lib/compilation');
|
||||
const monacoapi = require('./lib/monaco-api');
|
||||
const fs = require('fs');
|
||||
const webpack = require('webpack');
|
||||
const webpackGulp = require('webpack-stream');
|
||||
|
||||
let root = path.dirname(__dirname);
|
||||
let sha1 = util.getVersion(root);
|
||||
|
@ -369,6 +367,9 @@ gulp.task('editor-distro',
|
|||
);
|
||||
|
||||
const bundleEditorESMTask = task.define('editor-esm-bundle-webpack', () => {
|
||||
const webpack = require('webpack');
|
||||
const webpackGulp = require('webpack-stream');
|
||||
|
||||
const result = es.through();
|
||||
|
||||
const webpackConfigPath = path.join(root, 'build/monaco/monaco.webpack.config.js');
|
||||
|
|
|
@ -9,17 +9,13 @@ require('events').EventEmitter.defaultMaxListeners = 100;
|
|||
const gulp = require('gulp');
|
||||
const path = require('path');
|
||||
const nodeUtil = require('util');
|
||||
const tsb = require('gulp-tsb');
|
||||
const es = require('event-stream');
|
||||
const filter = require('gulp-filter');
|
||||
const webpack = require('webpack');
|
||||
const util = require('./lib/util');
|
||||
const task = require('./lib/task');
|
||||
const watcher = require('./lib/watch');
|
||||
const createReporter = require('./lib/reporter').createReporter;
|
||||
const glob = require('glob');
|
||||
const sourcemaps = require('gulp-sourcemaps');
|
||||
const nlsDev = require('vscode-nls-dev');
|
||||
const root = path.dirname(__dirname);
|
||||
const commit = util.getVersion(root);
|
||||
const plumber = require('gulp-plumber');
|
||||
|
@ -29,10 +25,48 @@ const ext = require('./lib/extensions');
|
|||
|
||||
const extensionsPath = path.join(path.dirname(__dirname), 'extensions');
|
||||
|
||||
const compilations = glob.sync('**/tsconfig.json', {
|
||||
cwd: extensionsPath,
|
||||
ignore: ['**/out/**', '**/node_modules/**']
|
||||
});
|
||||
// To save 250ms for each gulp startup, we are caching the result here
|
||||
// const compilations = glob.sync('**/tsconfig.json', {
|
||||
// cwd: extensionsPath,
|
||||
// ignore: ['**/out/**', '**/node_modules/**']
|
||||
// });
|
||||
const compilations = [
|
||||
'configuration-editing/build/tsconfig.json',
|
||||
'configuration-editing/tsconfig.json',
|
||||
'css-language-features/client/tsconfig.json',
|
||||
'css-language-features/server/tsconfig.json',
|
||||
'debug-auto-launch/tsconfig.json',
|
||||
'debug-server-ready/tsconfig.json',
|
||||
'emmet/tsconfig.json',
|
||||
'extension-editing/tsconfig.json',
|
||||
'git-ui/tsconfig.json',
|
||||
'git/tsconfig.json',
|
||||
'github-authentication/tsconfig.json',
|
||||
'github/tsconfig.json',
|
||||
'grunt/tsconfig.json',
|
||||
'gulp/tsconfig.json',
|
||||
'html-language-features/client/tsconfig.json',
|
||||
'html-language-features/server/tsconfig.json',
|
||||
'image-preview/tsconfig.json',
|
||||
'jake/tsconfig.json',
|
||||
'json-language-features/client/tsconfig.json',
|
||||
'json-language-features/server/tsconfig.json',
|
||||
'markdown-language-features/preview-src/tsconfig.json',
|
||||
'markdown-language-features/tsconfig.json',
|
||||
'merge-conflict/tsconfig.json',
|
||||
'microsoft-authentication/tsconfig.json',
|
||||
'npm/tsconfig.json',
|
||||
'php-language-features/tsconfig.json',
|
||||
'python/tsconfig.json',
|
||||
'search-result/tsconfig.json',
|
||||
'typescript-language-features/test-workspace/tsconfig.json',
|
||||
'typescript-language-features/tsconfig.json',
|
||||
'vscode-api-tests/tsconfig.json',
|
||||
'vscode-colorize-tests/tsconfig.json',
|
||||
'vscode-custom-editor-tests/tsconfig.json',
|
||||
'vscode-notebook-tests/tsconfig.json',
|
||||
'vscode-test-resolver/tsconfig.json'
|
||||
];
|
||||
|
||||
const getBaseUrl = out => `https://ticino.blob.core.windows.net/sourcemaps/${commit}/${out}`;
|
||||
|
||||
|
@ -64,6 +98,10 @@ const tasks = compilations.map(function (tsconfigFile) {
|
|||
}
|
||||
|
||||
function createPipeline(build, emitError) {
|
||||
const nlsDev = require('vscode-nls-dev');
|
||||
const tsb = require('gulp-tsb');
|
||||
const sourcemaps = require('gulp-sourcemaps');
|
||||
|
||||
const reporter = createReporter('extensions');
|
||||
|
||||
overrideOptions.inlineSources = Boolean(build);
|
||||
|
@ -181,6 +219,7 @@ gulp.task(watchWebExtensionsTask);
|
|||
exports.watchWebExtensionsTask = watchWebExtensionsTask;
|
||||
|
||||
async function buildWebExtensions(isWatch) {
|
||||
const webpack = require('webpack');
|
||||
|
||||
const webpackConfigLocations = await nodeUtil.promisify(glob)(
|
||||
path.join(extensionsPath, '**', 'extension-browser.webpack.config.js'),
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
const gulp = require('gulp');
|
||||
const filter = require('gulp-filter');
|
||||
const es = require('event-stream');
|
||||
const gulpeslint = require('gulp-eslint');
|
||||
const vfs = require('vinyl-fs');
|
||||
const path = require('path');
|
||||
const task = require('./lib/task');
|
||||
const { all, jsHygieneFilter, tsHygieneFilter, hygiene } = require('./hygiene');
|
||||
|
||||
gulp.task('eslint', () => {
|
||||
const gulpeslint = require('gulp-eslint');
|
||||
return vfs
|
||||
.src(all, { base: '.', follow: true, allowEmpty: true })
|
||||
.pipe(filter(jsHygieneFilter.concat(tsHygieneFilter)))
|
||||
|
|
|
@ -14,10 +14,8 @@ const task = require('./lib/task');
|
|||
const vfs = require('vinyl-fs');
|
||||
const flatmap = require('gulp-flatmap');
|
||||
const gunzip = require('gulp-gunzip');
|
||||
const untar = require('gulp-untar');
|
||||
const File = require('vinyl');
|
||||
const fs = require('fs');
|
||||
const remote = require('gulp-remote-retry-src');
|
||||
const rename = require('gulp-rename');
|
||||
const filter = require('gulp-filter');
|
||||
const cp = require('child_process');
|
||||
|
@ -77,6 +75,9 @@ if (defaultNodeTask) {
|
|||
}
|
||||
|
||||
function nodejs(platform, arch) {
|
||||
const remote = require('gulp-remote-retry-src');
|
||||
const untar = require('gulp-untar');
|
||||
|
||||
if (arch === 'ia32') {
|
||||
arch = 'x86';
|
||||
}
|
||||
|
|
|
@ -11,13 +11,10 @@ const os = require('os');
|
|||
const cp = require('child_process');
|
||||
const path = require('path');
|
||||
const es = require('event-stream');
|
||||
const azure = require('gulp-azure-storage');
|
||||
const electron = require('gulp-atom-electron');
|
||||
const vfs = require('vinyl-fs');
|
||||
const rename = require('gulp-rename');
|
||||
const replace = require('gulp-replace');
|
||||
const filter = require('gulp-filter');
|
||||
const json = require('gulp-json-editor');
|
||||
const _ = require('underscore');
|
||||
const util = require('./lib/util');
|
||||
const task = require('./lib/task');
|
||||
|
@ -143,6 +140,9 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op
|
|||
platform = platform || process.platform;
|
||||
|
||||
return () => {
|
||||
const electron = require('gulp-atom-electron');
|
||||
const json = require('gulp-json-editor');
|
||||
|
||||
const out = sourceFolderName;
|
||||
|
||||
const checksums = computeChecksums(out, [
|
||||
|
@ -503,6 +503,8 @@ gulp.task(task.define(
|
|||
task.series(
|
||||
generateVSCodeConfigurationTask,
|
||||
() => {
|
||||
const azure = require('gulp-azure-storage');
|
||||
|
||||
if (!shouldSetupSettingsSearch()) {
|
||||
const branch = process.env.BUILD_SOURCEBRANCH;
|
||||
console.log(`Only runs on master and release branches, not ${branch}`);
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
const filter = require('gulp-filter');
|
||||
const es = require('event-stream');
|
||||
const gulpeslint = require('gulp-eslint');
|
||||
const tsfmt = require('typescript-formatter');
|
||||
const VinylFile = require('vinyl');
|
||||
const vfs = require('vinyl-fs');
|
||||
const path = require('path');
|
||||
|
@ -165,6 +163,9 @@ const copyrightHeaderLines = [
|
|||
];
|
||||
|
||||
function hygiene(some) {
|
||||
const gulpeslint = require('gulp-eslint');
|
||||
const tsfmt = require('typescript-formatter');
|
||||
|
||||
let errorCount = 0;
|
||||
|
||||
const productJson = es.through(function (file) {
|
||||
|
|
|
@ -8,9 +8,6 @@ exports.watchTask = exports.compileTask = void 0;
|
|||
const es = require("event-stream");
|
||||
const fs = require("fs");
|
||||
const gulp = require("gulp");
|
||||
const bom = require("gulp-bom");
|
||||
const sourcemaps = require("gulp-sourcemaps");
|
||||
const tsb = require("gulp-tsb");
|
||||
const path = require("path");
|
||||
const monacodts = require("./monaco-api");
|
||||
const nls = require("./nls");
|
||||
|
@ -36,10 +33,13 @@ function getTypeScriptCompilerOptions(src) {
|
|||
return options;
|
||||
}
|
||||
function createCompile(src, build, emitError) {
|
||||
const tsb = require('gulp-tsb');
|
||||
const sourcemaps = require('gulp-sourcemaps');
|
||||
const projectPath = path.join(__dirname, '../../', src, 'tsconfig.json');
|
||||
const overrideOptions = Object.assign(Object.assign({}, getTypeScriptCompilerOptions(src)), { inlineSources: Boolean(build) });
|
||||
const compilation = tsb.create(projectPath, overrideOptions, false, err => reporter(err));
|
||||
function pipeline(token) {
|
||||
const bom = require('gulp-bom');
|
||||
const utf8Filter = util.filter(data => /(\/|\\)test(\/|\\).*utf8/.test(data.path));
|
||||
const tsFilter = util.filter(data => /\.ts$/.test(data.path));
|
||||
const noDeclarationsFilter = util.filter(data => !(/\.d\.ts$/.test(data.path)));
|
||||
|
@ -52,7 +52,7 @@ function createCompile(src, build, emitError) {
|
|||
.pipe(util.loadSourcemaps())
|
||||
.pipe(compilation(token))
|
||||
.pipe(noDeclarationsFilter)
|
||||
.pipe(build ? nls() : es.through())
|
||||
.pipe(build ? nls.nls() : es.through())
|
||||
.pipe(noDeclarationsFilter.restore)
|
||||
.pipe(sourcemaps.write('.', {
|
||||
addComment: false,
|
||||
|
|
|
@ -8,9 +8,6 @@
|
|||
import * as es from 'event-stream';
|
||||
import * as fs from 'fs';
|
||||
import * as gulp from 'gulp';
|
||||
import * as bom from 'gulp-bom';
|
||||
import * as sourcemaps from 'gulp-sourcemaps';
|
||||
import * as tsb from 'gulp-tsb';
|
||||
import * as path from 'path';
|
||||
import * as monacodts from './monaco-api';
|
||||
import * as nls from './nls';
|
||||
|
@ -41,12 +38,17 @@ function getTypeScriptCompilerOptions(src: string): ts.CompilerOptions {
|
|||
}
|
||||
|
||||
function createCompile(src: string, build: boolean, emitError?: boolean) {
|
||||
const tsb = <typeof import('gulp-tsb')>require('gulp-tsb');
|
||||
const sourcemaps = <typeof import('gulp-sourcemaps')>require('gulp-sourcemaps');
|
||||
|
||||
|
||||
const projectPath = path.join(__dirname, '../../', src, 'tsconfig.json');
|
||||
const overrideOptions = { ...getTypeScriptCompilerOptions(src), inlineSources: Boolean(build) };
|
||||
|
||||
const compilation = tsb.create(projectPath, overrideOptions, false, err => reporter(err));
|
||||
|
||||
function pipeline(token?: util.ICancellationToken) {
|
||||
const bom = <typeof import('gulp-bom')>require('gulp-bom');
|
||||
|
||||
const utf8Filter = util.filter(data => /(\/|\\)test(\/|\\).*utf8/.test(data.path));
|
||||
const tsFilter = util.filter(data => /\.ts$/.test(data.path));
|
||||
|
@ -61,7 +63,7 @@ function createCompile(src: string, build: boolean, emitError?: boolean) {
|
|||
.pipe(util.loadSourcemaps())
|
||||
.pipe(compilation(token))
|
||||
.pipe(noDeclarationsFilter)
|
||||
.pipe(build ? nls() : es.through())
|
||||
.pipe(build ? nls.nls() : es.through())
|
||||
.pipe(noDeclarationsFilter.restore)
|
||||
.pipe(sourcemaps.write('.', {
|
||||
addComment: false,
|
||||
|
|
|
@ -9,10 +9,8 @@ const fs = require("fs");
|
|||
const path = require("path");
|
||||
const vfs = require("vinyl-fs");
|
||||
const filter = require("gulp-filter");
|
||||
const json = require("gulp-json-editor");
|
||||
const _ = require("underscore");
|
||||
const util = require("./util");
|
||||
const electron = require('gulp-atom-electron');
|
||||
const root = path.dirname(path.dirname(__dirname));
|
||||
const product = JSON.parse(fs.readFileSync(path.join(root, 'product.json'), 'utf8'));
|
||||
const commit = util.getVersion(root);
|
||||
|
@ -80,6 +78,8 @@ exports.config = {
|
|||
};
|
||||
function getElectron(arch) {
|
||||
return () => {
|
||||
const electron = require('gulp-atom-electron');
|
||||
const json = require('gulp-json-editor');
|
||||
const electronOpts = _.extend({}, exports.config, {
|
||||
platform: process.platform,
|
||||
arch: arch === 'armhf' ? 'arm' : arch,
|
||||
|
|
|
@ -9,12 +9,9 @@ import * as fs from 'fs';
|
|||
import * as path from 'path';
|
||||
import * as vfs from 'vinyl-fs';
|
||||
import * as filter from 'gulp-filter';
|
||||
import * as json from 'gulp-json-editor';
|
||||
import * as _ from 'underscore';
|
||||
import * as util from './util';
|
||||
|
||||
const electron = require('gulp-atom-electron');
|
||||
|
||||
const root = path.dirname(path.dirname(__dirname));
|
||||
const product = JSON.parse(fs.readFileSync(path.join(root, 'product.json'), 'utf8'));
|
||||
const commit = util.getVersion(root);
|
||||
|
@ -86,6 +83,9 @@ export const config = {
|
|||
|
||||
function getElectron(arch: string): () => NodeJS.ReadWriteStream {
|
||||
return () => {
|
||||
const electron = require('gulp-atom-electron');
|
||||
const json = <typeof import('gulp-json-editor')>require('gulp-json-editor');
|
||||
|
||||
const electronOpts = _.extend({}, config, {
|
||||
platform: process.platform,
|
||||
arch: arch === 'armhf' ? 'arm' : arch,
|
||||
|
|
|
@ -11,20 +11,15 @@ const glob = require("glob");
|
|||
const gulp = require("gulp");
|
||||
const path = require("path");
|
||||
const File = require("vinyl");
|
||||
const vsce = require("vsce");
|
||||
const stats_1 = require("./stats");
|
||||
const util2 = require("./util");
|
||||
const remote = require("gulp-remote-retry-src");
|
||||
const vzip = require('gulp-vinyl-zip');
|
||||
const filter = require("gulp-filter");
|
||||
const rename = require("gulp-rename");
|
||||
const fancyLog = require("fancy-log");
|
||||
const ansiColors = require("ansi-colors");
|
||||
const buffer = require('gulp-buffer');
|
||||
const json = require("gulp-json-editor");
|
||||
const jsoncParser = require("jsonc-parser");
|
||||
const webpack = require('webpack');
|
||||
const webpackGulp = require('webpack-stream');
|
||||
const util = require('./util');
|
||||
const root = path.dirname(path.dirname(__dirname));
|
||||
const commit = util.getVersion(root);
|
||||
|
@ -88,6 +83,9 @@ function fromLocalWebpack(extensionPath, webpackConfigFileName) {
|
|||
}
|
||||
}
|
||||
}
|
||||
const vsce = require('vsce');
|
||||
const webpack = require('webpack');
|
||||
const webpackGulp = require('webpack-stream');
|
||||
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn, packagedDependencies }).then(fileNames => {
|
||||
const files = fileNames
|
||||
.map(fileName => path.join(extensionPath, fileName))
|
||||
|
@ -149,6 +147,7 @@ function fromLocalWebpack(extensionPath, webpackConfigFileName) {
|
|||
}
|
||||
function fromLocalNormal(extensionPath) {
|
||||
const result = es.through();
|
||||
const vsce = require('vsce');
|
||||
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn })
|
||||
.then(fileNames => {
|
||||
const files = fileNames
|
||||
|
@ -170,6 +169,8 @@ const baseHeaders = {
|
|||
'X-Market-User-Id': '291C1CD0-051A-4123-9B4B-30D60EF52EE2',
|
||||
};
|
||||
function fromMarketplace(extensionName, version, metadata) {
|
||||
const remote = require('gulp-remote-retry-src');
|
||||
const json = require('gulp-json-editor');
|
||||
const [publisher, name] = extensionName.split('.');
|
||||
const url = `https://marketplace.visualstudio.com/_apis/public/gallery/publishers/${publisher}/vsextensions/${name}/${version}/vspackage`;
|
||||
fancyLog('Downloading extension:', ansiColors.yellow(`${extensionName}@${version}`), '...');
|
||||
|
|
|
@ -10,20 +10,15 @@ import * as gulp from 'gulp';
|
|||
import * as path from 'path';
|
||||
import { Stream } from 'stream';
|
||||
import * as File from 'vinyl';
|
||||
import * as vsce from 'vsce';
|
||||
import { createStatsStream } from './stats';
|
||||
import * as util2 from './util';
|
||||
import remote = require('gulp-remote-retry-src');
|
||||
const vzip = require('gulp-vinyl-zip');
|
||||
import filter = require('gulp-filter');
|
||||
import rename = require('gulp-rename');
|
||||
import * as fancyLog from 'fancy-log';
|
||||
import * as ansiColors from 'ansi-colors';
|
||||
const buffer = require('gulp-buffer');
|
||||
import json = require('gulp-json-editor');
|
||||
import * as jsoncParser from 'jsonc-parser';
|
||||
const webpack = require('webpack');
|
||||
const webpackGulp = require('webpack-stream');
|
||||
const util = require('./util');
|
||||
const root = path.dirname(path.dirname(__dirname));
|
||||
const commit = util.getVersion(root);
|
||||
|
@ -97,6 +92,10 @@ function fromLocalWebpack(extensionPath: string, webpackConfigFileName: string):
|
|||
}
|
||||
}
|
||||
|
||||
const vsce = <typeof import('vsce')>require('vsce');
|
||||
const webpack = require('webpack');
|
||||
const webpackGulp = require('webpack-stream');
|
||||
|
||||
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn, packagedDependencies }).then(fileNames => {
|
||||
const files = fileNames
|
||||
.map(fileName => path.join(extensionPath, fileName))
|
||||
|
@ -175,6 +174,8 @@ function fromLocalWebpack(extensionPath: string, webpackConfigFileName: string):
|
|||
function fromLocalNormal(extensionPath: string): Stream {
|
||||
const result = es.through();
|
||||
|
||||
const vsce = <typeof import('vsce')>require('vsce');
|
||||
|
||||
vsce.listFiles({ cwd: extensionPath, packageManager: vsce.PackageManager.Yarn })
|
||||
.then(fileNames => {
|
||||
const files = fileNames
|
||||
|
@ -200,6 +201,9 @@ const baseHeaders = {
|
|||
};
|
||||
|
||||
export function fromMarketplace(extensionName: string, version: string, metadata: any): Stream {
|
||||
const remote = require('gulp-remote-retry-src');
|
||||
const json = <typeof import('gulp-json-editor')>require('gulp-json-editor');
|
||||
|
||||
const [publisher, name] = extensionName.split('.');
|
||||
const url = `https://marketplace.visualstudio.com/_apis/public/gallery/publishers/${publisher}/vsextensions/${name}/${version}/vspackage`;
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.execute = exports.run3 = exports.DeclarationResolver = exports.FSProvider = exports.RECIPE_PATH = void 0;
|
||||
const fs = require("fs");
|
||||
const ts = require("typescript");
|
||||
const path = require("path");
|
||||
const fancyLog = require("fancy-log");
|
||||
const ansiColors = require("ansi-colors");
|
||||
|
@ -18,7 +17,7 @@ const DECLARATION_PATH = path.join(__dirname, '../../src/vs/monaco.d.ts');
|
|||
function logErr(message, ...rest) {
|
||||
fancyLog(ansiColors.yellow(`[monaco.d.ts]`), message, ...rest);
|
||||
}
|
||||
function isDeclaration(a) {
|
||||
function isDeclaration(ts, a) {
|
||||
return (a.kind === ts.SyntaxKind.InterfaceDeclaration
|
||||
|| a.kind === ts.SyntaxKind.EnumDeclaration
|
||||
|| a.kind === ts.SyntaxKind.ClassDeclaration
|
||||
|
@ -26,7 +25,7 @@ function isDeclaration(a) {
|
|||
|| a.kind === ts.SyntaxKind.FunctionDeclaration
|
||||
|| a.kind === ts.SyntaxKind.ModuleDeclaration);
|
||||
}
|
||||
function visitTopLevelDeclarations(sourceFile, visitor) {
|
||||
function visitTopLevelDeclarations(ts, sourceFile, visitor) {
|
||||
let stop = false;
|
||||
let visit = (node) => {
|
||||
if (stop) {
|
||||
|
@ -49,9 +48,9 @@ function visitTopLevelDeclarations(sourceFile, visitor) {
|
|||
};
|
||||
visit(sourceFile);
|
||||
}
|
||||
function getAllTopLevelDeclarations(sourceFile) {
|
||||
function getAllTopLevelDeclarations(ts, sourceFile) {
|
||||
let all = [];
|
||||
visitTopLevelDeclarations(sourceFile, (node) => {
|
||||
visitTopLevelDeclarations(ts, sourceFile, (node) => {
|
||||
if (node.kind === ts.SyntaxKind.InterfaceDeclaration || node.kind === ts.SyntaxKind.ClassDeclaration || node.kind === ts.SyntaxKind.ModuleDeclaration) {
|
||||
let interfaceDeclaration = node;
|
||||
let triviaStart = interfaceDeclaration.pos;
|
||||
|
@ -71,10 +70,10 @@ function getAllTopLevelDeclarations(sourceFile) {
|
|||
});
|
||||
return all;
|
||||
}
|
||||
function getTopLevelDeclaration(sourceFile, typeName) {
|
||||
function getTopLevelDeclaration(ts, sourceFile, typeName) {
|
||||
let result = null;
|
||||
visitTopLevelDeclarations(sourceFile, (node) => {
|
||||
if (isDeclaration(node) && node.name) {
|
||||
visitTopLevelDeclarations(ts, sourceFile, (node) => {
|
||||
if (isDeclaration(ts, node) && node.name) {
|
||||
if (node.name.text === typeName) {
|
||||
result = node;
|
||||
return true /*stop*/;
|
||||
|
@ -104,18 +103,18 @@ function hasModifier(modifiers, kind) {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
function isStatic(member) {
|
||||
function isStatic(ts, member) {
|
||||
return hasModifier(member.modifiers, ts.SyntaxKind.StaticKeyword);
|
||||
}
|
||||
function isDefaultExport(declaration) {
|
||||
function isDefaultExport(ts, declaration) {
|
||||
return (hasModifier(declaration.modifiers, ts.SyntaxKind.DefaultKeyword)
|
||||
&& hasModifier(declaration.modifiers, ts.SyntaxKind.ExportKeyword));
|
||||
}
|
||||
function getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage, enums) {
|
||||
function getMassagedTopLevelDeclarationText(ts, sourceFile, declaration, importName, usage, enums) {
|
||||
let result = getNodeText(sourceFile, declaration);
|
||||
if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration || declaration.kind === ts.SyntaxKind.ClassDeclaration) {
|
||||
let interfaceDeclaration = declaration;
|
||||
const staticTypeName = (isDefaultExport(interfaceDeclaration)
|
||||
const staticTypeName = (isDefaultExport(ts, interfaceDeclaration)
|
||||
? `${importName}.default`
|
||||
: `${importName}.${declaration.name.text}`);
|
||||
let instanceTypeName = staticTypeName;
|
||||
|
@ -137,7 +136,7 @@ function getMassagedTopLevelDeclarationText(sourceFile, declaration, importName,
|
|||
else {
|
||||
const memberName = member.name.text;
|
||||
const memberAccess = (memberName.indexOf('.') >= 0 ? `['${memberName}']` : `.${memberName}`);
|
||||
if (isStatic(member)) {
|
||||
if (isStatic(ts, member)) {
|
||||
usage.push(`a = ${staticTypeName}${memberAccess};`);
|
||||
}
|
||||
else {
|
||||
|
@ -191,7 +190,7 @@ function getMassagedTopLevelDeclarationText(sourceFile, declaration, importName,
|
|||
}
|
||||
return result;
|
||||
}
|
||||
function format(text, endl) {
|
||||
function format(ts, text, endl) {
|
||||
const REALLY_FORMAT = false;
|
||||
text = preformat(text, endl);
|
||||
if (!REALLY_FORMAT) {
|
||||
|
@ -336,7 +335,7 @@ function createReplacer(data) {
|
|||
});
|
||||
return createReplacerFromDirectives(directives);
|
||||
}
|
||||
function generateDeclarationFile(recipe, sourceFileGetter) {
|
||||
function generateDeclarationFile(ts, recipe, sourceFileGetter) {
|
||||
const endl = /\r\n/.test(recipe) ? '\r\n' : '\n';
|
||||
let lines = recipe.split(endl);
|
||||
let result = [];
|
||||
|
@ -379,14 +378,14 @@ function generateDeclarationFile(recipe, sourceFileGetter) {
|
|||
if (typeName.length === 0) {
|
||||
return;
|
||||
}
|
||||
let declaration = getTopLevelDeclaration(sourceFile, typeName);
|
||||
let declaration = getTopLevelDeclaration(ts, sourceFile, typeName);
|
||||
if (!declaration) {
|
||||
logErr(`While handling ${line}`);
|
||||
logErr(`Cannot find ${typeName}`);
|
||||
failed = true;
|
||||
return;
|
||||
}
|
||||
result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage, enums)));
|
||||
result.push(replacer(getMassagedTopLevelDeclarationText(ts, sourceFile, declaration, importName, usage, enums)));
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -413,8 +412,8 @@ function generateDeclarationFile(recipe, sourceFileGetter) {
|
|||
typesToExcludeMap[typeName] = true;
|
||||
typesToExcludeArr.push(typeName);
|
||||
});
|
||||
getAllTopLevelDeclarations(sourceFile).forEach((declaration) => {
|
||||
if (isDeclaration(declaration) && declaration.name) {
|
||||
getAllTopLevelDeclarations(ts, sourceFile).forEach((declaration) => {
|
||||
if (isDeclaration(ts, declaration) && declaration.name) {
|
||||
if (typesToExcludeMap[declaration.name.text]) {
|
||||
return;
|
||||
}
|
||||
|
@ -428,7 +427,7 @@ function generateDeclarationFile(recipe, sourceFileGetter) {
|
|||
}
|
||||
}
|
||||
}
|
||||
result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage, enums)));
|
||||
result.push(replacer(getMassagedTopLevelDeclarationText(ts, sourceFile, declaration, importName, usage, enums)));
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -450,7 +449,7 @@ function generateDeclarationFile(recipe, sourceFileGetter) {
|
|||
resultTxt = resultTxt.replace(/\bURI\b/g, 'Uri');
|
||||
resultTxt = resultTxt.replace(/\bEvent</g, 'IEvent<');
|
||||
resultTxt = resultTxt.split(/\r\n|\n|\r/).join(endl);
|
||||
resultTxt = format(resultTxt, endl);
|
||||
resultTxt = format(ts, resultTxt, endl);
|
||||
resultTxt = resultTxt.split(/\r\n|\n|\r/).join(endl);
|
||||
enums.sort((e1, e2) => {
|
||||
if (e1.enumName < e2.enumName) {
|
||||
|
@ -471,7 +470,7 @@ function generateDeclarationFile(recipe, sourceFileGetter) {
|
|||
''
|
||||
].concat(enums.map(e => e.text)).join(endl);
|
||||
resultEnums = resultEnums.split(/\r\n|\n|\r/).join(endl);
|
||||
resultEnums = format(resultEnums, endl);
|
||||
resultEnums = format(ts, resultEnums, endl);
|
||||
resultEnums = resultEnums.split(/\r\n|\n|\r/).join(endl);
|
||||
return {
|
||||
result: resultTxt,
|
||||
|
@ -479,9 +478,9 @@ function generateDeclarationFile(recipe, sourceFileGetter) {
|
|||
enums: resultEnums
|
||||
};
|
||||
}
|
||||
function _run(sourceFileGetter) {
|
||||
function _run(ts, sourceFileGetter) {
|
||||
const recipe = fs.readFileSync(exports.RECIPE_PATH).toString();
|
||||
const t = generateDeclarationFile(recipe, sourceFileGetter);
|
||||
const t = generateDeclarationFile(ts, recipe, sourceFileGetter);
|
||||
if (!t) {
|
||||
return null;
|
||||
}
|
||||
|
@ -521,6 +520,7 @@ class CacheEntry {
|
|||
class DeclarationResolver {
|
||||
constructor(_fsProvider) {
|
||||
this._fsProvider = _fsProvider;
|
||||
this.ts = require('typescript');
|
||||
this._sourceFileCache = Object.create(null);
|
||||
}
|
||||
invalidateCache(moduleId) {
|
||||
|
@ -555,25 +555,26 @@ class DeclarationResolver {
|
|||
if (/\.d\.ts$/.test(moduleId)) {
|
||||
// const mtime = this._fsProvider.statFileSync()
|
||||
const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
|
||||
return new CacheEntry(ts.createSourceFile(fileName, fileContents, ts.ScriptTarget.ES5), mtime);
|
||||
return new CacheEntry(this.ts.createSourceFile(fileName, fileContents, this.ts.ScriptTarget.ES5), mtime);
|
||||
}
|
||||
const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
|
||||
const fileMap = {
|
||||
'file.ts': fileContents
|
||||
};
|
||||
const service = ts.createLanguageService(new TypeScriptLanguageServiceHost({}, fileMap, {}));
|
||||
const service = this.ts.createLanguageService(new TypeScriptLanguageServiceHost(this.ts, {}, fileMap, {}));
|
||||
const text = service.getEmitOutput('file.ts', true, true).outputFiles[0].text;
|
||||
return new CacheEntry(ts.createSourceFile(fileName, text, ts.ScriptTarget.ES5), mtime);
|
||||
return new CacheEntry(this.ts.createSourceFile(fileName, text, this.ts.ScriptTarget.ES5), mtime);
|
||||
}
|
||||
}
|
||||
exports.DeclarationResolver = DeclarationResolver;
|
||||
function run3(resolver) {
|
||||
const sourceFileGetter = (moduleId) => resolver.getDeclarationSourceFile(moduleId);
|
||||
return _run(sourceFileGetter);
|
||||
return _run(resolver.ts, sourceFileGetter);
|
||||
}
|
||||
exports.run3 = run3;
|
||||
class TypeScriptLanguageServiceHost {
|
||||
constructor(libs, files, compilerOptions) {
|
||||
constructor(ts, libs, files, compilerOptions) {
|
||||
this._ts = ts;
|
||||
this._libs = libs;
|
||||
this._files = files;
|
||||
this._compilerOptions = compilerOptions;
|
||||
|
@ -595,17 +596,17 @@ class TypeScriptLanguageServiceHost {
|
|||
}
|
||||
getScriptSnapshot(fileName) {
|
||||
if (this._files.hasOwnProperty(fileName)) {
|
||||
return ts.ScriptSnapshot.fromString(this._files[fileName]);
|
||||
return this._ts.ScriptSnapshot.fromString(this._files[fileName]);
|
||||
}
|
||||
else if (this._libs.hasOwnProperty(fileName)) {
|
||||
return ts.ScriptSnapshot.fromString(this._libs[fileName]);
|
||||
return this._ts.ScriptSnapshot.fromString(this._libs[fileName]);
|
||||
}
|
||||
else {
|
||||
return ts.ScriptSnapshot.fromString('');
|
||||
return this._ts.ScriptSnapshot.fromString('');
|
||||
}
|
||||
}
|
||||
getScriptKind(_fileName) {
|
||||
return ts.ScriptKind.TS;
|
||||
return this._ts.ScriptKind.TS;
|
||||
}
|
||||
getCurrentDirectory() {
|
||||
return '';
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as ts from 'typescript';
|
||||
import type * as ts from 'typescript';
|
||||
import * as path from 'path';
|
||||
import * as fancyLog from 'fancy-log';
|
||||
import * as ansiColors from 'ansi-colors';
|
||||
|
@ -26,7 +26,7 @@ type SourceFileGetter = (moduleId: string) => ts.SourceFile | null;
|
|||
type TSTopLevelDeclaration = ts.InterfaceDeclaration | ts.EnumDeclaration | ts.ClassDeclaration | ts.TypeAliasDeclaration | ts.FunctionDeclaration | ts.ModuleDeclaration;
|
||||
type TSTopLevelDeclare = TSTopLevelDeclaration | ts.VariableStatement;
|
||||
|
||||
function isDeclaration(a: TSTopLevelDeclare): a is TSTopLevelDeclaration {
|
||||
function isDeclaration(ts: typeof import('typescript'), a: TSTopLevelDeclare): a is TSTopLevelDeclaration {
|
||||
return (
|
||||
a.kind === ts.SyntaxKind.InterfaceDeclaration
|
||||
|| a.kind === ts.SyntaxKind.EnumDeclaration
|
||||
|
@ -37,7 +37,7 @@ function isDeclaration(a: TSTopLevelDeclare): a is TSTopLevelDeclaration {
|
|||
);
|
||||
}
|
||||
|
||||
function visitTopLevelDeclarations(sourceFile: ts.SourceFile, visitor: (node: TSTopLevelDeclare) => boolean): void {
|
||||
function visitTopLevelDeclarations(ts: typeof import('typescript'), sourceFile: ts.SourceFile, visitor: (node: TSTopLevelDeclare) => boolean): void {
|
||||
let stop = false;
|
||||
|
||||
let visit = (node: ts.Node): void => {
|
||||
|
@ -66,9 +66,9 @@ function visitTopLevelDeclarations(sourceFile: ts.SourceFile, visitor: (node: TS
|
|||
}
|
||||
|
||||
|
||||
function getAllTopLevelDeclarations(sourceFile: ts.SourceFile): TSTopLevelDeclare[] {
|
||||
function getAllTopLevelDeclarations(ts: typeof import('typescript'), sourceFile: ts.SourceFile): TSTopLevelDeclare[] {
|
||||
let all: TSTopLevelDeclare[] = [];
|
||||
visitTopLevelDeclarations(sourceFile, (node) => {
|
||||
visitTopLevelDeclarations(ts, sourceFile, (node) => {
|
||||
if (node.kind === ts.SyntaxKind.InterfaceDeclaration || node.kind === ts.SyntaxKind.ClassDeclaration || node.kind === ts.SyntaxKind.ModuleDeclaration) {
|
||||
let interfaceDeclaration = <ts.InterfaceDeclaration>node;
|
||||
let triviaStart = interfaceDeclaration.pos;
|
||||
|
@ -90,10 +90,10 @@ function getAllTopLevelDeclarations(sourceFile: ts.SourceFile): TSTopLevelDeclar
|
|||
}
|
||||
|
||||
|
||||
function getTopLevelDeclaration(sourceFile: ts.SourceFile, typeName: string): TSTopLevelDeclare | null {
|
||||
function getTopLevelDeclaration(ts: typeof import('typescript'), sourceFile: ts.SourceFile, typeName: string): TSTopLevelDeclare | null {
|
||||
let result: TSTopLevelDeclare | null = null;
|
||||
visitTopLevelDeclarations(sourceFile, (node) => {
|
||||
if (isDeclaration(node) && node.name) {
|
||||
visitTopLevelDeclarations(ts, sourceFile, (node) => {
|
||||
if (isDeclaration(ts, node) && node.name) {
|
||||
if (node.name.text === typeName) {
|
||||
result = node;
|
||||
return true /*stop*/;
|
||||
|
@ -127,24 +127,24 @@ function hasModifier(modifiers: ts.NodeArray<ts.Modifier> | undefined, kind: ts.
|
|||
return false;
|
||||
}
|
||||
|
||||
function isStatic(member: ts.ClassElement | ts.TypeElement): boolean {
|
||||
function isStatic(ts: typeof import('typescript'), member: ts.ClassElement | ts.TypeElement): boolean {
|
||||
return hasModifier(member.modifiers, ts.SyntaxKind.StaticKeyword);
|
||||
}
|
||||
|
||||
function isDefaultExport(declaration: ts.InterfaceDeclaration | ts.ClassDeclaration): boolean {
|
||||
function isDefaultExport(ts: typeof import('typescript'), declaration: ts.InterfaceDeclaration | ts.ClassDeclaration): boolean {
|
||||
return (
|
||||
hasModifier(declaration.modifiers, ts.SyntaxKind.DefaultKeyword)
|
||||
&& hasModifier(declaration.modifiers, ts.SyntaxKind.ExportKeyword)
|
||||
);
|
||||
}
|
||||
|
||||
function getMassagedTopLevelDeclarationText(sourceFile: ts.SourceFile, declaration: TSTopLevelDeclare, importName: string, usage: string[], enums: IEnumEntry[]): string {
|
||||
function getMassagedTopLevelDeclarationText(ts: typeof import('typescript'), sourceFile: ts.SourceFile, declaration: TSTopLevelDeclare, importName: string, usage: string[], enums: IEnumEntry[]): string {
|
||||
let result = getNodeText(sourceFile, declaration);
|
||||
if (declaration.kind === ts.SyntaxKind.InterfaceDeclaration || declaration.kind === ts.SyntaxKind.ClassDeclaration) {
|
||||
let interfaceDeclaration = <ts.InterfaceDeclaration | ts.ClassDeclaration>declaration;
|
||||
|
||||
const staticTypeName = (
|
||||
isDefaultExport(interfaceDeclaration)
|
||||
isDefaultExport(ts, interfaceDeclaration)
|
||||
? `${importName}.default`
|
||||
: `${importName}.${declaration.name!.text}`
|
||||
);
|
||||
|
@ -168,7 +168,7 @@ function getMassagedTopLevelDeclarationText(sourceFile: ts.SourceFile, declarati
|
|||
} else {
|
||||
const memberName = (<ts.Identifier | ts.StringLiteral>member.name).text;
|
||||
const memberAccess = (memberName.indexOf('.') >= 0 ? `['${memberName}']` : `.${memberName}`);
|
||||
if (isStatic(member)) {
|
||||
if (isStatic(ts, member)) {
|
||||
usage.push(`a = ${staticTypeName}${memberAccess};`);
|
||||
} else {
|
||||
usage.push(`a = (<${instanceTypeName}>b)${memberAccess};`);
|
||||
|
@ -222,7 +222,7 @@ function getMassagedTopLevelDeclarationText(sourceFile: ts.SourceFile, declarati
|
|||
return result;
|
||||
}
|
||||
|
||||
function format(text: string, endl: string): string {
|
||||
function format(ts: typeof import('typescript'), text: string, endl: string): string {
|
||||
const REALLY_FORMAT = false;
|
||||
|
||||
text = preformat(text, endl);
|
||||
|
@ -396,7 +396,7 @@ interface IEnumEntry {
|
|||
text: string;
|
||||
}
|
||||
|
||||
function generateDeclarationFile(recipe: string, sourceFileGetter: SourceFileGetter): ITempResult | null {
|
||||
function generateDeclarationFile(ts: typeof import('typescript'), recipe: string, sourceFileGetter: SourceFileGetter): ITempResult | null {
|
||||
const endl = /\r\n/.test(recipe) ? '\r\n' : '\n';
|
||||
|
||||
let lines = recipe.split(endl);
|
||||
|
@ -452,14 +452,14 @@ function generateDeclarationFile(recipe: string, sourceFileGetter: SourceFileGet
|
|||
if (typeName.length === 0) {
|
||||
return;
|
||||
}
|
||||
let declaration = getTopLevelDeclaration(sourceFile, typeName);
|
||||
let declaration = getTopLevelDeclaration(ts, sourceFile, typeName);
|
||||
if (!declaration) {
|
||||
logErr(`While handling ${line}`);
|
||||
logErr(`Cannot find ${typeName}`);
|
||||
failed = true;
|
||||
return;
|
||||
}
|
||||
result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage, enums)));
|
||||
result.push(replacer(getMassagedTopLevelDeclarationText(ts, sourceFile, declaration, importName, usage, enums)));
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -491,8 +491,8 @@ function generateDeclarationFile(recipe: string, sourceFileGetter: SourceFileGet
|
|||
typesToExcludeArr.push(typeName);
|
||||
});
|
||||
|
||||
getAllTopLevelDeclarations(sourceFile).forEach((declaration) => {
|
||||
if (isDeclaration(declaration) && declaration.name) {
|
||||
getAllTopLevelDeclarations(ts, sourceFile).forEach((declaration) => {
|
||||
if (isDeclaration(ts, declaration) && declaration.name) {
|
||||
if (typesToExcludeMap[declaration.name.text]) {
|
||||
return;
|
||||
}
|
||||
|
@ -505,7 +505,7 @@ function generateDeclarationFile(recipe: string, sourceFileGetter: SourceFileGet
|
|||
}
|
||||
}
|
||||
}
|
||||
result.push(replacer(getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, usage, enums)));
|
||||
result.push(replacer(getMassagedTopLevelDeclarationText(ts, sourceFile, declaration, importName, usage, enums)));
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -530,7 +530,7 @@ function generateDeclarationFile(recipe: string, sourceFileGetter: SourceFileGet
|
|||
resultTxt = resultTxt.replace(/\bURI\b/g, 'Uri');
|
||||
resultTxt = resultTxt.replace(/\bEvent</g, 'IEvent<');
|
||||
resultTxt = resultTxt.split(/\r\n|\n|\r/).join(endl);
|
||||
resultTxt = format(resultTxt, endl);
|
||||
resultTxt = format(ts, resultTxt, endl);
|
||||
resultTxt = resultTxt.split(/\r\n|\n|\r/).join(endl);
|
||||
|
||||
enums.sort((e1, e2) => {
|
||||
|
@ -553,7 +553,7 @@ function generateDeclarationFile(recipe: string, sourceFileGetter: SourceFileGet
|
|||
''
|
||||
].concat(enums.map(e => e.text)).join(endl);
|
||||
resultEnums = resultEnums.split(/\r\n|\n|\r/).join(endl);
|
||||
resultEnums = format(resultEnums, endl);
|
||||
resultEnums = format(ts, resultEnums, endl);
|
||||
resultEnums = resultEnums.split(/\r\n|\n|\r/).join(endl);
|
||||
|
||||
return {
|
||||
|
@ -571,9 +571,9 @@ export interface IMonacoDeclarationResult {
|
|||
isTheSame: boolean;
|
||||
}
|
||||
|
||||
function _run(sourceFileGetter: SourceFileGetter): IMonacoDeclarationResult | null {
|
||||
function _run(ts: typeof import('typescript'), sourceFileGetter: SourceFileGetter): IMonacoDeclarationResult | null {
|
||||
const recipe = fs.readFileSync(RECIPE_PATH).toString();
|
||||
const t = generateDeclarationFile(recipe, sourceFileGetter);
|
||||
const t = generateDeclarationFile(ts, recipe, sourceFileGetter);
|
||||
if (!t) {
|
||||
return null;
|
||||
}
|
||||
|
@ -617,9 +617,11 @@ class CacheEntry {
|
|||
|
||||
export class DeclarationResolver {
|
||||
|
||||
public readonly ts: typeof import('typescript');
|
||||
private _sourceFileCache: { [moduleId: string]: CacheEntry | null; };
|
||||
|
||||
constructor(private readonly _fsProvider: FSProvider) {
|
||||
this.ts = <typeof import('typescript')>require('typescript');
|
||||
this._sourceFileCache = Object.create(null);
|
||||
}
|
||||
|
||||
|
@ -659,7 +661,7 @@ export class DeclarationResolver {
|
|||
// const mtime = this._fsProvider.statFileSync()
|
||||
const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
|
||||
return new CacheEntry(
|
||||
ts.createSourceFile(fileName, fileContents, ts.ScriptTarget.ES5),
|
||||
this.ts.createSourceFile(fileName, fileContents, this.ts.ScriptTarget.ES5),
|
||||
mtime
|
||||
);
|
||||
}
|
||||
|
@ -667,10 +669,10 @@ export class DeclarationResolver {
|
|||
const fileMap: IFileMap = {
|
||||
'file.ts': fileContents
|
||||
};
|
||||
const service = ts.createLanguageService(new TypeScriptLanguageServiceHost({}, fileMap, {}));
|
||||
const service = this.ts.createLanguageService(new TypeScriptLanguageServiceHost(this.ts, {}, fileMap, {}));
|
||||
const text = service.getEmitOutput('file.ts', true, true).outputFiles[0].text;
|
||||
return new CacheEntry(
|
||||
ts.createSourceFile(fileName, text, ts.ScriptTarget.ES5),
|
||||
this.ts.createSourceFile(fileName, text, this.ts.ScriptTarget.ES5),
|
||||
mtime
|
||||
);
|
||||
}
|
||||
|
@ -678,7 +680,7 @@ export class DeclarationResolver {
|
|||
|
||||
export function run3(resolver: DeclarationResolver): IMonacoDeclarationResult | null {
|
||||
const sourceFileGetter = (moduleId: string) => resolver.getDeclarationSourceFile(moduleId);
|
||||
return _run(sourceFileGetter);
|
||||
return _run(resolver.ts, sourceFileGetter);
|
||||
}
|
||||
|
||||
|
||||
|
@ -689,11 +691,13 @@ interface IFileMap { [fileName: string]: string; }
|
|||
|
||||
class TypeScriptLanguageServiceHost implements ts.LanguageServiceHost {
|
||||
|
||||
private readonly _ts: typeof import('typescript');
|
||||
private readonly _libs: ILibMap;
|
||||
private readonly _files: IFileMap;
|
||||
private readonly _compilerOptions: ts.CompilerOptions;
|
||||
|
||||
constructor(libs: ILibMap, files: IFileMap, compilerOptions: ts.CompilerOptions) {
|
||||
constructor(ts: typeof import('typescript'), libs: ILibMap, files: IFileMap, compilerOptions: ts.CompilerOptions) {
|
||||
this._ts = ts;
|
||||
this._libs = libs;
|
||||
this._files = files;
|
||||
this._compilerOptions = compilerOptions;
|
||||
|
@ -719,15 +723,15 @@ class TypeScriptLanguageServiceHost implements ts.LanguageServiceHost {
|
|||
}
|
||||
getScriptSnapshot(fileName: string): ts.IScriptSnapshot {
|
||||
if (this._files.hasOwnProperty(fileName)) {
|
||||
return ts.ScriptSnapshot.fromString(this._files[fileName]);
|
||||
return this._ts.ScriptSnapshot.fromString(this._files[fileName]);
|
||||
} else if (this._libs.hasOwnProperty(fileName)) {
|
||||
return ts.ScriptSnapshot.fromString(this._libs[fileName]);
|
||||
return this._ts.ScriptSnapshot.fromString(this._libs[fileName]);
|
||||
} else {
|
||||
return ts.ScriptSnapshot.fromString('');
|
||||
return this._ts.ScriptSnapshot.fromString('');
|
||||
}
|
||||
}
|
||||
getScriptKind(_fileName: string): ts.ScriptKind {
|
||||
return ts.ScriptKind.TS;
|
||||
return this._ts.ScriptKind.TS;
|
||||
}
|
||||
getCurrentDirectory(): string {
|
||||
return '';
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
const ts = require("typescript");
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.nls = void 0;
|
||||
const lazy = require("lazy.js");
|
||||
const event_stream_1 = require("event-stream");
|
||||
const File = require("vinyl");
|
||||
|
@ -16,7 +17,7 @@ var CollectStepResult;
|
|||
CollectStepResult[CollectStepResult["No"] = 2] = "No";
|
||||
CollectStepResult[CollectStepResult["NoAndRecurse"] = 3] = "NoAndRecurse";
|
||||
})(CollectStepResult || (CollectStepResult = {}));
|
||||
function collect(node, fn) {
|
||||
function collect(ts, node, fn) {
|
||||
const result = [];
|
||||
function loop(node) {
|
||||
const stepResult = fn(node);
|
||||
|
@ -69,14 +70,16 @@ function nls() {
|
|||
if (!typescript) {
|
||||
return this.emit('error', new Error(`File ${f.relative} does not have the original content in the source map.`));
|
||||
}
|
||||
nls.patchFiles(f, typescript).forEach(f => this.emit('data', f));
|
||||
_nls.patchFiles(f, typescript).forEach(f => this.emit('data', f));
|
||||
}));
|
||||
return event_stream_1.duplex(input, output);
|
||||
}
|
||||
function isImportNode(node) {
|
||||
exports.nls = nls;
|
||||
function isImportNode(ts, node) {
|
||||
return node.kind === ts.SyntaxKind.ImportDeclaration || node.kind === ts.SyntaxKind.ImportEqualsDeclaration;
|
||||
}
|
||||
(function (nls_1) {
|
||||
var _nls;
|
||||
(function (_nls) {
|
||||
function fileFrom(file, contents, path = file.path) {
|
||||
return new File({
|
||||
contents: Buffer.from(contents),
|
||||
|
@ -85,17 +88,14 @@ function isImportNode(node) {
|
|||
path: path
|
||||
});
|
||||
}
|
||||
nls_1.fileFrom = fileFrom;
|
||||
function mappedPositionFrom(source, lc) {
|
||||
return { source, line: lc.line + 1, column: lc.character };
|
||||
}
|
||||
nls_1.mappedPositionFrom = mappedPositionFrom;
|
||||
function lcFrom(position) {
|
||||
return { line: position.line - 1, character: position.column };
|
||||
}
|
||||
nls_1.lcFrom = lcFrom;
|
||||
class SingleFileServiceHost {
|
||||
constructor(options, filename, contents) {
|
||||
constructor(ts, options, filename, contents) {
|
||||
this.options = options;
|
||||
this.filename = filename;
|
||||
this.getCompilationSettings = () => this.options;
|
||||
|
@ -108,20 +108,19 @@ function isImportNode(node) {
|
|||
this.lib = ts.ScriptSnapshot.fromString('');
|
||||
}
|
||||
}
|
||||
nls_1.SingleFileServiceHost = SingleFileServiceHost;
|
||||
function isCallExpressionWithinTextSpanCollectStep(textSpan, node) {
|
||||
function isCallExpressionWithinTextSpanCollectStep(ts, textSpan, node) {
|
||||
if (!ts.textSpanContainsTextSpan({ start: node.pos, length: node.end - node.pos }, textSpan)) {
|
||||
return CollectStepResult.No;
|
||||
}
|
||||
return node.kind === ts.SyntaxKind.CallExpression ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse;
|
||||
}
|
||||
function analyze(contents, options = {}) {
|
||||
function analyze(ts, contents, options = {}) {
|
||||
const filename = 'file.ts';
|
||||
const serviceHost = new SingleFileServiceHost(Object.assign(clone(options), { noResolve: true }), filename, contents);
|
||||
const serviceHost = new SingleFileServiceHost(ts, Object.assign(clone(options), { noResolve: true }), filename, contents);
|
||||
const service = ts.createLanguageService(serviceHost);
|
||||
const sourceFile = ts.createSourceFile(filename, contents, ts.ScriptTarget.ES5, true);
|
||||
// all imports
|
||||
const imports = lazy(collect(sourceFile, n => isImportNode(n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse));
|
||||
const imports = lazy(collect(ts, sourceFile, n => isImportNode(ts, n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse));
|
||||
// import nls = require('vs/nls');
|
||||
const importEqualsDeclarations = imports
|
||||
.filter(n => n.kind === ts.SyntaxKind.ImportEqualsDeclaration)
|
||||
|
@ -152,7 +151,7 @@ function isImportNode(node) {
|
|||
.flatten()
|
||||
.filter(r => !r.isWriteAccess)
|
||||
// find the deepest call expressions AST nodes that contain those references
|
||||
.map(r => collect(sourceFile, n => isCallExpressionWithinTextSpanCollectStep(r.textSpan, n)))
|
||||
.map(r => collect(ts, sourceFile, n => isCallExpressionWithinTextSpanCollectStep(ts, r.textSpan, n)))
|
||||
.map(a => lazy(a).last())
|
||||
.filter(n => !!n)
|
||||
.map(n => n)
|
||||
|
@ -178,7 +177,7 @@ function isImportNode(node) {
|
|||
// find the deepest call expressions AST nodes that contain those references
|
||||
const localizeCallExpressions = localizeReferences
|
||||
.concat(namedLocalizeReferences)
|
||||
.map(r => collect(sourceFile, n => isCallExpressionWithinTextSpanCollectStep(r.textSpan, n)))
|
||||
.map(r => collect(ts, sourceFile, n => isCallExpressionWithinTextSpanCollectStep(ts, r.textSpan, n)))
|
||||
.map(a => lazy(a).last())
|
||||
.filter(n => !!n)
|
||||
.map(n => n);
|
||||
|
@ -199,7 +198,6 @@ function isImportNode(node) {
|
|||
nlsExpressions: nlsExpressions.toArray()
|
||||
};
|
||||
}
|
||||
nls_1.analyze = analyze;
|
||||
class TextModel {
|
||||
constructor(contents) {
|
||||
const regex = /\r\n|\r|\n/g;
|
||||
|
@ -250,9 +248,8 @@ function isImportNode(node) {
|
|||
.flatten().toArray().join('');
|
||||
}
|
||||
}
|
||||
nls_1.TextModel = TextModel;
|
||||
function patchJavascript(patches, contents, moduleId) {
|
||||
const model = new nls.TextModel(contents);
|
||||
const model = new TextModel(contents);
|
||||
// patch the localize calls
|
||||
lazy(patches).reverse().each(p => model.apply(p));
|
||||
// patch the 'vs/nls' imports
|
||||
|
@ -261,7 +258,6 @@ function isImportNode(node) {
|
|||
model.set(0, patchedFirstLine);
|
||||
return model.toString();
|
||||
}
|
||||
nls_1.patchJavascript = patchJavascript;
|
||||
function patchSourcemap(patches, rsm, smc) {
|
||||
const smg = new sm.SourceMapGenerator({
|
||||
file: rsm.file,
|
||||
|
@ -297,9 +293,8 @@ function isImportNode(node) {
|
|||
}
|
||||
return JSON.parse(smg.toString());
|
||||
}
|
||||
nls_1.patchSourcemap = patchSourcemap;
|
||||
function patch(moduleId, typescript, javascript, sourcemap) {
|
||||
const { localizeCalls, nlsExpressions } = analyze(typescript);
|
||||
function patch(ts, moduleId, typescript, javascript, sourcemap) {
|
||||
const { localizeCalls, nlsExpressions } = analyze(ts, typescript);
|
||||
if (localizeCalls.length === 0) {
|
||||
return { javascript, sourcemap };
|
||||
}
|
||||
|
@ -332,13 +327,13 @@ function isImportNode(node) {
|
|||
sourcemap = patchSourcemap(patches, sourcemap, smc);
|
||||
return { javascript, sourcemap, nlsKeys, nls };
|
||||
}
|
||||
nls_1.patch = patch;
|
||||
function patchFiles(javascriptFile, typescript) {
|
||||
const ts = require('typescript');
|
||||
// hack?
|
||||
const moduleId = javascriptFile.relative
|
||||
.replace(/\.js$/, '')
|
||||
.replace(/\\/g, '/');
|
||||
const { javascript, sourcemap, nlsKeys, nls } = patch(moduleId, typescript, javascriptFile.contents.toString(), javascriptFile.sourceMap);
|
||||
const { javascript, sourcemap, nlsKeys, nls } = patch(ts, moduleId, typescript, javascriptFile.contents.toString(), javascriptFile.sourceMap);
|
||||
const result = [fileFrom(javascriptFile, javascript)];
|
||||
result[0].sourceMap = sourcemap;
|
||||
if (nlsKeys) {
|
||||
|
@ -349,6 +344,5 @@ function isImportNode(node) {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
nls_1.patchFiles = patchFiles;
|
||||
})(nls || (nls = {}));
|
||||
module.exports = nls;
|
||||
_nls.patchFiles = patchFiles;
|
||||
})(_nls || (_nls = {}));
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as ts from 'typescript';
|
||||
import type * as ts from 'typescript';
|
||||
import * as lazy from 'lazy.js';
|
||||
import { duplex, through } from 'event-stream';
|
||||
import * as File from 'vinyl';
|
||||
|
@ -21,7 +21,7 @@ enum CollectStepResult {
|
|||
NoAndRecurse
|
||||
}
|
||||
|
||||
function collect(node: ts.Node, fn: (node: ts.Node) => CollectStepResult): ts.Node[] {
|
||||
function collect(ts: typeof import('typescript'), node: ts.Node, fn: (node: ts.Node) => CollectStepResult): ts.Node[] {
|
||||
const result: ts.Node[] = [];
|
||||
|
||||
function loop(node: ts.Node) {
|
||||
|
@ -65,7 +65,7 @@ define([], [${ wrap + lines.map(l => indent + l).join(',\n') + wrap}]);`;
|
|||
/**
|
||||
* Returns a stream containing the patched JavaScript and source maps.
|
||||
*/
|
||||
function nls(): NodeJS.ReadWriteStream {
|
||||
export function nls(): NodeJS.ReadWriteStream {
|
||||
const input = through();
|
||||
const output = input.pipe(through(function (f: FileSourceMap) {
|
||||
if (!f.sourceMap) {
|
||||
|
@ -87,48 +87,48 @@ function nls(): NodeJS.ReadWriteStream {
|
|||
return this.emit('error', new Error(`File ${f.relative} does not have the original content in the source map.`));
|
||||
}
|
||||
|
||||
nls.patchFiles(f, typescript).forEach(f => this.emit('data', f));
|
||||
_nls.patchFiles(f, typescript).forEach(f => this.emit('data', f));
|
||||
}));
|
||||
|
||||
return duplex(input, output);
|
||||
}
|
||||
|
||||
function isImportNode(node: ts.Node): boolean {
|
||||
function isImportNode(ts: typeof import('typescript'), node: ts.Node): boolean {
|
||||
return node.kind === ts.SyntaxKind.ImportDeclaration || node.kind === ts.SyntaxKind.ImportEqualsDeclaration;
|
||||
}
|
||||
|
||||
module nls {
|
||||
module _nls {
|
||||
|
||||
export interface INlsStringResult {
|
||||
interface INlsStringResult {
|
||||
javascript: string;
|
||||
sourcemap: sm.RawSourceMap;
|
||||
nls?: string;
|
||||
nlsKeys?: string;
|
||||
}
|
||||
|
||||
export interface ISpan {
|
||||
interface ISpan {
|
||||
start: ts.LineAndCharacter;
|
||||
end: ts.LineAndCharacter;
|
||||
}
|
||||
|
||||
export interface ILocalizeCall {
|
||||
interface ILocalizeCall {
|
||||
keySpan: ISpan;
|
||||
key: string;
|
||||
valueSpan: ISpan;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface ILocalizeAnalysisResult {
|
||||
interface ILocalizeAnalysisResult {
|
||||
localizeCalls: ILocalizeCall[];
|
||||
nlsExpressions: ISpan[];
|
||||
}
|
||||
|
||||
export interface IPatch {
|
||||
interface IPatch {
|
||||
span: ISpan;
|
||||
content: string;
|
||||
}
|
||||
|
||||
export function fileFrom(file: File, contents: string, path: string = file.path) {
|
||||
function fileFrom(file: File, contents: string, path: string = file.path) {
|
||||
return new File({
|
||||
contents: Buffer.from(contents),
|
||||
base: file.base,
|
||||
|
@ -137,20 +137,20 @@ module nls {
|
|||
});
|
||||
}
|
||||
|
||||
export function mappedPositionFrom(source: string, lc: ts.LineAndCharacter): sm.MappedPosition {
|
||||
function mappedPositionFrom(source: string, lc: ts.LineAndCharacter): sm.MappedPosition {
|
||||
return { source, line: lc.line + 1, column: lc.character };
|
||||
}
|
||||
|
||||
export function lcFrom(position: sm.Position): ts.LineAndCharacter {
|
||||
function lcFrom(position: sm.Position): ts.LineAndCharacter {
|
||||
return { line: position.line - 1, character: position.column };
|
||||
}
|
||||
|
||||
export class SingleFileServiceHost implements ts.LanguageServiceHost {
|
||||
class SingleFileServiceHost implements ts.LanguageServiceHost {
|
||||
|
||||
private file: ts.IScriptSnapshot;
|
||||
private lib: ts.IScriptSnapshot;
|
||||
|
||||
constructor(private options: ts.CompilerOptions, private filename: string, contents: string) {
|
||||
constructor(ts: typeof import('typescript'), private options: ts.CompilerOptions, private filename: string, contents: string) {
|
||||
this.file = ts.ScriptSnapshot.fromString(contents);
|
||||
this.lib = ts.ScriptSnapshot.fromString('');
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ module nls {
|
|||
getDefaultLibFileName = () => 'lib.d.ts';
|
||||
}
|
||||
|
||||
function isCallExpressionWithinTextSpanCollectStep(textSpan: ts.TextSpan, node: ts.Node): CollectStepResult {
|
||||
function isCallExpressionWithinTextSpanCollectStep(ts: typeof import('typescript'), textSpan: ts.TextSpan, node: ts.Node): CollectStepResult {
|
||||
if (!ts.textSpanContainsTextSpan({ start: node.pos, length: node.end - node.pos }, textSpan)) {
|
||||
return CollectStepResult.No;
|
||||
}
|
||||
|
@ -171,14 +171,14 @@ module nls {
|
|||
return node.kind === ts.SyntaxKind.CallExpression ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse;
|
||||
}
|
||||
|
||||
export function analyze(contents: string, options: ts.CompilerOptions = {}): ILocalizeAnalysisResult {
|
||||
function analyze(ts: typeof import('typescript'), contents: string, options: ts.CompilerOptions = {}): ILocalizeAnalysisResult {
|
||||
const filename = 'file.ts';
|
||||
const serviceHost = new SingleFileServiceHost(Object.assign(clone(options), { noResolve: true }), filename, contents);
|
||||
const serviceHost = new SingleFileServiceHost(ts, Object.assign(clone(options), { noResolve: true }), filename, contents);
|
||||
const service = ts.createLanguageService(serviceHost);
|
||||
const sourceFile = ts.createSourceFile(filename, contents, ts.ScriptTarget.ES5, true);
|
||||
|
||||
// all imports
|
||||
const imports = lazy(collect(sourceFile, n => isImportNode(n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse));
|
||||
const imports = lazy(collect(ts, sourceFile, n => isImportNode(ts, n) ? CollectStepResult.YesAndRecurse : CollectStepResult.NoAndRecurse));
|
||||
|
||||
// import nls = require('vs/nls');
|
||||
const importEqualsDeclarations = imports
|
||||
|
@ -215,7 +215,7 @@ module nls {
|
|||
.filter(r => !r.isWriteAccess)
|
||||
|
||||
// find the deepest call expressions AST nodes that contain those references
|
||||
.map(r => collect(sourceFile, n => isCallExpressionWithinTextSpanCollectStep(r.textSpan, n)))
|
||||
.map(r => collect(ts, sourceFile, n => isCallExpressionWithinTextSpanCollectStep(ts, r.textSpan, n)))
|
||||
.map(a => lazy(a).last())
|
||||
.filter(n => !!n)
|
||||
.map(n => <ts.CallExpression>n)
|
||||
|
@ -246,7 +246,7 @@ module nls {
|
|||
// find the deepest call expressions AST nodes that contain those references
|
||||
const localizeCallExpressions = localizeReferences
|
||||
.concat(namedLocalizeReferences)
|
||||
.map(r => collect(sourceFile, n => isCallExpressionWithinTextSpanCollectStep(r.textSpan, n)))
|
||||
.map(r => collect(ts, sourceFile, n => isCallExpressionWithinTextSpanCollectStep(ts, r.textSpan, n)))
|
||||
.map(a => lazy(a).last())
|
||||
.filter(n => !!n)
|
||||
.map(n => <ts.CallExpression>n);
|
||||
|
@ -270,7 +270,7 @@ module nls {
|
|||
};
|
||||
}
|
||||
|
||||
export class TextModel {
|
||||
class TextModel {
|
||||
|
||||
private lines: string[];
|
||||
private lineEndings: string[];
|
||||
|
@ -336,8 +336,8 @@ module nls {
|
|||
}
|
||||
}
|
||||
|
||||
export function patchJavascript(patches: IPatch[], contents: string, moduleId: string): string {
|
||||
const model = new nls.TextModel(contents);
|
||||
function patchJavascript(patches: IPatch[], contents: string, moduleId: string): string {
|
||||
const model = new TextModel(contents);
|
||||
|
||||
// patch the localize calls
|
||||
lazy(patches).reverse().each(p => model.apply(p));
|
||||
|
@ -350,7 +350,7 @@ module nls {
|
|||
return model.toString();
|
||||
}
|
||||
|
||||
export function patchSourcemap(patches: IPatch[], rsm: sm.RawSourceMap, smc: sm.SourceMapConsumer): sm.RawSourceMap {
|
||||
function patchSourcemap(patches: IPatch[], rsm: sm.RawSourceMap, smc: sm.SourceMapConsumer): sm.RawSourceMap {
|
||||
const smg = new sm.SourceMapGenerator({
|
||||
file: rsm.file,
|
||||
sourceRoot: rsm.sourceRoot
|
||||
|
@ -395,8 +395,8 @@ module nls {
|
|||
return JSON.parse(smg.toString());
|
||||
}
|
||||
|
||||
export function patch(moduleId: string, typescript: string, javascript: string, sourcemap: sm.RawSourceMap): INlsStringResult {
|
||||
const { localizeCalls, nlsExpressions } = analyze(typescript);
|
||||
function patch(ts: typeof import('typescript'), moduleId: string, typescript: string, javascript: string, sourcemap: sm.RawSourceMap): INlsStringResult {
|
||||
const { localizeCalls, nlsExpressions } = analyze(ts, typescript);
|
||||
|
||||
if (localizeCalls.length === 0) {
|
||||
return { javascript, sourcemap };
|
||||
|
@ -438,12 +438,14 @@ module nls {
|
|||
}
|
||||
|
||||
export function patchFiles(javascriptFile: File, typescript: string): File[] {
|
||||
const ts = <typeof import('typescript')>require('typescript');
|
||||
// hack?
|
||||
const moduleId = javascriptFile.relative
|
||||
.replace(/\.js$/, '')
|
||||
.replace(/\\/g, '/');
|
||||
|
||||
const { javascript, sourcemap, nlsKeys, nls } = patch(
|
||||
ts,
|
||||
moduleId,
|
||||
typescript,
|
||||
javascriptFile.contents.toString(),
|
||||
|
@ -464,5 +466,3 @@ module nls {
|
|||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export = nls;
|
||||
|
|
|
@ -8,17 +8,12 @@ exports.minifyTask = exports.optimizeTask = exports.loaderConfig = void 0;
|
|||
const es = require("event-stream");
|
||||
const gulp = require("gulp");
|
||||
const concat = require("gulp-concat");
|
||||
const minifyCSS = require("gulp-cssnano");
|
||||
const filter = require("gulp-filter");
|
||||
const flatmap = require("gulp-flatmap");
|
||||
const sourcemaps = require("gulp-sourcemaps");
|
||||
const uglify = require("gulp-uglify");
|
||||
const composer = require("gulp-uglify/composer");
|
||||
const fancyLog = require("fancy-log");
|
||||
const ansiColors = require("ansi-colors");
|
||||
const path = require("path");
|
||||
const pump = require("pump");
|
||||
const terser = require("terser");
|
||||
const VinylFile = require("vinyl");
|
||||
const bundle = require("./bundle");
|
||||
const i18n_1 = require("./i18n");
|
||||
|
@ -124,6 +119,7 @@ function optimizeTask(opts) {
|
|||
const out = opts.out;
|
||||
const fileContentMapper = opts.fileContentMapper || ((contents, _path) => contents);
|
||||
return function () {
|
||||
const sourcemaps = require('gulp-sourcemaps');
|
||||
const bundlesStream = es.through(); // this stream will contain the bundled files
|
||||
const resourcesStream = es.through(); // this stream will contain the resources
|
||||
const bundleInfoStream = es.through(); // this stream will contain bundleInfo.json
|
||||
|
@ -171,6 +167,8 @@ exports.optimizeTask = optimizeTask;
|
|||
* to have a file "context" to include our copyright only once per file.
|
||||
*/
|
||||
function uglifyWithCopyrights() {
|
||||
const composer = require('gulp-uglify/composer');
|
||||
const terser = require('terser');
|
||||
const preserveComments = (f) => {
|
||||
return (_node, comment) => {
|
||||
const text = comment.value;
|
||||
|
@ -212,6 +210,9 @@ function uglifyWithCopyrights() {
|
|||
function minifyTask(src, sourceMapBaseUrl) {
|
||||
const sourceMappingURL = sourceMapBaseUrl ? ((f) => `${sourceMapBaseUrl}/${f.relative}.map`) : undefined;
|
||||
return cb => {
|
||||
const minifyCSS = require('gulp-cssnano');
|
||||
const uglify = require('gulp-uglify');
|
||||
const sourcemaps = require('gulp-sourcemaps');
|
||||
const jsFilter = filter('**/*.js', { restore: true });
|
||||
const cssFilter = filter('**/*.css', { restore: true });
|
||||
pump(gulp.src([src + '/**', '!' + src + '/**/*.map']), jsFilter, sourcemaps.init({ loadMaps: true }), uglifyWithCopyrights(), jsFilter.restore, cssFilter, minifyCSS({ reduceIdents: false }), cssFilter.restore, sourcemaps.mapSources((sourcePath) => {
|
||||
|
|
|
@ -8,17 +8,12 @@
|
|||
import * as es from 'event-stream';
|
||||
import * as gulp from 'gulp';
|
||||
import * as concat from 'gulp-concat';
|
||||
import * as minifyCSS from 'gulp-cssnano';
|
||||
import * as filter from 'gulp-filter';
|
||||
import * as flatmap from 'gulp-flatmap';
|
||||
import * as sourcemaps from 'gulp-sourcemaps';
|
||||
import * as uglify from 'gulp-uglify';
|
||||
import * as composer from 'gulp-uglify/composer';
|
||||
import * as fancyLog from 'fancy-log';
|
||||
import * as ansiColors from 'ansi-colors';
|
||||
import * as path from 'path';
|
||||
import * as pump from 'pump';
|
||||
import * as terser from 'terser';
|
||||
import * as VinylFile from 'vinyl';
|
||||
import * as bundle from './bundle';
|
||||
import { Language, processNlsFiles } from './i18n';
|
||||
|
@ -184,6 +179,8 @@ export function optimizeTask(opts: IOptimizeTaskOpts): () => NodeJS.ReadWriteStr
|
|||
const fileContentMapper = opts.fileContentMapper || ((contents: string, _path: string) => contents);
|
||||
|
||||
return function () {
|
||||
const sourcemaps = <typeof import('gulp-sourcemaps')>require('gulp-sourcemaps');
|
||||
|
||||
const bundlesStream = es.through(); // this stream will contain the bundled files
|
||||
const resourcesStream = es.through(); // this stream will contain the resources
|
||||
const bundleInfoStream = es.through(); // this stream will contain bundleInfo.json
|
||||
|
@ -243,6 +240,9 @@ declare class FileWithCopyright extends VinylFile {
|
|||
* to have a file "context" to include our copyright only once per file.
|
||||
*/
|
||||
function uglifyWithCopyrights(): NodeJS.ReadWriteStream {
|
||||
const composer = <typeof import('gulp-uglify/composer')>require('gulp-uglify/composer');
|
||||
const terser = <typeof import('terser')>require('terser');
|
||||
|
||||
const preserveComments = (f: FileWithCopyright) => {
|
||||
return (_node: any, comment: { value: string; type: string; }) => {
|
||||
const text = comment.value;
|
||||
|
@ -291,6 +291,10 @@ export function minifyTask(src: string, sourceMapBaseUrl?: string): (cb: any) =>
|
|||
const sourceMappingURL = sourceMapBaseUrl ? ((f: any) => `${sourceMapBaseUrl}/${f.relative}.map`) : undefined;
|
||||
|
||||
return cb => {
|
||||
const minifyCSS = <typeof import('gulp-cssnano')>require('gulp-cssnano');
|
||||
const uglify = <typeof import('gulp-uglify')>require('gulp-uglify');
|
||||
const sourcemaps = <typeof import('gulp-sourcemaps')>require('gulp-sourcemaps');
|
||||
|
||||
const jsFilter = filter('**/*.js', { restore: true });
|
||||
const cssFilter = filter('**/*.css', { restore: true });
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*--------------------------------------------------------------------------------------------*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createESMSourcesAndResources2 = exports.extractEditor = void 0;
|
||||
const ts = require("typescript");
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const tss = require("./treeshaking");
|
||||
|
@ -29,6 +28,7 @@ function writeFile(filePath, contents) {
|
|||
}
|
||||
function extractEditor(options) {
|
||||
var _a;
|
||||
const ts = require('typescript');
|
||||
const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.monaco.json')).toString());
|
||||
let compilerOptions;
|
||||
if (tsConfig.extends) {
|
||||
|
@ -115,6 +115,7 @@ function extractEditor(options) {
|
|||
}
|
||||
exports.extractEditor = extractEditor;
|
||||
function createESMSourcesAndResources2(options) {
|
||||
const ts = require('typescript');
|
||||
const SRC_FOLDER = path.join(REPO_ROOT, options.srcFolder);
|
||||
const OUT_FOLDER = path.join(REPO_ROOT, options.outFolder);
|
||||
const OUT_RESOURCES_FOLDER = path.join(REPO_ROOT, options.outResourcesFolder);
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as ts from 'typescript';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as tss from './treeshaking';
|
||||
|
@ -31,6 +30,8 @@ function writeFile(filePath: string, contents: Buffer | string): void {
|
|||
}
|
||||
|
||||
export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: string }): void {
|
||||
const ts = <typeof import('typescript')>require('typescript');
|
||||
|
||||
const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.monaco.json')).toString());
|
||||
let compilerOptions: { [key: string]: any };
|
||||
if (tsConfig.extends) {
|
||||
|
@ -134,6 +135,8 @@ export interface IOptions2 {
|
|||
}
|
||||
|
||||
export function createESMSourcesAndResources2(options: IOptions2): void {
|
||||
const ts = <typeof import('typescript')>require('typescript');
|
||||
|
||||
const SRC_FOLDER = path.join(REPO_ROOT, options.srcFolder);
|
||||
const OUT_FOLDER = path.join(REPO_ROOT, options.outFolder);
|
||||
const OUT_RESOURCES_FOLDER = path.join(REPO_ROOT, options.outResourcesFolder);
|
||||
|
|
|
@ -8,7 +8,6 @@ exports.submitAllStats = exports.createStatsStream = void 0;
|
|||
const es = require("event-stream");
|
||||
const fancyLog = require("fancy-log");
|
||||
const ansiColors = require("ansi-colors");
|
||||
const appInsights = require("applicationinsights");
|
||||
class Entry {
|
||||
constructor(name, totalCount, totalSize) {
|
||||
this.name = name;
|
||||
|
@ -73,6 +72,7 @@ function createStatsStream(group, log) {
|
|||
}
|
||||
exports.createStatsStream = createStatsStream;
|
||||
function submitAllStats(productJson, commit) {
|
||||
const appInsights = require('applicationinsights');
|
||||
const sorted = [];
|
||||
// move entries for single files to the front
|
||||
_entries.forEach(value => {
|
||||
|
|
|
@ -9,7 +9,6 @@ import * as es from 'event-stream';
|
|||
import * as fancyLog from 'fancy-log';
|
||||
import * as ansiColors from 'ansi-colors';
|
||||
import * as File from 'vinyl';
|
||||
import * as appInsights from 'applicationinsights';
|
||||
|
||||
class Entry {
|
||||
constructor(readonly name: string, public totalCount: number, public totalSize: number) { }
|
||||
|
@ -75,6 +74,7 @@ export function createStatsStream(group: string, log?: boolean): es.ThroughStrea
|
|||
}
|
||||
|
||||
export function submitAllStats(productJson: any, commit: string): Promise<boolean> {
|
||||
const appInsights = <typeof import('applicationinsights')>require('applicationinsights');
|
||||
|
||||
const sorted: Entry[] = [];
|
||||
// move entries for single files to the front
|
||||
|
|
|
@ -7,7 +7,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||
exports.shake = exports.toStringShakeLevel = exports.ShakeLevel = void 0;
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const ts = require("typescript");
|
||||
const TYPESCRIPT_LIB_FOLDER = path.dirname(require.resolve('typescript/lib/lib.d.ts'));
|
||||
var ShakeLevel;
|
||||
(function (ShakeLevel) {
|
||||
|
@ -41,7 +40,8 @@ function printDiagnostics(options, diagnostics) {
|
|||
}
|
||||
}
|
||||
function shake(options) {
|
||||
const languageService = createTypeScriptLanguageService(options);
|
||||
const ts = require('typescript');
|
||||
const languageService = createTypeScriptLanguageService(ts, options);
|
||||
const program = languageService.getProgram();
|
||||
const globalDiagnostics = program.getGlobalDiagnostics();
|
||||
if (globalDiagnostics.length > 0) {
|
||||
|
@ -58,14 +58,14 @@ function shake(options) {
|
|||
printDiagnostics(options, semanticDiagnostics);
|
||||
throw new Error(`Compilation Errors encountered.`);
|
||||
}
|
||||
markNodes(languageService, options);
|
||||
return generateResult(languageService, options.shakeLevel);
|
||||
markNodes(ts, languageService, options);
|
||||
return generateResult(ts, languageService, options.shakeLevel);
|
||||
}
|
||||
exports.shake = shake;
|
||||
//#region Discovery, LanguageService & Setup
|
||||
function createTypeScriptLanguageService(options) {
|
||||
function createTypeScriptLanguageService(ts, options) {
|
||||
// Discover referenced files
|
||||
const FILES = discoverAndReadFiles(options);
|
||||
const FILES = discoverAndReadFiles(ts, options);
|
||||
// Add fake usage files
|
||||
options.inlineEntryPoints.forEach((inlineEntryPoint, index) => {
|
||||
FILES[`inlineEntryPoint.${index}.ts`] = inlineEntryPoint;
|
||||
|
@ -76,15 +76,15 @@ function createTypeScriptLanguageService(options) {
|
|||
FILES[typing] = fs.readFileSync(filePath).toString();
|
||||
});
|
||||
// Resolve libs
|
||||
const RESOLVED_LIBS = processLibFiles(options);
|
||||
const RESOLVED_LIBS = processLibFiles(ts, options);
|
||||
const compilerOptions = ts.convertCompilerOptionsFromJson(options.compilerOptions, options.sourcesRoot).options;
|
||||
const host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, compilerOptions);
|
||||
const host = new TypeScriptLanguageServiceHost(ts, RESOLVED_LIBS, FILES, compilerOptions);
|
||||
return ts.createLanguageService(host);
|
||||
}
|
||||
/**
|
||||
* Read imports and follow them until all files have been handled
|
||||
*/
|
||||
function discoverAndReadFiles(options) {
|
||||
function discoverAndReadFiles(ts, options) {
|
||||
const FILES = {};
|
||||
const in_queue = Object.create(null);
|
||||
const queue = [];
|
||||
|
@ -137,7 +137,7 @@ function discoverAndReadFiles(options) {
|
|||
/**
|
||||
* Read lib files and follow lib references
|
||||
*/
|
||||
function processLibFiles(options) {
|
||||
function processLibFiles(ts, options) {
|
||||
const stack = [...options.compilerOptions.lib];
|
||||
const result = {};
|
||||
while (stack.length > 0) {
|
||||
|
@ -161,7 +161,8 @@ function processLibFiles(options) {
|
|||
* A TypeScript language service host
|
||||
*/
|
||||
class TypeScriptLanguageServiceHost {
|
||||
constructor(libs, files, compilerOptions) {
|
||||
constructor(ts, libs, files, compilerOptions) {
|
||||
this._ts = ts;
|
||||
this._libs = libs;
|
||||
this._files = files;
|
||||
this._compilerOptions = compilerOptions;
|
||||
|
@ -183,17 +184,17 @@ class TypeScriptLanguageServiceHost {
|
|||
}
|
||||
getScriptSnapshot(fileName) {
|
||||
if (this._files.hasOwnProperty(fileName)) {
|
||||
return ts.ScriptSnapshot.fromString(this._files[fileName]);
|
||||
return this._ts.ScriptSnapshot.fromString(this._files[fileName]);
|
||||
}
|
||||
else if (this._libs.hasOwnProperty(fileName)) {
|
||||
return ts.ScriptSnapshot.fromString(this._libs[fileName]);
|
||||
return this._ts.ScriptSnapshot.fromString(this._libs[fileName]);
|
||||
}
|
||||
else {
|
||||
return ts.ScriptSnapshot.fromString('');
|
||||
return this._ts.ScriptSnapshot.fromString('');
|
||||
}
|
||||
}
|
||||
getScriptKind(_fileName) {
|
||||
return ts.ScriptKind.TS;
|
||||
return this._ts.ScriptKind.TS;
|
||||
}
|
||||
getCurrentDirectory() {
|
||||
return '';
|
||||
|
@ -240,7 +241,7 @@ function nodeOrChildIsBlack(node) {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
function markNodes(languageService, options) {
|
||||
function markNodes(ts, languageService, options) {
|
||||
const program = languageService.getProgram();
|
||||
if (!program) {
|
||||
throw new Error('Could not get program from language service');
|
||||
|
@ -342,7 +343,7 @@ function markNodes(languageService, options) {
|
|||
if (!referenceSourceFile) {
|
||||
continue;
|
||||
}
|
||||
const referenceNode = getTokenAtPosition(referenceSourceFile, reference.textSpan.start, false, false);
|
||||
const referenceNode = getTokenAtPosition(ts, referenceSourceFile, reference.textSpan.start, false, false);
|
||||
if (ts.isMethodDeclaration(referenceNode.parent)
|
||||
|| ts.isPropertyDeclaration(referenceNode.parent)
|
||||
|| ts.isGetAccessor(referenceNode.parent)
|
||||
|
@ -408,7 +409,7 @@ function markNodes(languageService, options) {
|
|||
}
|
||||
const nodeSourceFile = node.getSourceFile();
|
||||
const loop = (node) => {
|
||||
const [symbol, symbolImportNode] = getRealNodeSymbol(checker, node);
|
||||
const [symbol, symbolImportNode] = getRealNodeSymbol(ts, checker, node);
|
||||
if (symbolImportNode) {
|
||||
setColor(symbolImportNode, 2 /* Black */);
|
||||
}
|
||||
|
@ -420,7 +421,7 @@ function markNodes(languageService, options) {
|
|||
// (they can be the declaration of a module import)
|
||||
continue;
|
||||
}
|
||||
if (options.shakeLevel === 2 /* ClassMembers */ && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration)) && !isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(program, checker, declaration)) {
|
||||
if (options.shakeLevel === 2 /* ClassMembers */ && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration)) && !isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts, program, checker, declaration)) {
|
||||
enqueue_black(declaration.name);
|
||||
for (let j = 0; j < declaration.members.length; j++) {
|
||||
const member = declaration.members[j];
|
||||
|
@ -484,7 +485,7 @@ function nodeIsInItsOwnDeclaration(nodeSourceFile, node, symbol) {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
function generateResult(languageService, shakeLevel) {
|
||||
function generateResult(ts, languageService, shakeLevel) {
|
||||
const program = languageService.getProgram();
|
||||
if (!program) {
|
||||
throw new Error('Could not get program from language service');
|
||||
|
@ -614,11 +615,11 @@ function generateResult(languageService, shakeLevel) {
|
|||
}
|
||||
//#endregion
|
||||
//#region Utils
|
||||
function isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(program, checker, declaration) {
|
||||
function isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts, program, checker, declaration) {
|
||||
if (!program.isSourceFileDefaultLibrary(declaration.getSourceFile()) && declaration.heritageClauses) {
|
||||
for (const heritageClause of declaration.heritageClauses) {
|
||||
for (const type of heritageClause.types) {
|
||||
const symbol = findSymbolFromHeritageType(checker, type);
|
||||
const symbol = findSymbolFromHeritageType(ts, checker, type);
|
||||
if (symbol) {
|
||||
const decl = symbol.valueDeclaration || (symbol.declarations && symbol.declarations[0]);
|
||||
if (decl && program.isSourceFileDefaultLibrary(decl.getSourceFile())) {
|
||||
|
@ -630,22 +631,22 @@ function isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(program, checker,
|
|||
}
|
||||
return false;
|
||||
}
|
||||
function findSymbolFromHeritageType(checker, type) {
|
||||
function findSymbolFromHeritageType(ts, checker, type) {
|
||||
if (ts.isExpressionWithTypeArguments(type)) {
|
||||
return findSymbolFromHeritageType(checker, type.expression);
|
||||
return findSymbolFromHeritageType(ts, checker, type.expression);
|
||||
}
|
||||
if (ts.isIdentifier(type)) {
|
||||
return getRealNodeSymbol(checker, type)[0];
|
||||
return getRealNodeSymbol(ts, checker, type)[0];
|
||||
}
|
||||
if (ts.isPropertyAccessExpression(type)) {
|
||||
return findSymbolFromHeritageType(checker, type.name);
|
||||
return findSymbolFromHeritageType(ts, checker, type.name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Returns the node's symbol and the `import` node (if the symbol resolved from a different module)
|
||||
*/
|
||||
function getRealNodeSymbol(checker, node) {
|
||||
function getRealNodeSymbol(ts, checker, node) {
|
||||
const getPropertySymbolsFromContextualType = ts.getPropertySymbolsFromContextualType;
|
||||
const getContainingObjectLiteralElement = ts.getContainingObjectLiteralElement;
|
||||
const getNameFromPropertyName = ts.getNameFromPropertyName;
|
||||
|
@ -758,7 +759,7 @@ function getRealNodeSymbol(checker, node) {
|
|||
return [null, null];
|
||||
}
|
||||
/** Get the token whose text contains the position */
|
||||
function getTokenAtPosition(sourceFile, position, allowPositionInLeadingTrivia, includeEndPosition) {
|
||||
function getTokenAtPosition(ts, sourceFile, position, allowPositionInLeadingTrivia, includeEndPosition) {
|
||||
let current = sourceFile;
|
||||
outer: while (true) {
|
||||
// find the child that contains 'position'
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as ts from 'typescript';
|
||||
import type * as ts from 'typescript';
|
||||
|
||||
const TYPESCRIPT_LIB_FOLDER = path.dirname(require.resolve('typescript/lib/lib.d.ts'));
|
||||
|
||||
|
@ -82,7 +82,8 @@ function printDiagnostics(options: ITreeShakingOptions, diagnostics: ReadonlyArr
|
|||
}
|
||||
|
||||
export function shake(options: ITreeShakingOptions): ITreeShakingResult {
|
||||
const languageService = createTypeScriptLanguageService(options);
|
||||
const ts = <typeof import('typescript')>require('typescript');
|
||||
const languageService = createTypeScriptLanguageService(ts, options);
|
||||
const program = languageService.getProgram()!;
|
||||
|
||||
const globalDiagnostics = program.getGlobalDiagnostics();
|
||||
|
@ -103,15 +104,15 @@ export function shake(options: ITreeShakingOptions): ITreeShakingResult {
|
|||
throw new Error(`Compilation Errors encountered.`);
|
||||
}
|
||||
|
||||
markNodes(languageService, options);
|
||||
markNodes(ts, languageService, options);
|
||||
|
||||
return generateResult(languageService, options.shakeLevel);
|
||||
return generateResult(ts, languageService, options.shakeLevel);
|
||||
}
|
||||
|
||||
//#region Discovery, LanguageService & Setup
|
||||
function createTypeScriptLanguageService(options: ITreeShakingOptions): ts.LanguageService {
|
||||
function createTypeScriptLanguageService(ts: typeof import('typescript'), options: ITreeShakingOptions): ts.LanguageService {
|
||||
// Discover referenced files
|
||||
const FILES = discoverAndReadFiles(options);
|
||||
const FILES = discoverAndReadFiles(ts, options);
|
||||
|
||||
// Add fake usage files
|
||||
options.inlineEntryPoints.forEach((inlineEntryPoint, index) => {
|
||||
|
@ -125,18 +126,18 @@ function createTypeScriptLanguageService(options: ITreeShakingOptions): ts.Langu
|
|||
});
|
||||
|
||||
// Resolve libs
|
||||
const RESOLVED_LIBS = processLibFiles(options);
|
||||
const RESOLVED_LIBS = processLibFiles(ts, options);
|
||||
|
||||
const compilerOptions = ts.convertCompilerOptionsFromJson(options.compilerOptions, options.sourcesRoot).options;
|
||||
|
||||
const host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, compilerOptions);
|
||||
const host = new TypeScriptLanguageServiceHost(ts, RESOLVED_LIBS, FILES, compilerOptions);
|
||||
return ts.createLanguageService(host);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read imports and follow them until all files have been handled
|
||||
*/
|
||||
function discoverAndReadFiles(options: ITreeShakingOptions): IFileMap {
|
||||
function discoverAndReadFiles(ts: typeof import('typescript'), options: ITreeShakingOptions): IFileMap {
|
||||
const FILES: IFileMap = {};
|
||||
|
||||
const in_queue: { [module: string]: boolean; } = Object.create(null);
|
||||
|
@ -199,7 +200,7 @@ function discoverAndReadFiles(options: ITreeShakingOptions): IFileMap {
|
|||
/**
|
||||
* Read lib files and follow lib references
|
||||
*/
|
||||
function processLibFiles(options: ITreeShakingOptions): ILibMap {
|
||||
function processLibFiles(ts: typeof import('typescript'), options: ITreeShakingOptions): ILibMap {
|
||||
|
||||
const stack: string[] = [...options.compilerOptions.lib];
|
||||
const result: ILibMap = {};
|
||||
|
@ -232,11 +233,13 @@ interface IFileMap { [fileName: string]: string; }
|
|||
*/
|
||||
class TypeScriptLanguageServiceHost implements ts.LanguageServiceHost {
|
||||
|
||||
private readonly _ts: typeof import('typescript');
|
||||
private readonly _libs: ILibMap;
|
||||
private readonly _files: IFileMap;
|
||||
private readonly _compilerOptions: ts.CompilerOptions;
|
||||
|
||||
constructor(libs: ILibMap, files: IFileMap, compilerOptions: ts.CompilerOptions) {
|
||||
constructor(ts: typeof import('typescript'), libs: ILibMap, files: IFileMap, compilerOptions: ts.CompilerOptions) {
|
||||
this._ts = ts;
|
||||
this._libs = libs;
|
||||
this._files = files;
|
||||
this._compilerOptions = compilerOptions;
|
||||
|
@ -262,15 +265,15 @@ class TypeScriptLanguageServiceHost implements ts.LanguageServiceHost {
|
|||
}
|
||||
getScriptSnapshot(fileName: string): ts.IScriptSnapshot {
|
||||
if (this._files.hasOwnProperty(fileName)) {
|
||||
return ts.ScriptSnapshot.fromString(this._files[fileName]);
|
||||
return this._ts.ScriptSnapshot.fromString(this._files[fileName]);
|
||||
} else if (this._libs.hasOwnProperty(fileName)) {
|
||||
return ts.ScriptSnapshot.fromString(this._libs[fileName]);
|
||||
return this._ts.ScriptSnapshot.fromString(this._libs[fileName]);
|
||||
} else {
|
||||
return ts.ScriptSnapshot.fromString('');
|
||||
return this._ts.ScriptSnapshot.fromString('');
|
||||
}
|
||||
}
|
||||
getScriptKind(_fileName: string): ts.ScriptKind {
|
||||
return ts.ScriptKind.TS;
|
||||
return this._ts.ScriptKind.TS;
|
||||
}
|
||||
getCurrentDirectory(): string {
|
||||
return '';
|
||||
|
@ -320,7 +323,7 @@ function nodeOrChildIsBlack(node: ts.Node): boolean {
|
|||
return false;
|
||||
}
|
||||
|
||||
function markNodes(languageService: ts.LanguageService, options: ITreeShakingOptions) {
|
||||
function markNodes(ts: typeof import('typescript'), languageService: ts.LanguageService, options: ITreeShakingOptions) {
|
||||
const program = languageService.getProgram();
|
||||
if (!program) {
|
||||
throw new Error('Could not get program from language service');
|
||||
|
@ -446,7 +449,7 @@ function markNodes(languageService: ts.LanguageService, options: ITreeShakingOpt
|
|||
continue;
|
||||
}
|
||||
|
||||
const referenceNode = getTokenAtPosition(referenceSourceFile, reference.textSpan.start, false, false);
|
||||
const referenceNode = getTokenAtPosition(ts, referenceSourceFile, reference.textSpan.start, false, false);
|
||||
if (
|
||||
ts.isMethodDeclaration(referenceNode.parent)
|
||||
|| ts.isPropertyDeclaration(referenceNode.parent)
|
||||
|
@ -522,7 +525,7 @@ function markNodes(languageService: ts.LanguageService, options: ITreeShakingOpt
|
|||
const nodeSourceFile = node.getSourceFile();
|
||||
|
||||
const loop = (node: ts.Node) => {
|
||||
const [symbol, symbolImportNode] = getRealNodeSymbol(checker, node);
|
||||
const [symbol, symbolImportNode] = getRealNodeSymbol(ts, checker, node);
|
||||
if (symbolImportNode) {
|
||||
setColor(symbolImportNode, NodeColor.Black);
|
||||
}
|
||||
|
@ -536,7 +539,7 @@ function markNodes(languageService: ts.LanguageService, options: ITreeShakingOpt
|
|||
continue;
|
||||
}
|
||||
|
||||
if (options.shakeLevel === ShakeLevel.ClassMembers && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration)) && !isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(program, checker, declaration)) {
|
||||
if (options.shakeLevel === ShakeLevel.ClassMembers && (ts.isClassDeclaration(declaration) || ts.isInterfaceDeclaration(declaration)) && !isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts, program, checker, declaration)) {
|
||||
enqueue_black(declaration.name!);
|
||||
|
||||
for (let j = 0; j < declaration.members.length; j++) {
|
||||
|
@ -607,7 +610,7 @@ function nodeIsInItsOwnDeclaration(nodeSourceFile: ts.SourceFile, node: ts.Node,
|
|||
return false;
|
||||
}
|
||||
|
||||
function generateResult(languageService: ts.LanguageService, shakeLevel: ShakeLevel): ITreeShakingResult {
|
||||
function generateResult(ts: typeof import('typescript'), languageService: ts.LanguageService, shakeLevel: ShakeLevel): ITreeShakingResult {
|
||||
const program = languageService.getProgram();
|
||||
if (!program) {
|
||||
throw new Error('Could not get program from language service');
|
||||
|
@ -752,11 +755,11 @@ function generateResult(languageService: ts.LanguageService, shakeLevel: ShakeLe
|
|||
|
||||
//#region Utils
|
||||
|
||||
function isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(program: ts.Program, checker: ts.TypeChecker, declaration: ts.ClassDeclaration | ts.InterfaceDeclaration): boolean {
|
||||
function isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(ts: typeof import('typescript'), program: ts.Program, checker: ts.TypeChecker, declaration: ts.ClassDeclaration | ts.InterfaceDeclaration): boolean {
|
||||
if (!program.isSourceFileDefaultLibrary(declaration.getSourceFile()) && declaration.heritageClauses) {
|
||||
for (const heritageClause of declaration.heritageClauses) {
|
||||
for (const type of heritageClause.types) {
|
||||
const symbol = findSymbolFromHeritageType(checker, type);
|
||||
const symbol = findSymbolFromHeritageType(ts, checker, type);
|
||||
if (symbol) {
|
||||
const decl = symbol.valueDeclaration || (symbol.declarations && symbol.declarations[0]);
|
||||
if (decl && program.isSourceFileDefaultLibrary(decl.getSourceFile())) {
|
||||
|
@ -769,15 +772,15 @@ function isLocalCodeExtendingOrInheritingFromDefaultLibSymbol(program: ts.Progra
|
|||
return false;
|
||||
}
|
||||
|
||||
function findSymbolFromHeritageType(checker: ts.TypeChecker, type: ts.ExpressionWithTypeArguments | ts.Expression | ts.PrivateIdentifier): ts.Symbol | null {
|
||||
function findSymbolFromHeritageType(ts: typeof import('typescript'), checker: ts.TypeChecker, type: ts.ExpressionWithTypeArguments | ts.Expression | ts.PrivateIdentifier): ts.Symbol | null {
|
||||
if (ts.isExpressionWithTypeArguments(type)) {
|
||||
return findSymbolFromHeritageType(checker, type.expression);
|
||||
return findSymbolFromHeritageType(ts, checker, type.expression);
|
||||
}
|
||||
if (ts.isIdentifier(type)) {
|
||||
return getRealNodeSymbol(checker, type)[0];
|
||||
return getRealNodeSymbol(ts, checker, type)[0];
|
||||
}
|
||||
if (ts.isPropertyAccessExpression(type)) {
|
||||
return findSymbolFromHeritageType(checker, type.name);
|
||||
return findSymbolFromHeritageType(ts, checker, type.name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -785,7 +788,7 @@ function findSymbolFromHeritageType(checker: ts.TypeChecker, type: ts.Expression
|
|||
/**
|
||||
* Returns the node's symbol and the `import` node (if the symbol resolved from a different module)
|
||||
*/
|
||||
function getRealNodeSymbol(checker: ts.TypeChecker, node: ts.Node): [ts.Symbol | null, ts.Declaration | null] {
|
||||
function getRealNodeSymbol(ts: typeof import('typescript'), checker: ts.TypeChecker, node: ts.Node): [ts.Symbol | null, ts.Declaration | null] {
|
||||
|
||||
// Use some TypeScript internals to avoid code duplication
|
||||
type ObjectLiteralElementWithName = ts.ObjectLiteralElement & { name: ts.PropertyName; parent: ts.ObjectLiteralExpression | ts.JsxAttributes };
|
||||
|
@ -913,7 +916,7 @@ function getRealNodeSymbol(checker: ts.TypeChecker, node: ts.Node): [ts.Symbol |
|
|||
}
|
||||
|
||||
/** Get the token whose text contains the position */
|
||||
function getTokenAtPosition(sourceFile: ts.SourceFile, position: number, allowPositionInLeadingTrivia: boolean, includeEndPosition: boolean): ts.Node {
|
||||
function getTokenAtPosition(ts: typeof import('typescript'), sourceFile: ts.SourceFile, position: number, allowPositionInLeadingTrivia: boolean, includeEndPosition: boolean): ts.Node {
|
||||
let current: ts.Node = sourceFile;
|
||||
outer: while (true) {
|
||||
// find the child that contains 'position'
|
||||
|
|
Loading…
Reference in New Issue