提交 d729e505 编写于 作者: A Alex Dima

Fix standalone editor gulp scripts.

Tree Shaking:
- do not proceed with tree shaking when there are compilation errors
- load .d.ts files in the language service
- adopt TS 3.1.1 in symbol resolution
- use the real tsconfig.json / with "node" resolution

Bundling:
- fix issue where files were being looked for in out-build instead of out-editor-build
上级 4312f42a
......@@ -28,7 +28,7 @@ var editorEntryPoints = [
name: 'vs/editor/editor.main',
include: [],
exclude: ['vs/css', 'vs/nls'],
prepend: ['out-build/vs/css.js', 'out-build/vs/nls.js'],
prepend: ['out-editor-build/vs/css.js', 'out-editor-build/vs/nls.js'],
},
{
name: 'vs/base/common/worker/simpleWorker',
......@@ -79,16 +79,21 @@ gulp.task('extract-editor-src', ['clean-editor-src'], function () {
apiusages,
extrausages
],
typings: [
'typings/lib.ie11_safe_es6.d.ts',
'typings/thenable.d.ts',
'typings/es6-promise.d.ts',
'typings/require-monaco.d.ts',
'vs/monaco.d.ts'
],
libs: [
`lib.d.ts`,
`lib.es2015.collection.d.ts`
`lib.es5.d.ts`,
`lib.dom.d.ts`,
`lib.webworker.importscripts.d.ts`
],
redirects: {
'vs/base/browser/ui/octiconLabel/octiconLabel': 'vs/base/browser/ui/octiconLabel/octiconLabel.mock',
},
compilerOptions: {
module: 2, // ModuleKind.AMD
},
shakeLevel: 2, // 0-Files, 1-InnerFile, 2-ClassMembers
importIgnorePattern: /^vs\/css!/,
destRoot: path.join(root, 'out-editor-src')
......@@ -108,6 +113,8 @@ gulp.task('optimize-editor', ['clean-optimized-editor', 'compile-editor-build'],
loaderConfig: {
paths: {
'vs': 'out-editor-build/vs',
'vs/css': 'out-editor-build/vs/css.build',
'vs/nls': 'out-editor-build/vs/nls.build',
'vscode': 'empty:'
}
},
......@@ -125,7 +132,7 @@ gulp.task('clean-editor-esm', util.rimraf('out-editor-esm'));
gulp.task('extract-editor-esm', ['clean-editor-esm', 'clean-editor-distro', 'extract-editor-src'], function () {
standalone.createESMSourcesAndResources2({
srcFolder: './out-editor-src',
outFolder: './out-editor-esm/src',
outFolder: './out-editor-esm',
outResourcesFolder: './out-monaco-editor-core/esm',
ignores: [
'inlineEntryPoint:0.ts',
......
......@@ -32,8 +32,12 @@ function bundle(entryPoints, config, callback) {
var loader = loaderModule.exports;
config.isBuild = true;
config.paths = config.paths || {};
config.paths['vs/nls'] = 'out-build/vs/nls.build';
config.paths['vs/css'] = 'out-build/vs/css.build';
if (!config.paths['vs/nls']) {
config.paths['vs/nls'] = 'out-build/vs/nls.build';
}
if (!config.paths['vs/css']) {
config.paths['vs/css'] = 'out-build/vs/css.build';
}
loader.config(config);
loader(['require'], function (localRequire) {
var resolvePath = function (path) {
......
......@@ -123,8 +123,12 @@ export function bundle(entryPoints: IEntryPoint[], config: ILoaderConfig, callba
const loader: any = loaderModule.exports;
config.isBuild = true;
config.paths = config.paths || {};
config.paths['vs/nls'] = 'out-build/vs/nls.build';
config.paths['vs/css'] = 'out-build/vs/css.build';
if (!config.paths['vs/nls']) {
config.paths['vs/nls'] = 'out-build/vs/nls.build';
}
if (!config.paths['vs/css']) {
config.paths['vs/css'] = 'out-build/vs/css.build';
}
loader.config(config);
loader(['require'], (localRequire: any) => {
......
......@@ -27,6 +27,13 @@ function writeFile(filePath, contents) {
fs.writeFileSync(filePath, contents);
}
function extractEditor(options) {
var tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString());
tsConfig.compilerOptions.noUnusedLocals = false;
tsConfig.compilerOptions.preserveConstEnums = false;
tsConfig.compilerOptions.declaration = false;
delete tsConfig.compilerOptions.types;
tsConfig.exclude = [];
options.compilerOptions = tsConfig.compilerOptions;
var result = tss.shake(options);
for (var fileName in result) {
if (result.hasOwnProperty(fileName)) {
......@@ -73,25 +80,16 @@ function extractEditor(options) {
}
}
}
var tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString());
tsConfig.compilerOptions.noUnusedLocals = false;
tsConfig.compilerOptions.preserveConstEnums = false;
tsConfig.compilerOptions.declaration = false;
writeOutputFile('tsconfig.json', JSON.stringify(tsConfig, null, '\t'));
[
'vs/css.build.js',
'vs/css.d.ts',
'vs/css.js',
'vs/loader.js',
'vs/monaco.d.ts',
'vs/nls.build.js',
'vs/nls.d.ts',
'vs/nls.js',
'vs/nls.mock.ts',
'typings/lib.ie11_safe_es6.d.ts',
'typings/thenable.d.ts',
'typings/es6-promise.d.ts',
'typings/require.d.ts',
].forEach(copyFile);
}
exports.extractEditor = extractEditor;
......@@ -102,7 +100,7 @@ function createESMSourcesAndResources2(options) {
var getDestAbsoluteFilePath = function (file) {
var dest = options.renames[file.replace(/\\/g, '/')] || file;
if (dest === 'tsconfig.json') {
return path.join(OUT_FOLDER, "../tsconfig.json");
return path.join(OUT_FOLDER, "tsconfig.json");
}
if (/\.ts$/.test(dest)) {
return path.join(OUT_FOLDER, dest);
......@@ -117,11 +115,8 @@ function createESMSourcesAndResources2(options) {
}
if (file === 'tsconfig.json') {
var tsConfig = JSON.parse(fs.readFileSync(path.join(SRC_FOLDER, file)).toString());
tsConfig.compilerOptions.moduleResolution = undefined;
tsConfig.compilerOptions.baseUrl = undefined;
tsConfig.compilerOptions.module = 'es6';
tsConfig.compilerOptions.rootDir = 'src';
tsConfig.compilerOptions.outDir = path.relative(path.dirname(OUT_FOLDER), OUT_RESOURCES_FOLDER);
tsConfig.compilerOptions.outDir = path.join(path.relative(OUT_FOLDER, OUT_RESOURCES_FOLDER), 'vs');
write(getDestAbsoluteFilePath(file), JSON.stringify(tsConfig, null, '\t'));
continue;
}
......
......@@ -31,6 +31,15 @@ function writeFile(filePath: string, contents: Buffer | string): void {
}
export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: string }): void {
const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString());
tsConfig.compilerOptions.noUnusedLocals = false;
tsConfig.compilerOptions.preserveConstEnums = false;
tsConfig.compilerOptions.declaration = false;
delete tsConfig.compilerOptions.types;
tsConfig.exclude = [];
options.compilerOptions = tsConfig.compilerOptions;
let result = tss.shake(options);
for (let fileName in result) {
if (result.hasOwnProperty(fileName)) {
......@@ -79,10 +88,6 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str
}
}
const tsConfig = JSON.parse(fs.readFileSync(path.join(options.sourcesRoot, 'tsconfig.json')).toString());
tsConfig.compilerOptions.noUnusedLocals = false;
tsConfig.compilerOptions.preserveConstEnums = false;
tsConfig.compilerOptions.declaration = false;
writeOutputFile('tsconfig.json', JSON.stringify(tsConfig, null, '\t'));
[
......@@ -90,15 +95,10 @@ export function extractEditor(options: tss.ITreeShakingOptions & { destRoot: str
'vs/css.d.ts',
'vs/css.js',
'vs/loader.js',
'vs/monaco.d.ts',
'vs/nls.build.js',
'vs/nls.d.ts',
'vs/nls.js',
'vs/nls.mock.ts',
'typings/lib.ie11_safe_es6.d.ts',
'typings/thenable.d.ts',
'typings/es6-promise.d.ts',
'typings/require.d.ts',
].forEach(copyFile);
}
......@@ -118,7 +118,7 @@ export function createESMSourcesAndResources2(options: IOptions2): void {
const getDestAbsoluteFilePath = (file: string): string => {
let dest = options.renames[file.replace(/\\/g, '/')] || file;
if (dest === 'tsconfig.json') {
return path.join(OUT_FOLDER, `../tsconfig.json`);
return path.join(OUT_FOLDER, `tsconfig.json`);
}
if (/\.ts$/.test(dest)) {
return path.join(OUT_FOLDER, dest);
......@@ -136,11 +136,8 @@ export function createESMSourcesAndResources2(options: IOptions2): void {
if (file === 'tsconfig.json') {
const tsConfig = JSON.parse(fs.readFileSync(path.join(SRC_FOLDER, file)).toString());
tsConfig.compilerOptions.moduleResolution = undefined;
tsConfig.compilerOptions.baseUrl = undefined;
tsConfig.compilerOptions.module = 'es6';
tsConfig.compilerOptions.rootDir = 'src';
tsConfig.compilerOptions.outDir = path.relative(path.dirname(OUT_FOLDER), OUT_RESOURCES_FOLDER);
tsConfig.compilerOptions.outDir = path.join(path.relative(OUT_FOLDER, OUT_RESOURCES_FOLDER), 'vs');
write(getDestAbsoluteFilePath(file), JSON.stringify(tsConfig, null, '\t'));
continue;
}
......
......@@ -14,8 +14,39 @@ var ShakeLevel;
ShakeLevel[ShakeLevel["InnerFile"] = 1] = "InnerFile";
ShakeLevel[ShakeLevel["ClassMembers"] = 2] = "ClassMembers";
})(ShakeLevel = exports.ShakeLevel || (exports.ShakeLevel = {}));
function printDiagnostics(diagnostics) {
for (var i = 0; i < diagnostics.length; i++) {
var diag = diagnostics[i];
var result = '';
if (diag.file) {
result += diag.file.fileName + ": ";
}
if (diag.file && diag.start) {
var location_1 = diag.file.getLineAndCharacterOfPosition(diag.start);
result += "- " + (location_1.line + 1) + "," + location_1.character + " - ";
}
result += JSON.stringify(diag.messageText);
console.log(result);
}
}
function shake(options) {
var languageService = createTypeScriptLanguageService(options);
var program = languageService.getProgram();
var globalDiagnostics = program.getGlobalDiagnostics();
if (globalDiagnostics.length > 0) {
printDiagnostics(globalDiagnostics);
throw new Error("Compilation Errors encountered.");
}
var syntacticDiagnostics = program.getSyntacticDiagnostics();
if (syntacticDiagnostics.length > 0) {
printDiagnostics(syntacticDiagnostics);
throw new Error("Compilation Errors encountered.");
}
var semanticDiagnostics = program.getSemanticDiagnostics();
if (semanticDiagnostics.length > 0) {
printDiagnostics(semanticDiagnostics);
throw new Error("Compilation Errors encountered.");
}
markNodes(languageService, options);
return generateResult(languageService, options.shakeLevel);
}
......@@ -28,13 +59,18 @@ function createTypeScriptLanguageService(options) {
options.inlineEntryPoints.forEach(function (inlineEntryPoint, index) {
FILES["inlineEntryPoint:" + index + ".ts"] = inlineEntryPoint;
});
// Add additional typings
options.typings.forEach(function (typing) {
var filePath = path.join(options.sourcesRoot, typing);
FILES[typing] = fs.readFileSync(filePath).toString();
});
// Resolve libs
var RESOLVED_LIBS = {};
options.libs.forEach(function (filename) {
var filepath = path.join(TYPESCRIPT_LIB_FOLDER, filename);
RESOLVED_LIBS["defaultLib:" + filename] = fs.readFileSync(filepath).toString();
});
var host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, options.compilerOptions);
var host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, ts.convertCompilerOptionsFromJson(options.compilerOptions, "").options);
return ts.createLanguageService(host);
}
/**
......@@ -57,7 +93,7 @@ function discoverAndReadFiles(options) {
var dts_filename = path.join(options.sourcesRoot, moduleId + '.d.ts');
if (fs.existsSync(dts_filename)) {
var dts_filecontents = fs.readFileSync(dts_filename).toString();
FILES[moduleId + '.d.ts'] = dts_filecontents;
FILES[moduleId + ".d.ts"] = dts_filecontents;
continue;
}
var ts_filename = void 0;
......@@ -81,7 +117,7 @@ function discoverAndReadFiles(options) {
}
enqueue(importedModuleId);
}
FILES[moduleId + '.ts'] = ts_filecontents;
FILES[moduleId + ".ts"] = ts_filecontents;
}
return FILES;
}
......@@ -517,68 +553,9 @@ function generateResult(languageService, shakeLevel) {
* Returns the node's symbol and the `import` node (if the symbol resolved from a different module)
*/
function getRealNodeSymbol(checker, node) {
/**
* Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 }
*/
/* @internal */
function getContainingObjectLiteralElement(node) {
switch (node.kind) {
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.NumericLiteral:
if (node.parent.kind === ts.SyntaxKind.ComputedPropertyName) {
return ts.isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined;
}
// falls through
case ts.SyntaxKind.Identifier:
return ts.isObjectLiteralElement(node.parent) &&
(node.parent.parent.kind === ts.SyntaxKind.ObjectLiteralExpression || node.parent.parent.kind === ts.SyntaxKind.JsxAttributes) &&
node.parent.name === node ? node.parent : undefined;
}
return undefined;
}
function getPropertySymbolsFromType(type, propName) {
function getTextOfPropertyName(name) {
function isStringOrNumericLiteral(node) {
var kind = node.kind;
return kind === ts.SyntaxKind.StringLiteral
|| kind === ts.SyntaxKind.NumericLiteral;
}
switch (name.kind) {
case ts.SyntaxKind.Identifier:
return name.text;
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.NumericLiteral:
return name.text;
case ts.SyntaxKind.ComputedPropertyName:
return isStringOrNumericLiteral(name.expression) ? name.expression.text : undefined;
}
}
var name = getTextOfPropertyName(propName);
if (name && type) {
var result = [];
var symbol_1 = type.getProperty(name);
if (type.flags & ts.TypeFlags.Union) {
for (var _i = 0, _a = type.types; _i < _a.length; _i++) {
var t = _a[_i];
var symbol_2 = t.getProperty(name);
if (symbol_2) {
result.push(symbol_2);
}
}
return result;
}
if (symbol_1) {
result.push(symbol_1);
return result;
}
}
return undefined;
}
function getPropertySymbolsFromContextualType(typeChecker, node) {
var objectLiteral = node.parent;
var contextualType = typeChecker.getContextualType(objectLiteral);
return getPropertySymbolsFromType(contextualType, node.name);
}
var getPropertySymbolsFromContextualType = ts.getPropertySymbolsFromContextualType;
var getContainingObjectLiteralElement = ts.getContainingObjectLiteralElement;
var getNameFromPropertyName = ts.getNameFromPropertyName;
// Go to the original declaration for cases:
//
// (1) when the aliased symbol was declared in the location(parent).
......@@ -606,8 +583,13 @@ function getRealNodeSymbol(checker, node) {
return [null, null];
}
}
var parent = node.parent;
var symbol = checker.getSymbolAtLocation(node);
var importNode = null;
// If this is an alias, and the request came at the declaration location
// get the aliased symbol instead. This allows for goto def on an import e.g.
// import {A, B} from "mod";
// to jump to the implementation directly.
if (symbol && symbol.flags & ts.SymbolFlags.Alias && shouldSkipAlias(node, symbol.declarations[0])) {
var aliased = checker.getAliasedSymbol(symbol);
if (aliased.declarations) {
......@@ -636,13 +618,22 @@ function getRealNodeSymbol(checker, node) {
// pr/*destination*/op1: number
// }
// bar<Test>(({pr/*goto*/op1})=>{});
if (ts.isPropertyName(node) && ts.isBindingElement(node.parent) && ts.isObjectBindingPattern(node.parent.parent) &&
(node === (node.parent.propertyName || node.parent.name))) {
var type = checker.getTypeAtLocation(node.parent.parent);
if (type) {
var propSymbols = getPropertySymbolsFromType(type, node);
if (propSymbols) {
symbol = propSymbols[0];
if (ts.isPropertyName(node) && ts.isBindingElement(parent) && ts.isObjectBindingPattern(parent.parent) &&
(node === (parent.propertyName || parent.name))) {
var name_1 = getNameFromPropertyName(node);
var type = checker.getTypeAtLocation(parent.parent);
if (name_1 && type) {
if (type.isUnion()) {
var prop = type.types[0].getProperty(name_1);
if (prop) {
symbol = prop;
}
}
else {
var prop = type.getProperty(name_1);
if (prop) {
symbol = prop;
}
}
}
}
......@@ -656,10 +647,13 @@ function getRealNodeSymbol(checker, node) {
// function Foo(arg: Props) {}
// Foo( { pr/*1*/op1: 10, prop2: false })
var element = getContainingObjectLiteralElement(node);
if (element && checker.getContextualType(element.parent)) {
var propertySymbols = getPropertySymbolsFromContextualType(checker, element);
if (propertySymbols) {
symbol = propertySymbols[0];
if (element) {
var contextualType = element && checker.getContextualType(element.parent);
if (contextualType) {
var propertySymbols = getPropertySymbolsFromContextualType(element, checker, contextualType, /*unionSymbolOk*/ false);
if (propertySymbols) {
symbol = propertySymbols[0];
}
}
}
}
......
......@@ -36,10 +36,14 @@ export interface ITreeShakingOptions {
* e.g. `lib.d.ts`, `lib.es2015.collection.d.ts`
*/
libs: string[];
/**
* Other .d.ts files
*/
typings: string[];
/**
* TypeScript compiler options.
*/
compilerOptions: ts.CompilerOptions;
compilerOptions?: any;
/**
* The shake level to perform.
*/
......@@ -56,8 +60,43 @@ export interface ITreeShakingResult {
[file: string]: string;
}
function printDiagnostics(diagnostics: ReadonlyArray<ts.Diagnostic>): void {
for (let i = 0; i < diagnostics.length; i++) {
const diag = diagnostics[i];
let result = '';
if (diag.file) {
result += `${diag.file.fileName}: `;
}
if (diag.file && diag.start) {
let location = diag.file.getLineAndCharacterOfPosition(diag.start);
result += `- ${location.line + 1},${location.character} - `
}
result += JSON.stringify(diag.messageText);
console.log(result);
}
}
export function shake(options: ITreeShakingOptions): ITreeShakingResult {
const languageService = createTypeScriptLanguageService(options);
const program = languageService.getProgram()!;
const globalDiagnostics = program.getGlobalDiagnostics();
if (globalDiagnostics.length > 0) {
printDiagnostics(globalDiagnostics);
throw new Error(`Compilation Errors encountered.`);
}
const syntacticDiagnostics = program.getSyntacticDiagnostics();
if (syntacticDiagnostics.length > 0) {
printDiagnostics(syntacticDiagnostics);
throw new Error(`Compilation Errors encountered.`);
}
const semanticDiagnostics = program.getSemanticDiagnostics();
if (semanticDiagnostics.length > 0) {
printDiagnostics(semanticDiagnostics);
throw new Error(`Compilation Errors encountered.`);
}
markNodes(languageService, options);
......@@ -74,6 +113,12 @@ function createTypeScriptLanguageService(options: ITreeShakingOptions): ts.Langu
FILES[`inlineEntryPoint:${index}.ts`] = inlineEntryPoint;
});
// Add additional typings
options.typings.forEach((typing) => {
const filePath = path.join(options.sourcesRoot, typing);
FILES[typing] = fs.readFileSync(filePath).toString();
});
// Resolve libs
const RESOLVED_LIBS: ILibMap = {};
options.libs.forEach((filename) => {
......@@ -81,7 +126,7 @@ function createTypeScriptLanguageService(options: ITreeShakingOptions): ts.Langu
RESOLVED_LIBS[`defaultLib:${filename}`] = fs.readFileSync(filepath).toString();
});
const host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, options.compilerOptions);
const host = new TypeScriptLanguageServiceHost(RESOLVED_LIBS, FILES, ts.convertCompilerOptionsFromJson(options.compilerOptions, ``).options);
return ts.createLanguageService(host);
}
......@@ -109,7 +154,7 @@ function discoverAndReadFiles(options: ITreeShakingOptions): IFileMap {
const dts_filename = path.join(options.sourcesRoot, moduleId + '.d.ts');
if (fs.existsSync(dts_filename)) {
const dts_filecontents = fs.readFileSync(dts_filename).toString();
FILES[moduleId + '.d.ts'] = dts_filecontents;
FILES[`${moduleId}.d.ts`] = dts_filecontents;
continue;
}
......@@ -136,7 +181,7 @@ function discoverAndReadFiles(options: ITreeShakingOptions): IFileMap {
enqueue(importedModuleId);
}
FILES[moduleId + '.ts'] = ts_filecontents;
FILES[`${moduleId}.ts`] = ts_filecontents;
}
return FILES;
......@@ -636,73 +681,12 @@ function generateResult(languageService: ts.LanguageService, shakeLevel: ShakeLe
* 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] {
/**
* Returns the containing object literal property declaration given a possible name node, e.g. "a" in x = { "a": 1 }
*/
/* @internal */
function getContainingObjectLiteralElement(node: ts.Node): ts.ObjectLiteralElement | undefined {
switch (node.kind) {
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.NumericLiteral:
if (node.parent.kind === ts.SyntaxKind.ComputedPropertyName) {
return ts.isObjectLiteralElement(node.parent.parent) ? node.parent.parent : undefined;
}
// falls through
case ts.SyntaxKind.Identifier:
return ts.isObjectLiteralElement(node.parent) &&
(node.parent.parent.kind === ts.SyntaxKind.ObjectLiteralExpression || node.parent.parent.kind === ts.SyntaxKind.JsxAttributes) &&
node.parent.name === node ? node.parent : undefined;
}
return undefined;
}
function getPropertySymbolsFromType(type: ts.Type, propName: ts.PropertyName) {
function getTextOfPropertyName(name: ts.PropertyName): string {
function isStringOrNumericLiteral(node: ts.Node): node is ts.StringLiteral | ts.NumericLiteral {
const kind = node.kind;
return kind === ts.SyntaxKind.StringLiteral
|| kind === ts.SyntaxKind.NumericLiteral;
}
switch (name.kind) {
case ts.SyntaxKind.Identifier:
return name.text;
case ts.SyntaxKind.StringLiteral:
case ts.SyntaxKind.NumericLiteral:
return name.text;
case ts.SyntaxKind.ComputedPropertyName:
return isStringOrNumericLiteral(name.expression) ? name.expression.text : undefined!;
}
}
const name = getTextOfPropertyName(propName);
if (name && type) {
const result: ts.Symbol[] = [];
const symbol = type.getProperty(name);
if (type.flags & ts.TypeFlags.Union) {
for (const t of (<ts.UnionType>type).types) {
const symbol = t.getProperty(name);
if (symbol) {
result.push(symbol);
}
}
return result;
}
if (symbol) {
result.push(symbol);
return result;
}
}
return undefined;
}
function getPropertySymbolsFromContextualType(typeChecker: ts.TypeChecker, node: ts.ObjectLiteralElement): ts.Symbol[] {
const objectLiteral = <ts.ObjectLiteralExpression | ts.JsxAttributes>node.parent;
const contextualType = typeChecker.getContextualType(objectLiteral)!;
return getPropertySymbolsFromType(contextualType, node.name!)!;
}
// Use some TypeScript internals to avoid code duplication
type ObjectLiteralElementWithName = ts.ObjectLiteralElement & { name: ts.PropertyName; parent: ts.ObjectLiteralExpression | ts.JsxAttributes };
const getPropertySymbolsFromContextualType: (node: ObjectLiteralElementWithName, checker: ts.TypeChecker, contextualType: ts.Type, unionSymbolOk: boolean) => ReadonlyArray<ts.Symbol> = (<any>ts).getPropertySymbolsFromContextualType;
const getContainingObjectLiteralElement: (node: ts.Node) => ObjectLiteralElementWithName | undefined = (<any>ts).getContainingObjectLiteralElement;
const getNameFromPropertyName: (name: ts.PropertyName) => string | undefined = (<any>ts).getNameFromPropertyName;
// Go to the original declaration for cases:
//
......@@ -733,8 +717,14 @@ function getRealNodeSymbol(checker: ts.TypeChecker, node: ts.Node): [ts.Symbol |
}
}
const { parent } = node;
let symbol = checker.getSymbolAtLocation(node);
let importNode: ts.Declaration | null = null;
// If this is an alias, and the request came at the declaration location
// get the aliased symbol instead. This allows for goto def on an import e.g.
// import {A, B} from "mod";
// to jump to the implementation directly.
if (symbol && symbol.flags & ts.SymbolFlags.Alias && shouldSkipAlias(node, symbol.declarations[0])) {
const aliased = checker.getAliasedSymbol(symbol);
if (aliased.declarations) {
......@@ -765,13 +755,21 @@ function getRealNodeSymbol(checker: ts.TypeChecker, node: ts.Node): [ts.Symbol |
// pr/*destination*/op1: number
// }
// bar<Test>(({pr/*goto*/op1})=>{});
if (ts.isPropertyName(node) && ts.isBindingElement(node.parent) && ts.isObjectBindingPattern(node.parent.parent) &&
(node === (node.parent.propertyName || node.parent.name))) {
const type = checker.getTypeAtLocation(node.parent.parent);
if (type) {
const propSymbols = getPropertySymbolsFromType(type, node);
if (propSymbols) {
symbol = propSymbols[0];
if (ts.isPropertyName(node) && ts.isBindingElement(parent) && ts.isObjectBindingPattern(parent.parent) &&
(node === (parent.propertyName || parent.name))) {
const name = getNameFromPropertyName(node);
const type = checker.getTypeAtLocation(parent.parent);
if (name && type) {
if (type.isUnion()) {
const prop = type.types[0].getProperty(name);
if (prop) {
symbol = prop;
}
} else {
const prop = type.getProperty(name);
if (prop) {
symbol = prop;
}
}
}
}
......@@ -786,10 +784,13 @@ function getRealNodeSymbol(checker: ts.TypeChecker, node: ts.Node): [ts.Symbol |
// function Foo(arg: Props) {}
// Foo( { pr/*1*/op1: 10, prop2: false })
const element = getContainingObjectLiteralElement(node);
if (element && checker.getContextualType(element.parent as ts.Expression)) {
const propertySymbols = getPropertySymbolsFromContextualType(checker, element);
if (propertySymbols) {
symbol = propertySymbols[0];
if (element) {
const contextualType = element && checker.getContextualType(element.parent);
if (contextualType) {
const propertySymbols = getPropertySymbolsFromContextualType(element, checker, contextualType, /*unionSymbolOk*/ false);
if (propertySymbols) {
symbol = propertySymbols[0];
}
}
}
}
......
......@@ -241,7 +241,7 @@ function generateDeclarationFile(out, inputFiles, recipe) {
usage.push("var b;");
var generateUsageImport = function (moduleId) {
var importName = 'm' + (++usageCounter);
usageImports.push("import * as " + importName + " from '" + moduleId.replace(/\.d\.ts$/, '') + "';");
usageImports.push("import * as " + importName + " from './" + moduleId.replace(/\.d\.ts$/, '') + "';");
return importName;
};
lines.forEach(function (line) {
......
......@@ -281,7 +281,7 @@ function generateDeclarationFile(out: string, inputFiles: { [file: string]: stri
const generateUsageImport = (moduleId: string) => {
let importName = 'm' + (++usageCounter);
usageImports.push(`import * as ${importName} from '${moduleId.replace(/\.d\.ts$/, '')}';`);
usageImports.push(`import * as ${importName} from './${moduleId.replace(/\.d\.ts$/, '')}';`);
return importName;
};
......
// This file is adding references to various symbols which should not be removed via tree shaking
import { ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation';
import { IContextViewService } from 'vs/platform/contextview/browser/contextView';
import { IHighlight } from 'vs/base/parts/quickopen/browser/quickOpenModel';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { CountBadge } from 'vs/base/browser/ui/countBadge/countBadge';
import { SimpleWorkerClient, create as create1 } from 'vs/base/common/worker/simpleWorker';
import { create as create2 } from 'vs/editor/common/services/editorSimpleWorker';
import { QuickOpenWidget } from 'vs/base/parts/quickopen/browser/quickOpenWidget';
import { SyncDescriptor0, SyncDescriptor1, SyncDescriptor2, SyncDescriptor3, SyncDescriptor4, SyncDescriptor5, SyncDescriptor6, SyncDescriptor7, SyncDescriptor8 } from 'vs/platform/instantiation/common/descriptors';
import { PolyfillPromise } from 'vs/base/common/winjs.polyfill.promise';
import { DiffNavigator } from 'vs/editor/browser/widget/diffNavigator';
import * as editorAPI from 'vs/editor/editor.api';
import { ServiceIdentifier } from './vs/platform/instantiation/common/instantiation';
import { IContextViewService } from './vs/platform/contextview/browser/contextView';
import { IHighlight } from './vs/base/parts/quickopen/browser/quickOpenModel';
import { IWorkspaceContextService } from './vs/platform/workspace/common/workspace';
import { IEnvironmentService } from './vs/platform/environment/common/environment';
import { CountBadge } from './vs/base/browser/ui/countBadge/countBadge';
import { SimpleWorkerClient, create as create1 } from './vs/base/common/worker/simpleWorker';
import { create as create2 } from './vs/editor/common/services/editorSimpleWorker';
import { QuickOpenWidget } from './vs/base/parts/quickopen/browser/quickOpenWidget';
import { SyncDescriptor0, SyncDescriptor1, SyncDescriptor2, SyncDescriptor3, SyncDescriptor4, SyncDescriptor5, SyncDescriptor6, SyncDescriptor7, SyncDescriptor8 } from './vs/platform/instantiation/common/descriptors';
import { PolyfillPromise } from './vs/base/common/winjs.polyfill.promise';
import { DiffNavigator } from './vs/editor/browser/widget/diffNavigator';
import * as editorAPI from './vs/editor/editor.api';
(function () {
var a: any;
......
......@@ -4,7 +4,9 @@
*--------------------------------------------------------------------------------------------*/
interface NodeRequire {
(moduleName: string): any;
}
toUrl(path: string): string;
(dependencies: string[], callback: (...args: any[]) => any, errorback?: (err: any) => void): any;
config(data: any): any;
}
declare var require: NodeRequire;
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册