Merge branch 'master' into libReference

This commit is contained in:
Ron Buckton
2018-05-09 11:19:18 -07:00
200 changed files with 3947 additions and 1327 deletions
+100 -72
View File
@@ -2220,7 +2220,22 @@ namespace ts {
}
if (moduleNotFoundError) {
// report errors only if it was requested
// For relative paths, see if this was possibly a projectReference redirect
if (pathIsRelative(moduleReference)) {
const sourceFile = getSourceFileOfNode(location);
const redirects = sourceFile.redirectedReferences;
if (redirects) {
const normalizedTargetPath = getNormalizedAbsolutePath(moduleReference, getDirectoryPath(sourceFile.fileName));
for (const ext of [Extension.Ts, Extension.Tsx]) {
const probePath = normalizedTargetPath + ext;
if (redirects.indexOf(probePath) >= 0) {
error(errorNode, Diagnostics.Output_file_0_has_not_been_built_from_source_file_1, moduleReference, probePath);
return undefined;
}
}
}
}
if (resolutionDiagnostic) {
error(errorNode, resolutionDiagnostic, moduleReference, resolvedModule.resolvedFileName);
}
@@ -5641,6 +5656,10 @@ namespace ts {
const symbol = type.symbol;
const members = getMembersOfSymbol(symbol);
(<InterfaceTypeWithDeclaredMembers>type).declaredProperties = getNamedMembers(members);
// Start with signatures at empty array in case of recursive types
(<InterfaceTypeWithDeclaredMembers>type).declaredCallSignatures = emptyArray;
(<InterfaceTypeWithDeclaredMembers>type).declaredConstructSignatures = emptyArray;
(<InterfaceTypeWithDeclaredMembers>type).declaredCallSignatures = getSignaturesOfSymbol(members.get(InternalSymbolName.Call));
(<InterfaceTypeWithDeclaredMembers>type).declaredConstructSignatures = getSignaturesOfSymbol(members.get(InternalSymbolName.New));
(<InterfaceTypeWithDeclaredMembers>type).declaredStringIndexInfo = getIndexInfoOfSymbol(symbol, IndexKind.String);
@@ -7033,7 +7052,7 @@ namespace ts {
for (let i = numTypeArguments; i < numTypeParameters; i++) {
const mapper = createTypeMapper(typeParameters, typeArguments);
let defaultType = getDefaultFromTypeParameter(typeParameters[i]);
if (defaultType && isTypeIdenticalTo(defaultType, emptyObjectType) && isJavaScriptImplicitAny) {
if (isJavaScriptImplicitAny && defaultType && isTypeIdenticalTo(defaultType, emptyObjectType)) {
defaultType = anyType;
}
typeArguments[i] = defaultType ? instantiateType(defaultType, mapper) : getDefaultTypeArgumentType(isJavaScriptImplicitAny);
@@ -10740,7 +10759,7 @@ namespace ts {
}
}
const constraint = getConstraintForRelation(<TypeParameter>source);
if (!constraint || constraint.flags & TypeFlags.Any) {
if (!constraint || (source.flags & TypeFlags.TypeParameter && constraint.flags & TypeFlags.Any)) {
// A type variable with no constraint is not related to the non-primitive object type.
if (result = isRelatedTo(emptyObjectType, extractTypesOfKind(target, ~TypeFlags.NonPrimitive))) {
errorInfo = saveErrorInfo;
@@ -22260,10 +22279,6 @@ namespace ts {
function checkUnusedIdentifiers(potentiallyUnusedIdentifiers: ReadonlyArray<PotentiallyUnusedIdentifier>, addDiagnostic: AddUnusedDiagnostic) {
for (const node of potentiallyUnusedIdentifiers) {
switch (node.kind) {
case SyntaxKind.SourceFile:
case SyntaxKind.ModuleDeclaration:
checkUnusedModuleMembers(node, addDiagnostic);
break;
case SyntaxKind.ClassDeclaration:
case SyntaxKind.ClassExpression:
checkUnusedClassMembers(node, addDiagnostic);
@@ -22272,6 +22287,8 @@ namespace ts {
case SyntaxKind.InterfaceDeclaration:
checkUnusedTypeParameters(node, addDiagnostic);
break;
case SyntaxKind.SourceFile:
case SyntaxKind.ModuleDeclaration:
case SyntaxKind.Block:
case SyntaxKind.CaseBlock:
case SyntaxKind.ForStatement:
@@ -22305,35 +22322,6 @@ namespace ts {
}
}
function checkUnusedLocalsAndParameters(node: Node, addDiagnostic: AddUnusedDiagnostic): void {
if (!(node.flags & NodeFlags.Ambient)) {
node.locals.forEach(local => {
// If it's purely a type parameter, ignore, will be checked in `checkUnusedTypeParameters`.
// If it's a type parameter merged with a parameter, check if the parameter-side is used.
if (local.flags & SymbolFlags.TypeParameter ? (local.flags & SymbolFlags.Variable && !(local.isReferenced & SymbolFlags.Variable)) : !local.isReferenced) {
if (local.valueDeclaration && getRootDeclaration(local.valueDeclaration).kind === SyntaxKind.Parameter) {
const parameter = <ParameterDeclaration>getRootDeclaration(local.valueDeclaration);
const name = getNameOfDeclaration(local.valueDeclaration);
if (!isParameterPropertyDeclaration(parameter) && !parameterIsThisKeyword(parameter) && !parameterNameStartsWithUnderscore(name)) {
addDiagnostic(UnusedKind.Parameter, createDiagnosticForNode(name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(local)));
}
}
else {
forEach(local.declarations, d => errorUnusedLocal(d, symbolName(local), addDiagnostic));
}
}
});
}
}
function isRemovedPropertyFromObjectSpread(node: Node) {
if (isBindingElement(node) && isObjectBindingPattern(node.parent)) {
const lastElement = lastOrUndefined(node.parent.elements);
return lastElement !== node && !!lastElement.dotDotDotToken;
}
return false;
}
function errorUnusedLocal(declaration: Declaration, name: string, addDiagnostic: AddUnusedDiagnostic) {
const node = getNameOfDeclaration(declaration) || declaration;
if (isIdentifierThatStartsWithUnderScore(node)) {
@@ -22344,10 +22332,8 @@ namespace ts {
}
}
if (!isRemovedPropertyFromObjectSpread(node.kind === SyntaxKind.Identifier ? node.parent : node)) {
const message = isTypeDeclaration(declaration) ? Diagnostics._0_is_declared_but_never_used : Diagnostics._0_is_declared_but_its_value_is_never_read;
addDiagnostic(UnusedKind.Local, createDiagnosticForNodeSpan(getSourceFileOfNode(declaration), declaration, node, message, name));
}
const message = isTypeDeclaration(declaration) ? Diagnostics._0_is_declared_but_never_used : Diagnostics._0_is_declared_but_its_value_is_never_read;
addDiagnostic(UnusedKind.Local, createDiagnosticForNodeSpan(getSourceFileOfNode(declaration), declaration, node, message, name));
}
function parameterNameStartsWithUnderscore(parameterName: DeclarationName) {
@@ -22409,44 +22395,86 @@ namespace ts {
}
}
function checkUnusedModuleMembers(node: ModuleDeclaration | SourceFile, addDiagnostic: AddUnusedDiagnostic): void {
if (!(node.flags & NodeFlags.Ambient)) {
// Ideally we could use the ImportClause directly as a key, but must wait until we have full ES6 maps. So must store key along with value.
const unusedImports = createMap<[ImportClause, ImportedDeclaration[]]>();
node.locals.forEach(local => {
if (local.isReferenced || local.exportSymbol) return;
for (const declaration of local.declarations) {
if (isAmbientModule(declaration)) continue;
if (isImportedDeclaration(declaration)) {
const importClause = importClauseFromImported(declaration);
const key = String(getNodeId(importClause));
const group = unusedImports.get(key);
if (group) {
group[1].push(declaration);
}
else {
unusedImports.set(key, [importClause, [declaration]]);
function addToGroup<K, V>(map: Map<[K, V[]]>, key: K, value: V, getKey: (key: K) => number | string): void {
const keyString = String(getKey(key));
const group = map.get(keyString);
if (group) {
group[1].push(value);
}
else {
map.set(keyString, [key, [value]]);
}
}
function tryGetRootParameterDeclaration(node: Node): ParameterDeclaration | undefined {
return tryCast(getRootDeclaration(node), isParameter);
}
function checkUnusedLocalsAndParameters(nodeWithLocals: Node, addDiagnostic: AddUnusedDiagnostic): void {
if (nodeWithLocals.flags & NodeFlags.Ambient) return;
// Ideally we could use the ImportClause directly as a key, but must wait until we have full ES6 maps. So must store key along with value.
const unusedImports = createMap<[ImportClause, ImportedDeclaration[]]>();
const unusedDestructures = createMap<[ObjectBindingPattern, BindingElement[]]>();
nodeWithLocals.locals.forEach(local => {
// If it's purely a type parameter, ignore, will be checked in `checkUnusedTypeParameters`.
// If it's a type parameter merged with a parameter, check if the parameter-side is used.
if (local.flags & SymbolFlags.TypeParameter ? !(local.flags & SymbolFlags.Variable && !(local.isReferenced & SymbolFlags.Variable)) : local.isReferenced || local.exportSymbol) {
return;
}
for (const declaration of local.declarations) {
if (isAmbientModule(declaration)) continue;
if (isImportedDeclaration(declaration)) {
addToGroup(unusedImports, importClauseFromImported(declaration), declaration, getNodeId);
}
else if (isBindingElement(declaration) && isObjectBindingPattern(declaration.parent)) {
// In `{ a, ...b }, `a` is considered used since it removes a property from `b`. `b` may still be unused though.
const lastElement = last(declaration.parent.elements);
if (declaration === lastElement || !last(declaration.parent.elements).dotDotDotToken) {
addToGroup(unusedDestructures, declaration.parent, declaration, getNodeId);
}
}
else {
const parameter = local.valueDeclaration && tryGetRootParameterDeclaration(local.valueDeclaration);
if (parameter) {
const name = getNameOfDeclaration(local.valueDeclaration);
if (!isParameterPropertyDeclaration(parameter) && !parameterIsThisKeyword(parameter) && !parameterNameStartsWithUnderscore(name)) {
addDiagnostic(UnusedKind.Parameter, createDiagnosticForNode(name, Diagnostics._0_is_declared_but_its_value_is_never_read, symbolName(local)));
}
}
else {
errorUnusedLocal(declaration, symbolName(local), addDiagnostic);
}
}
});
unusedImports.forEach(([importClause, unuseds]) => {
const importDecl = importClause.parent;
if (forEachImportedDeclaration(importClause, d => !contains(unuseds, d))) {
for (const unused of unuseds) errorUnusedLocal(unused, idText(unused.name), addDiagnostic);
}
});
unusedImports.forEach(([importClause, unuseds]) => {
const importDecl = importClause.parent;
if (forEachImportedDeclaration(importClause, d => !contains(unuseds, d))) {
for (const unused of unuseds) errorUnusedLocal(unused, idText(unused.name), addDiagnostic);
}
else if (unuseds.length === 1) {
addDiagnostic(UnusedKind.Local, createDiagnosticForNode(importDecl, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(first(unuseds).name)));
}
else {
addDiagnostic(UnusedKind.Local, createDiagnosticForNode(importDecl, Diagnostics.All_imports_in_import_declaration_are_unused));
}
});
unusedDestructures.forEach(([bindingPattern, bindingElements]) => {
const kind = tryGetRootParameterDeclaration(bindingPattern.parent) ? UnusedKind.Parameter : UnusedKind.Local;
if (!bindingPattern.elements.every(e => contains(bindingElements, e))) {
for (const e of bindingElements) {
addDiagnostic(kind, createDiagnosticForNode(e, Diagnostics._0_is_declared_but_its_value_is_never_read, getBindingElementNameText(e)));
}
else if (unuseds.length === 1) {
addDiagnostic(UnusedKind.Local, createDiagnosticForNode(importDecl, Diagnostics._0_is_declared_but_its_value_is_never_read, idText(first(unuseds).name)));
}
else {
addDiagnostic(UnusedKind.Local, createDiagnosticForNode(importDecl, Diagnostics.All_imports_in_import_declaration_are_unused, showModuleSpecifier(importDecl)));
}
});
}
}
else if (bindingElements.length === 1) {
addDiagnostic(kind, createDiagnosticForNode(bindingPattern, Diagnostics._0_is_declared_but_its_value_is_never_read, getBindingElementNameText(first(bindingElements))));
}
else {
addDiagnostic(kind, createDiagnosticForNode(bindingPattern, Diagnostics.All_destructured_elements_are_unused));
}
});
}
type ImportedDeclaration = ImportClause | ImportSpecifier | NamespaceImport;
@@ -28026,7 +28054,7 @@ namespace ts {
function checkGrammarImportCallExpression(node: ImportCall): boolean {
if (moduleKind === ModuleKind.ES2015) {
return grammarErrorOnNode(node, Diagnostics.Dynamic_import_cannot_be_used_when_targeting_ECMAScript_2015_modules);
return grammarErrorOnNode(node, Diagnostics.Dynamic_import_is_only_supported_when_module_flag_is_commonjs_or_esNext);
}
if (node.typeArguments) {
+100 -5
View File
@@ -248,6 +248,13 @@ namespace ts {
category: Diagnostics.Basic_Options,
description: Diagnostics.Specify_the_root_directory_of_input_files_Use_to_control_the_output_directory_structure_with_outDir,
},
{
name: "composite",
type: "boolean",
isTSConfigOnly: true,
category: Diagnostics.Basic_Options,
description: Diagnostics.Enable_project_compilation,
},
{
name: "removeComments",
type: "boolean",
@@ -827,12 +834,14 @@ namespace ts {
export function parseCommandLine(commandLine: ReadonlyArray<string>, readFile?: (path: string) => string | undefined): ParsedCommandLine {
const options: CompilerOptions = {};
const fileNames: string[] = [];
const projectReferences: ProjectReference[] | undefined = undefined;
const errors: Diagnostic[] = [];
parseStrings(commandLine);
return {
options,
fileNames,
projectReferences,
errors
};
@@ -946,6 +955,49 @@ namespace ts {
return optionNameMap.get(optionName);
}
export type DiagnosticReporter = (diagnostic: Diagnostic) => void;
/**
* Reports config file diagnostics
*/
export interface ConfigFileDiagnosticsReporter {
/**
* Reports unrecoverable error when parsing config file
*/
onUnRecoverableConfigFileDiagnostic: DiagnosticReporter;
}
/**
* Interface extending ParseConfigHost to support ParseConfigFile that reads config file and reports errors
*/
export interface ParseConfigFileHost extends ParseConfigHost, ConfigFileDiagnosticsReporter {
getCurrentDirectory(): string;
}
/**
* Reads the config file, reports errors if any and exits if the config file cannot be found
*/
export function getParsedCommandLineOfConfigFile(configFileName: string, optionsToExtend: CompilerOptions, host: ParseConfigFileHost): ParsedCommandLine | undefined {
let configFileText: string;
try {
configFileText = host.readFile(configFileName);
}
catch (e) {
const error = createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, configFileName, e.message);
host.onUnRecoverableConfigFileDiagnostic(error);
return undefined;
}
if (!configFileText) {
const error = createCompilerDiagnostic(Diagnostics.File_0_not_found, configFileName);
host.onUnRecoverableConfigFileDiagnostic(error);
return undefined;
}
const result = parseJsonText(configFileName, configFileText);
const cwd = host.getCurrentDirectory();
return parseJsonSourceFileConfigFileContent(result, host, getNormalizedAbsolutePath(getDirectoryPath(configFileName), cwd), optionsToExtend, getNormalizedAbsolutePath(configFileName, cwd));
}
/**
* Read tsconfig.json file
* @param fileName The path to the config file
@@ -1021,6 +1073,14 @@ namespace ts {
name: "extends",
type: "string"
},
{
name: "references",
type: "list",
element: {
name: "references",
type: "object"
}
},
{
name: "files",
type: "list",
@@ -1428,7 +1488,7 @@ namespace ts {
for (let i = 0; i < nameColumn.length; i++) {
const optionName = nameColumn[i];
const description = descriptionColumn[i];
result.push(optionName && `${tab}${tab}${optionName}${ description && (makePadding(marginLength - optionName.length + 2) + description)}`);
result.push(optionName && `${tab}${tab}${optionName}${description && (makePadding(marginLength - optionName.length + 2) + description)}`);
}
if (fileNames.length) {
result.push(`${tab}},`);
@@ -1512,12 +1572,13 @@ namespace ts {
const parsedConfig = parseConfig(json, sourceFile, host, basePath, configFileName, resolutionStack, errors);
const { raw } = parsedConfig;
const options = extend(existingOptions, parsedConfig.options || {});
options.configFilePath = configFileName;
options.configFilePath = configFileName && normalizeSlashes(configFileName);
setConfigFileInOptions(options, sourceFile);
const { fileNames, wildcardDirectories, spec } = getFileNames();
const { fileNames, wildcardDirectories, spec, projectReferences } = getFileNames();
return {
options,
fileNames,
projectReferences,
typeAcquisition: parsedConfig.typeAcquisition || getDefaultTypeAcquisition(),
raw,
errors,
@@ -1571,10 +1632,33 @@ namespace ts {
}
const result = matchFileNames(filesSpecs, includeSpecs, excludeSpecs, configFileName ? directoryOfCombinedPath(configFileName, basePath) : basePath, options, host, errors, extraFileExtensions, sourceFile);
if (result.fileNames.length === 0 && !hasProperty(raw, "files") && resolutionStack.length === 0) {
if (result.fileNames.length === 0 && !hasProperty(raw, "files") && resolutionStack.length === 0 && !hasProperty(raw, "references")) {
errors.push(getErrorForNoInputFiles(result.spec, configFileName));
}
if (hasProperty(raw, "references") && !isNullOrUndefined(raw.references)) {
if (isArray(raw.references)) {
const references: ProjectReference[] = [];
for (const ref of raw.references) {
if (typeof ref.path !== "string") {
createCompilerDiagnosticOnlyIfJson(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "reference.path", "string");
}
else {
references.push({
path: getNormalizedAbsolutePath(ref.path, basePath),
originalPath: ref.path,
prepend: ref.prepend,
circular: ref.circular
});
}
}
result.projectReferences = references;
}
else {
createCompilerDiagnosticOnlyIfJson(Diagnostics.Compiler_option_0_requires_a_value_of_type_1, "references", "Array");
}
}
return result;
}
@@ -1863,6 +1947,9 @@ namespace ts {
const options = getDefaultCompilerOptions(configFileName);
convertOptionsFromJson(optionDeclarations, jsonOptions, basePath, options, Diagnostics.Unknown_compiler_option_0, errors);
if (configFileName) {
options.configFilePath = normalizeSlashes(configFileName);
}
return options;
}
@@ -2061,7 +2148,7 @@ namespace ts {
// new entries in these paths.
const wildcardDirectories = getWildcardDirectories(validatedIncludeSpecs, validatedExcludeSpecs, basePath, host.useCaseSensitiveFileNames);
const spec: ConfigFileSpecs = { filesSpecs, includeSpecs, excludeSpecs, validatedIncludeSpecs, validatedExcludeSpecs, wildcardDirectories };
const spec: ConfigFileSpecs = { filesSpecs, referencesSpecs: undefined, includeSpecs, excludeSpecs, validatedIncludeSpecs, validatedExcludeSpecs, wildcardDirectories };
return getFileNamesFromConfigSpecs(spec, basePath, options, host, extraFileExtensions);
}
@@ -2132,8 +2219,16 @@ namespace ts {
const literalFiles = arrayFrom(literalFileMap.values());
const wildcardFiles = arrayFrom(wildcardFileMap.values());
const projectReferences = spec.referencesSpecs && spec.referencesSpecs.map((r): ProjectReference => {
return {
...r,
path: getNormalizedAbsolutePath(r.path, basePath)
};
});
return {
fileNames: literalFiles.concat(wildcardFiles),
projectReferences,
wildcardDirectories,
spec
};
+5
View File
@@ -2068,6 +2068,10 @@ namespace ts {
: moduleKind === ModuleKind.System;
}
export function getEmitDeclarations(compilerOptions: CompilerOptions): boolean {
return !!(compilerOptions.declaration || compilerOptions.composite);
}
export type StrictOptionName = "noImplicitAny" | "noImplicitThis" | "strictNullChecks" | "strictFunctionTypes" | "strictPropertyInitialization" | "alwaysStrict";
export function getStrictOptionValue(compilerOptions: CompilerOptions, flag: StrictOptionName): boolean {
@@ -2328,6 +2332,7 @@ namespace ts {
const reduced = [components[0]];
for (let i = 1; i < components.length; i++) {
const component = components[i];
if (!component) continue;
if (component === ".") continue;
if (component === "..") {
if (reduced.length > 1) {
+47 -1
View File
@@ -895,7 +895,7 @@
"category": "Error",
"code": 1322
},
"Dynamic import cannot be used when targeting ECMAScript 2015 modules.": {
"Dynamic import is only supported when '--module' flag is 'commonjs' or 'esNext'.": {
"category": "Error",
"code": 1323
},
@@ -3559,6 +3559,48 @@
"category": "Message",
"code": 6197
},
"All destructured elements are unused.": {
"category": "Error",
"code": 6198,
"reportsUnnecessary": true
},
"Projects to reference": {
"category": "Message",
"code": 6300
},
"Enable project compilation": {
"category": "Message",
"code": 6302
},
"Project references may not form a circular graph. Cycle detected: {0}": {
"category": "Error",
"code": 6202
},
"Composite projects may not disable declaration emit.": {
"category": "Error",
"code": 6304
},
"Output file '{0}' has not been built from source file '{1}'.": {
"category": "Error",
"code": 6305
},
"Referenced project '{0}' must have setting \"composite\": true.": {
"category": "Error",
"code": 6306
},
"File '{0}' is not in project file list. Projects must list all files or use an 'include' pattern.": {
"category": "Error",
"code": 6307
},
"Cannot prepend project '{0}' because it does not have 'outFile' set": {
"category": "Error",
"code": 6308
},
"Output file '{0}' from project '{1}' does not exist": {
"category": "Error",
"code": 6309
},
"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",
@@ -3956,6 +3998,10 @@
"category": "Message",
"code": 90008
},
"Remove destructuring": {
"category": "Message",
"code": 90009
},
"Import '{0}' from module \"{1}\"": {
"category": "Message",
"code": 90013
+70 -17
View File
@@ -1,4 +1,5 @@
namespace ts {
const infoExtension = ".tsbundleinfo";
const brackets = createBracketsMap();
/*@internal*/
@@ -15,12 +16,11 @@ namespace ts {
host: EmitHost, action: (emitFileNames: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) => T,
sourceFilesOrTargetSourceFile?: ReadonlyArray<SourceFile> | SourceFile,
emitOnlyDtsFiles?: boolean) {
const sourceFiles = isArray(sourceFilesOrTargetSourceFile) ? sourceFilesOrTargetSourceFile : getSourceFilesToEmit(host, sourceFilesOrTargetSourceFile);
const options = host.getCompilerOptions();
if (options.outFile || options.out) {
if (sourceFiles.length) {
const bundle = createBundle(sourceFiles);
const bundle = createBundle(sourceFiles, host.getPrependNodes());
const result = action(getOutputPathsFor(bundle, host, emitOnlyDtsFiles), bundle);
if (result) {
return result;
@@ -45,7 +45,8 @@ namespace ts {
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
const declarationFilePath = (forceDtsPaths || options.declaration) ? removeFileExtension(jsFilePath) + Extension.Dts : undefined;
const declarationMapPath = getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath };
const bundleInfoPath = options.references && jsFilePath && (removeFileExtension(jsFilePath) + infoExtension);
return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, bundleInfoPath };
}
else {
const jsFilePath = getOwnEmitOutputFilePath(sourceFile, host, getOutputExtension(sourceFile, options));
@@ -54,7 +55,7 @@ namespace ts {
const isJs = isSourceFileJavaScript(sourceFile);
const declarationFilePath = ((forceDtsPaths || options.declaration) && !isJs) ? getDeclarationEmitOutputFilePath(sourceFile, host) : undefined;
const declarationMapPath = getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath };
return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, bundleInfoPath: undefined };
}
}
@@ -62,6 +63,13 @@ namespace ts {
return (options.sourceMap && !options.inlineSourceMap) ? jsFilePath + ".map" : undefined;
}
function createDefaultBundleInfo(): BundleInfo {
return {
originalOffset: -1,
totalLength: -1
};
}
// JavaScript files are always LanguageVariant.JSX, as JSX syntax is allowed in .js files also.
// So for JavaScript files, '.jsx' is only emitted if the input was '.jsx', and JsxEmit.Preserve.
// For TypeScript, the only time to emit with a '.jsx' extension, is on JSX input, and JsxEmit.Preserve
@@ -87,7 +95,7 @@ namespace ts {
/*@internal*/
// targetSourceFile is when users only want one file in entire project to be emitted. This is used in compileOnSave feature
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean, transformers?: TransformerFactory<SourceFile>[]): EmitResult {
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile: SourceFile, emitOnlyDtsFiles?: boolean, transformers?: TransformerFactory<Bundle | SourceFile>[], declarationTransformers?: TransformerFactory<Bundle | SourceFile>[]): EmitResult {
const compilerOptions = host.getCompilerOptions();
const sourceMapDataList: SourceMapData[] = (compilerOptions.sourceMap || compilerOptions.inlineSourceMap || getAreDeclarationMapsEnabled(compilerOptions)) ? [] : undefined;
const emittedFilesList: string[] = compilerOptions.listEmittedFiles ? [] : undefined;
@@ -103,6 +111,7 @@ namespace ts {
// Explicitly do not passthru either `inline` option
});
let bundleInfo: BundleInfo = createDefaultBundleInfo();
let emitSkipped = false;
// Emit each output file
@@ -118,8 +127,8 @@ namespace ts {
sourceMaps: sourceMapDataList
};
function emitSourceFileOrBundle({ jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath }: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) {
emitJsFileOrBundle(sourceFileOrBundle, jsFilePath, sourceMapFilePath);
function emitSourceFileOrBundle({ jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, bundleInfoPath }: EmitFileNames, sourceFileOrBundle: SourceFile | Bundle) {
emitJsFileOrBundle(sourceFileOrBundle, jsFilePath, sourceMapFilePath, bundleInfoPath);
emitDeclarationFileOrBundle(sourceFileOrBundle, declarationFilePath, declarationMapPath);
if (!emitSkipped && emittedFilesList) {
@@ -132,11 +141,13 @@ namespace ts {
if (declarationFilePath) {
emittedFilesList.push(declarationFilePath);
}
if (bundleInfoPath) {
emittedFilesList.push(bundleInfoPath);
}
}
}
function emitJsFileOrBundle(sourceFileOrBundle: SourceFile | Bundle, jsFilePath: string, sourceMapFilePath: string) {
const sourceFiles = isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : sourceFileOrBundle.sourceFiles;
function emitJsFileOrBundle(sourceFileOrBundle: SourceFile | Bundle, jsFilePath: string, sourceMapFilePath: string, bundleInfoPath: string | undefined) {
// Make sure not to write js file and source map file if any of them cannot be written
if (host.isEmitBlocked(jsFilePath) || compilerOptions.noEmit || compilerOptions.emitDeclarationOnly) {
emitSkipped = true;
@@ -146,7 +157,7 @@ namespace ts {
return;
}
// Transform the source files
const transform = transformNodes(resolver, host, compilerOptions, sourceFiles, transformers, /*allowDtsFiles*/ false);
const transform = transformNodes(resolver, host, compilerOptions, [sourceFileOrBundle], transformers, /*allowDtsFiles*/ false);
// Create a printer to print the nodes
const printer = createPrinter({ ...compilerOptions, noEmitHelpers: compilerOptions.noEmitHelpers } as PrinterOptions, {
@@ -166,7 +177,8 @@ namespace ts {
onSetSourceFile: setSourceFile,
});
printSourceFileOrBundle(jsFilePath, sourceMapFilePath, isSourceFile(sourceFileOrBundle) ? transform.transformed[0] : createBundle(transform.transformed), printer, sourceMap);
Debug.assert(transform.transformed.length === 1, "Should only see one output from the transform");
printSourceFileOrBundle(jsFilePath, sourceMapFilePath, transform.transformed[0], bundleInfoPath, printer, sourceMap);
// Clean up emit nodes on parse tree
transform.dispose();
@@ -179,8 +191,8 @@ namespace ts {
const sourceFiles = isSourceFile(sourceFileOrBundle) ? [sourceFileOrBundle] : sourceFileOrBundle.sourceFiles;
// Setup and perform the transformation to retrieve declarations from the input files
const nonJsFiles = filter(sourceFiles, isSourceFileNotJavaScript);
const inputListOrBundle = (compilerOptions.outFile || compilerOptions.out) ? [createBundle(nonJsFiles)] : nonJsFiles;
const declarationTransform = transformNodes(resolver, host, compilerOptions, inputListOrBundle, [transformDeclarations], /*allowDtsFiles*/ false);
const inputListOrBundle = (compilerOptions.outFile || compilerOptions.out) ? [createBundle(nonJsFiles, !isSourceFile(sourceFileOrBundle) ? sourceFileOrBundle.prepends : undefined)] : nonJsFiles;
const declarationTransform = transformNodes(resolver, host, compilerOptions, inputListOrBundle, concatenate([transformDeclarations], declarationTransformers), /*allowDtsFiles*/ false);
if (length(declarationTransform.diagnostics)) {
for (const diagnostic of declarationTransform.diagnostics) {
emitterDiagnostics.add(diagnostic);
@@ -203,19 +215,20 @@ namespace ts {
const declBlocked = (!!declarationTransform.diagnostics && !!declarationTransform.diagnostics.length) || !!host.isEmitBlocked(declarationFilePath) || !!compilerOptions.noEmit;
emitSkipped = emitSkipped || declBlocked;
if (!declBlocked || emitOnlyDtsFiles) {
printSourceFileOrBundle(declarationFilePath, declarationMapPath, declarationTransform.transformed[0], declarationPrinter, declarationSourceMap);
Debug.assert(declarationTransform.transformed.length === 1, "Should only see one output from the decl transform");
printSourceFileOrBundle(declarationFilePath, declarationMapPath, declarationTransform.transformed[0], /* bundleInfopath*/ undefined, declarationPrinter, declarationSourceMap);
}
declarationTransform.dispose();
}
function printSourceFileOrBundle(jsFilePath: string, sourceMapFilePath: string | undefined, sourceFileOrBundle: SourceFile | Bundle, printer: Printer, mapRecorder: SourceMapWriter) {
function printSourceFileOrBundle(jsFilePath: string, sourceMapFilePath: string | undefined, sourceFileOrBundle: SourceFile | Bundle, bundleInfoPath: string | undefined, printer: Printer, mapRecorder: SourceMapWriter) {
const bundle = sourceFileOrBundle.kind === SyntaxKind.Bundle ? sourceFileOrBundle : undefined;
const sourceFile = sourceFileOrBundle.kind === SyntaxKind.SourceFile ? sourceFileOrBundle : undefined;
const sourceFiles = bundle ? bundle.sourceFiles : [sourceFile];
mapRecorder.initialize(jsFilePath, sourceMapFilePath || "", sourceFileOrBundle, sourceMapDataList);
if (bundle) {
printer.writeBundle(bundle, writer);
printer.writeBundle(bundle, writer, bundleInfo);
}
else {
printer.writeFile(sourceFile, writer);
@@ -236,9 +249,17 @@ namespace ts {
// Write the output file
writeFile(host, emitterDiagnostics, jsFilePath, writer.getText(), compilerOptions.emitBOM, sourceFiles);
// Write bundled offset information if applicable
if (bundleInfoPath) {
bundleInfo.totalLength = writer.getTextPos();
writeFile(host, emitterDiagnostics, bundleInfoPath, JSON.stringify(bundleInfo, undefined, 2), /*writeByteOrderMark*/ false);
}
// Reset state
mapRecorder.reset();
writer.clear();
bundleInfo = createDefaultBundleInfo();
}
function setSourceFile(node: SourceFile) {
@@ -335,6 +356,7 @@ namespace ts {
switch (node.kind) {
case SyntaxKind.SourceFile: return printFile(<SourceFile>node);
case SyntaxKind.Bundle: return printBundle(<Bundle>node);
case SyntaxKind.UnparsedSource: return printUnparsedSource(<UnparsedSource>node);
}
writeNode(hint, node, sourceFile, beginPrint());
return endPrint();
@@ -355,6 +377,11 @@ namespace ts {
return endPrint();
}
function printUnparsedSource(unparsed: UnparsedSource): string {
writeUnparsedSource(unparsed, beginPrint());
return endPrint();
}
/**
* If `sourceFile` is `undefined`, `node` must be a synthesized `TypeNode`.
*/
@@ -379,7 +406,7 @@ namespace ts {
writer = previousWriter;
}
function writeBundle(bundle: Bundle, output: EmitTextWriter) {
function writeBundle(bundle: Bundle, output: EmitTextWriter, bundleInfo?: BundleInfo) {
isOwnFileEmit = false;
const previousWriter = writer;
setWriter(output);
@@ -387,6 +414,16 @@ namespace ts {
emitPrologueDirectivesIfNeeded(bundle);
emitHelpers(bundle);
emitSyntheticTripleSlashReferencesIfNeeded(bundle);
for (const prepend of bundle.prepends) {
print(EmitHint.Unspecified, prepend, /*sourceFile*/ undefined);
writeLine();
}
if (bundleInfo) {
bundleInfo.originalOffset = writer.getTextPos();
}
for (const sourceFile of bundle.sourceFiles) {
print(EmitHint.SourceFile, sourceFile, sourceFile);
}
@@ -394,6 +431,14 @@ namespace ts {
writer = previousWriter;
}
function writeUnparsedSource(unparsed: UnparsedSource, output: EmitTextWriter) {
const previousWriter = writer;
setWriter(output);
print(EmitHint.Unspecified, unparsed, /*sourceFile*/ undefined);
reset();
writer = previousWriter;
}
function writeFile(sourceFile: SourceFile, output: EmitTextWriter) {
isOwnFileEmit = true;
const previousWriter = writer;
@@ -534,6 +579,9 @@ namespace ts {
case SyntaxKind.TemplateTail:
return emitLiteral(<LiteralExpression>node);
case SyntaxKind.UnparsedSource:
return emitUnparsedSource(<UnparsedSource>node);
// Identifiers
case SyntaxKind.Identifier:
return emitIdentifier(<Identifier>node);
@@ -978,6 +1026,11 @@ namespace ts {
}
}
// SyntaxKind.UnparsedSource
function emitUnparsedSource(unparsed: UnparsedSource) {
write(unparsed.text);
}
//
// Identifiers
//
+18 -4
View File
@@ -2564,15 +2564,29 @@ namespace ts {
: node;
}
export function createBundle(sourceFiles: ReadonlyArray<SourceFile>) {
export function createBundle(sourceFiles: ReadonlyArray<SourceFile>, prepends: ReadonlyArray<UnparsedSource | InputFiles> = emptyArray) {
const node = <Bundle>createNode(SyntaxKind.Bundle);
node.prepends = prepends;
node.sourceFiles = sourceFiles;
return node;
}
export function updateBundle(node: Bundle, sourceFiles: ReadonlyArray<SourceFile>) {
if (node.sourceFiles !== sourceFiles) {
return createBundle(sourceFiles);
export function createUnparsedSourceFile(text: string): UnparsedSource {
const node = <UnparsedSource>createNode(SyntaxKind.UnparsedSource);
node.text = text;
return node;
}
export function createInputFiles(javascript: string, declaration: string): InputFiles {
const node = <InputFiles>createNode(SyntaxKind.InputFiles);
node.javascriptText = javascript;
node.declarationText = declaration;
return node;
}
export function updateBundle(node: Bundle, sourceFiles: ReadonlyArray<SourceFile>, prepends: ReadonlyArray<UnparsedSource> = emptyArray) {
if (node.sourceFiles !== sourceFiles || node.prepends !== prepends) {
return createBundle(sourceFiles, prepends);
}
return node;
}
+6 -1
View File
@@ -119,7 +119,12 @@ namespace ts {
export function readJson(path: string, host: { readFile(fileName: string): string | undefined }): object {
try {
const jsonText = host.readFile(path);
return jsonText ? JSON.parse(jsonText) : {};
if (!jsonText) return {};
const result = parseConfigFileTextToJson(path, jsonText);
if (result.error) {
return {};
}
return result.config;
}
catch (e) {
// gracefully handle if readFile fails or returns not JSON
+8 -2
View File
@@ -503,7 +503,13 @@ namespace ts {
export function createSourceFile(fileName: string, sourceText: string, languageVersion: ScriptTarget, setParentNodes = false, scriptKind?: ScriptKind): SourceFile {
performance.mark("beforeParse");
const result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, scriptKind);
let result: SourceFile;
if (languageVersion === ScriptTarget.JSON) {
result = Parser.parseJsonText(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes);
}
else {
result = Parser.parseSourceFile(fileName, sourceText, languageVersion, /*syntaxCursor*/ undefined, setParentNodes, scriptKind);
}
performance.mark("afterParse");
performance.measure("Parse", "beforeParse", "afterParse");
return result;
@@ -3566,7 +3572,7 @@ namespace ts {
// 2) CoverCallExpressionAndAsyncArrowHead[?Yield, ?Await][no LineTerminator here]=>AsyncConciseBody[?In]
if (token() === SyntaxKind.AsyncKeyword) {
nextToken();
// If the "async" is followed by "=>" token then it is not a begining of an async arrow-function
// If the "async" is followed by "=>" token then it is not a beginning of an async arrow-function
// but instead a simple arrow-function which will be parsed inside "parseAssignmentExpressionOrHigher"
if (scanner.hasPrecedingLineBreak() || token() === SyntaxKind.EqualsGreaterThanToken) {
return Tristate.False;
+288 -12
View File
@@ -188,7 +188,8 @@ namespace ts {
directoryExists: directoryName => sys.directoryExists(directoryName),
getEnvironmentVariable: name => sys.getEnvironmentVariable ? sys.getEnvironmentVariable(name) : "",
getDirectories: (path: string) => sys.getDirectories(path),
realpath
realpath,
readDirectory: (path, extensions, include, exclude, depth) => sys.readDirectory(path, extensions, include, exclude, depth)
};
}
@@ -328,14 +329,14 @@ namespace ts {
output += formatColorAndReset(relativeFileName, ForegroundColorEscapeSequences.Cyan);
output += ":";
output += formatColorAndReset(`${ firstLine + 1 }`, ForegroundColorEscapeSequences.Yellow);
output += formatColorAndReset(`${firstLine + 1}`, ForegroundColorEscapeSequences.Yellow);
output += ":";
output += formatColorAndReset(`${ firstLineChar + 1 }`, ForegroundColorEscapeSequences.Yellow);
output += formatColorAndReset(`${firstLineChar + 1}`, ForegroundColorEscapeSequences.Yellow);
output += " - ";
}
output += formatColorAndReset(diagnosticCategoryName(diagnostic), getCategoryFormat(diagnostic.category));
output += formatColorAndReset(` TS${ diagnostic.code }: `, ForegroundColorEscapeSequences.Grey);
output += formatColorAndReset(` TS${diagnostic.code}: `, ForegroundColorEscapeSequences.Grey);
output += flattenDiagnosticMessageText(diagnostic.messageText, host.getNewLine());
if (diagnostic.file) {
@@ -477,6 +478,16 @@ namespace ts {
);
}
function createCreateProgramOptions(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): CreateProgramOptions {
return {
rootNames,
options,
host,
oldProgram,
configFileParsingDiagnostics
};
}
/**
* Create a new 'Program' instance. A Program is an immutable collection of 'SourceFile's and a 'CompilerOptions'
* that represent a compilation unit.
@@ -491,7 +502,13 @@ namespace ts {
* @param configFileParsingDiagnostics - error during config file parsing
* @returns A 'Program' object.
*/
export function createProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): Program {
export function createProgram(createProgramOptions: CreateProgramOptions): Program;
export function createProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): Program;
export function createProgram(rootNamesOrOptions: ReadonlyArray<string> | CreateProgramOptions, _options?: CompilerOptions, _host?: CompilerHost, _oldProgram?: Program, _configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): Program {
const createProgramOptions = isArray(rootNamesOrOptions) ? createCreateProgramOptions(rootNamesOrOptions, _options, _host, _oldProgram, _configFileParsingDiagnostics) : rootNamesOrOptions;
const { rootNames, options, configFileParsingDiagnostics, projectReferences } = createProgramOptions;
let { host, oldProgram } = createProgramOptions;
let program: Program;
let processingDefaultLibFiles: SourceFile[] | undefined;
let processingOtherFiles: SourceFile[] | undefined;
@@ -528,6 +545,7 @@ namespace ts {
performance.mark("beforeProgram");
host = host || createCompilerHost(options);
const configParsingHost = parseConfigHostFromCompilerHost(host);
let skipDefaultLib = options.noLib;
const getDefaultLibraryFileName = memoize(() => host.getDefaultLibFileName(options));
@@ -539,6 +557,7 @@ namespace ts {
// Map storing if there is emit blocking diagnostics for given input
const hasEmitBlockingDiagnostics = createMap<boolean>();
let _compilerOptionsObjectLiteralSyntax: ObjectLiteralExpression;
let _referencesArrayLiteralSyntax: ArrayLiteralExpression;
let moduleResolutionCache: ModuleResolutionCache;
let resolveModuleNamesWorker: (moduleNames: string[], containingFile: string, reusedNames?: string[]) => ResolvedModuleFull[];
@@ -583,6 +602,23 @@ namespace ts {
// used to track cases when two file names differ only in casing
const filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? createMap<SourceFile>() : undefined;
// A parallel array to projectReferences storing the results of reading in the referenced tsconfig files
const resolvedProjectReferences: (ResolvedProjectReference | undefined)[] | undefined = projectReferences ? [] : undefined;
const projectReferenceRedirects: Map<string> = createMap();
if (projectReferences) {
for (const ref of projectReferences) {
const parsedRef = parseProjectReferenceConfigFile(ref);
resolvedProjectReferences.push(parsedRef);
if (parsedRef) {
if (parsedRef.commandLine.options.outFile) {
const dtsOutfile = changeExtension(parsedRef.commandLine.options.outFile, ".d.ts");
processSourceFile(dtsOutfile, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined);
}
addProjectReferenceRedirects(parsedRef.commandLine, projectReferenceRedirects);
}
}
}
const shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options);
const structuralIsReused = tryReuseStructureFromOldProgram();
if (structuralIsReused !== StructureIsReused.Completely) {
@@ -676,6 +712,7 @@ namespace ts {
isEmittedFile,
getConfigFileParsingDiagnostics,
getResolvedModuleWithFailedLookupLocationsFromCache,
getProjectReferences
};
verifyCompilerOptions();
@@ -711,12 +748,18 @@ namespace ts {
if (commonSourceDirectory === undefined) {
const emittedFiles = filter(files, file => sourceFileMayBeEmitted(file, options, isSourceFileFromExternalLibrary));
if (options.rootDir && checkSourceFilesBelongToPath(emittedFiles, options.rootDir)) {
// If a rootDir is specified and is valid use it as the commonSourceDirectory
// If a rootDir is specified use it as the commonSourceDirectory
commonSourceDirectory = getNormalizedAbsolutePath(options.rootDir, currentDirectory);
}
else if (options.composite) {
// Project compilations never infer their root from the input source paths
commonSourceDirectory = getDirectoryPath(normalizeSlashes(options.configFilePath));
checkSourceFilesBelongToPath(emittedFiles, commonSourceDirectory);
}
else {
commonSourceDirectory = computeCommonSourceDirectory(emittedFiles);
}
if (commonSourceDirectory && commonSourceDirectory[commonSourceDirectory.length - 1] !== directorySeparator) {
// Make sure directory path ends with directory separator so this string can directly
// used to replace with "" to get the relative path of the source file and the relative path doesn't
@@ -762,7 +805,7 @@ namespace ts {
// We only set `file.resolvedModules` via work from the current function,
// so it is defined iff we already called the current function on `file`.
// That call happened no later than the creation of the `file` object,
// which per above occured during the current program creation.
// which per above occurred during the current program creation.
// Since we assume the filesystem does not change during program creation,
// it is safe to reuse resolutions from the earlier call.
const result: ResolvedModuleFull[] = [];
@@ -918,6 +961,35 @@ namespace ts {
return oldProgram.structureIsReused = StructureIsReused.Not;
}
// Check if any referenced project tsconfig files are different
const oldRefs = oldProgram.getProjectReferences();
if (projectReferences) {
if (!oldRefs) {
return oldProgram.structureIsReused = StructureIsReused.Not;
}
for (let i = 0; i < projectReferences.length; i++) {
const oldRef = oldRefs[i];
if (oldRef) {
const newRef = parseProjectReferenceConfigFile(projectReferences[i]);
if (!newRef || newRef.sourceFile !== oldRef.sourceFile) {
// Resolved project reference has gone missing or changed
return oldProgram.structureIsReused = StructureIsReused.Not;
}
}
else {
// A previously-unresolved reference may be resolved now
if (parseProjectReferenceConfigFile(projectReferences[i]) !== undefined) {
return oldProgram.structureIsReused = StructureIsReused.Not;
}
}
}
}
else {
if (oldRefs) {
return oldProgram.structureIsReused = StructureIsReused.Not;
}
}
// check if program source files has changed in the way that can affect structure of the program
const newSourceFiles: SourceFile[] = [];
const filePaths: Path[] = [];
@@ -1110,6 +1182,7 @@ namespace ts {
function getEmitHost(writeFileCallback?: WriteFileCallback): EmitHost {
return {
getPrependNodes,
getCanonicalFileName,
getCommonSourceDirectory: program.getCommonSourceDirectory,
getCompilerOptions: program.getCompilerOptions,
@@ -1125,6 +1198,35 @@ namespace ts {
};
}
function getProjectReferences() {
if (!resolvedProjectReferences) return;
return resolvedProjectReferences;
}
function getPrependNodes(): InputFiles[] {
if (!projectReferences) {
return emptyArray;
}
const nodes: InputFiles[] = [];
for (let i = 0; i < projectReferences.length; i++) {
const ref = projectReferences[i];
const resolvedRefOpts = resolvedProjectReferences[i].commandLine;
if (ref.prepend && resolvedRefOpts && resolvedRefOpts.options) {
// Upstream project didn't have outFile set -- skip (error will have been issued earlier)
if (!resolvedRefOpts.options.outFile) continue;
const dtsFilename = changeExtension(resolvedRefOpts.options.outFile, ".d.ts");
const js = host.readFile(resolvedRefOpts.options.outFile) || `/* Input file ${resolvedRefOpts.options.outFile} was missing */\r\n`;
const dts = host.readFile(dtsFilename) || `/* Input file ${dtsFilename} was missing */\r\n`;
const node = createInputFiles(js, dts);
nodes.push(node);
}
}
return nodes;
}
function isSourceFileFromExternalLibrary(file: SourceFile): boolean {
return sourceFilesFoundSearchingNodeModules.get(file.path);
}
@@ -1221,7 +1323,9 @@ namespace ts {
getEmitHost(writeFileCallback),
sourceFile,
emitOnlyDtsFiles,
transformers);
transformers,
customTransformers && customTransformers.afterDeclarations
);
performance.mark("afterEmit");
performance.measure("Emit", "beforeEmit", "afterEmit");
@@ -1750,7 +1854,13 @@ namespace ts {
const sourceFile = getSourceFile(fileName);
if (fail) {
if (!sourceFile) {
fail(Diagnostics.File_0_not_found, fileName);
const redirect = getProjectReferenceRedirect(fileName);
if (redirect) {
fail(Diagnostics.Output_file_0_has_not_been_built_from_source_file_1, redirect, fileName);
}
else {
fail(Diagnostics.File_0_not_found, fileName);
}
}
else if (refFile && host.getCanonicalFileName(fileName) === host.getCanonicalFileName(refFile.fileName)) {
fail(Diagnostics.A_file_cannot_have_a_reference_to_itself);
@@ -1848,6 +1958,21 @@ namespace ts {
return file;
}
let redirectedPath: string | undefined;
if (refFile) {
const redirect = getProjectReferenceRedirect(fileName);
if (redirect) {
((refFile.redirectedReferences || (refFile.redirectedReferences = [])) as string[]).push(fileName);
fileName = redirect;
// Once we start redirecting to a file, we can potentially come back to it
// via a back-reference from another file in the .d.ts folder. If that happens we'll
// end up trying to add it to the program *again* because we were tracking it via its
// original (un-redirected) name. So we have to map both the original path and the redirected path
// to the source file we're about to find/create
redirectedPath = toPath(redirect);
}
}
// We haven't looked for this file, do so now and cache result
const file = host.getSourceFile(fileName, options.target, hostErrorMessage => {
if (refFile !== undefined && refPos !== undefined && refEnd !== undefined) {
@@ -1880,6 +2005,10 @@ namespace ts {
}
filesByName.set(path, file);
if (redirectedPath) {
filesByName.set(redirectedPath, file);
}
if (file) {
sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0);
file.path = path;
@@ -1919,6 +2048,23 @@ namespace ts {
return file;
}
function getProjectReferenceRedirect(fileName: string): string | undefined {
const path = toPath(fileName);
// If this file is produced by a referenced project, we need to rewrite it to
// look in the output folder of the referenced project rather than the input
const normalized = getNormalizedAbsolutePath(fileName, path);
let result: string | undefined;
projectReferenceRedirects.forEach((v, k) => {
if (result !== undefined) {
return undefined;
}
if (normalized.indexOf(k) === 0) {
result = changeExtension(fileName.replace(k, v), ".d.ts");
}
});
return result;
}
function processReferencedFiles(file: SourceFile, isDefaultLib: boolean) {
forEach(file.referencedFiles, ref => {
const referencedFileName = resolveTripleslashReference(ref.fileName, file.fileName);
@@ -1929,6 +2075,10 @@ namespace ts {
function processTypeReferenceDirectives(file: SourceFile) {
// We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
const typeDirectives = map(file.typeReferenceDirectives, ref => ref.fileName.toLocaleLowerCase());
if (!typeDirectives) {
return;
}
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeDirectives, file.fileName);
for (let i = 0; i < typeDirectives.length; i++) {
@@ -2109,6 +2259,31 @@ namespace ts {
return allFilesBelongToPath;
}
function parseProjectReferenceConfigFile(ref: ProjectReference): { commandLine: ParsedCommandLine, sourceFile: SourceFile } | undefined {
// The actual filename (i.e. add "/tsconfig.json" if necessary)
const refPath = resolveProjectReferencePath(host, ref);
// An absolute path pointing to the containing directory of the config file
const basePath = getNormalizedAbsolutePath(getDirectoryPath(refPath), host.getCurrentDirectory());
const sourceFile = host.getSourceFile(refPath, ScriptTarget.JSON) as JsonSourceFile;
if (sourceFile === undefined) {
return undefined;
}
const commandLine = parseJsonSourceFileConfigFileContent(sourceFile, configParsingHost, basePath, /*existingOptions*/ undefined, refPath);
return { commandLine, sourceFile };
}
function addProjectReferenceRedirects(referencedProject: ParsedCommandLine, target: Map<string>) {
const rootDir = normalizePath(referencedProject.options.rootDir || getDirectoryPath(referencedProject.options.configFilePath));
target.set(rootDir, getDeclarationOutputDirectory(referencedProject));
}
function getDeclarationOutputDirectory(proj: ParsedCommandLine) {
return proj.options.declarationDir ||
proj.options.outDir ||
getDirectoryPath(proj.options.configFilePath);
}
function verifyCompilerOptions() {
if (options.strictPropertyInitialization && !options.strictNullChecks) {
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "strictPropertyInitialization", "strictNullChecks");
@@ -2145,6 +2320,47 @@ namespace ts {
createDiagnosticForOptionName(Diagnostics.Option_paths_cannot_be_used_without_specifying_baseUrl_option, "paths");
}
if (options.composite) {
if (options.declaration === false) {
createDiagnosticForOptionName(Diagnostics.Composite_projects_may_not_disable_declaration_emit, "declaration");
}
}
if (projectReferences) {
for (let i = 0; i < projectReferences.length; i++) {
const ref = projectReferences[i];
const resolvedRefOpts = resolvedProjectReferences[i] && resolvedProjectReferences[i].commandLine.options;
if (resolvedRefOpts === undefined) {
createDiagnosticForReference(i, Diagnostics.File_0_does_not_exist, ref.path);
continue;
}
if (!resolvedRefOpts.composite) {
createDiagnosticForReference(i, Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true, ref.path);
}
if (ref.prepend) {
if (resolvedRefOpts.outFile) {
if (!host.fileExists(resolvedRefOpts.outFile)) {
createDiagnosticForReference(i, Diagnostics.Output_file_0_from_project_1_does_not_exist, resolvedRefOpts.outFile, ref.path);
}
}
else {
createDiagnosticForReference(i, Diagnostics.Cannot_prepend_project_0_because_it_does_not_have_outFile_set, ref.path);
}
}
}
}
// List of collected files is complete; validate exhautiveness if this is a project with a file list
if (options.composite && rootNames.length < files.length) {
const normalizedRootNames = rootNames.map(r => normalizePath(r).toLowerCase());
const sourceFiles = files.filter(f => !f.isDeclarationFile).map(f => normalizePath(f.path).toLowerCase());
for (const file of sourceFiles) {
if (normalizedRootNames.every(r => r !== file)) {
programDiagnostics.add(createCompilerDiagnostic(Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern, file));
}
}
}
if (options.paths) {
for (const key in options.paths) {
if (!hasProperty(options.paths, key)) {
@@ -2380,12 +2596,16 @@ namespace ts {
}
}
function getOptionPathsSyntax() {
function getOptionsSyntaxByName(name: string): object | undefined {
const compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
if (compilerOptionsObjectLiteralSyntax) {
return getPropertyAssignment(compilerOptionsObjectLiteralSyntax, "paths");
return getPropertyAssignment(compilerOptionsObjectLiteralSyntax, name);
}
return emptyArray;
return undefined;
}
function getOptionPathsSyntax(): PropertyAssignment[] {
return getOptionsSyntaxByName("paths") as PropertyAssignment[] || emptyArray;
}
function createDiagnosticForOptionName(message: DiagnosticMessage, option1: string, option2?: string, option3?: string) {
@@ -2396,6 +2616,16 @@ namespace ts {
createDiagnosticForOption(/*onKey*/ false, option1, /*option2*/ undefined, message, arg0);
}
function createDiagnosticForReference(index: number, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number) {
const referencesSyntax = getProjectReferencesSyntax();
if (referencesSyntax) {
if (createOptionDiagnosticInArrayLiteralSyntax(referencesSyntax, index, message, arg0, arg1)) {
return;
}
}
programDiagnostics.add(createCompilerDiagnostic(message, arg0, arg1));
}
function createDiagnosticForOption(onKey: boolean, option1: string, option2: string, message: DiagnosticMessage, arg0: string | number, arg1?: string | number, arg2?: string | number) {
const compilerOptionsObjectLiteralSyntax = getCompilerOptionsObjectLiteralSyntax();
const needCompilerDiagnostic = !compilerOptionsObjectLiteralSyntax ||
@@ -2406,6 +2636,22 @@ namespace ts {
}
}
function getProjectReferencesSyntax(): ArrayLiteralExpression | null {
if (_referencesArrayLiteralSyntax === undefined) {
_referencesArrayLiteralSyntax = null; // tslint:disable-line:no-null-keyword
if (options.configFile) {
const jsonObjectLiteral = getTsConfigObjectLiteralExpression(options.configFile);
for (const prop of getPropertyAssignment(jsonObjectLiteral, "references")) {
if (isArrayLiteralExpression(prop.initializer)) {
_referencesArrayLiteralSyntax = prop.initializer;
break;
}
}
}
}
return _referencesArrayLiteralSyntax;
}
function getCompilerOptionsObjectLiteralSyntax() {
if (_compilerOptionsObjectLiteralSyntax === undefined) {
_compilerOptionsObjectLiteralSyntax = null; // tslint:disable-line:no-null-keyword
@@ -2430,6 +2676,14 @@ namespace ts {
return !!props.length;
}
function createOptionDiagnosticInArrayLiteralSyntax(arrayLiteral: ArrayLiteralExpression, index: number, message: DiagnosticMessage, arg0: string | number, arg1?: string | number, arg2?: string | number): boolean {
if (arrayLiteral.elements.length <= index) {
// Out-of-bounds
return false;
}
programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile, arrayLiteral.elements[index], message, arg0, arg1, arg2));
}
function blockEmittingOfFile(emitFileName: string, diag: Diagnostic) {
hasEmitBlockingDiagnostics.set(toPath(emitFileName), true);
programDiagnostics.add(diag);
@@ -2471,6 +2725,28 @@ namespace ts {
}
}
/* @internal */
export function parseConfigHostFromCompilerHost(host: CompilerHost): ParseConfigFileHost {
return {
fileExists: f => host.fileExists(f),
readDirectory: (root, extensions, includes, depth?) => host.readDirectory ? host.readDirectory(root, extensions, includes, depth) : [],
readFile: f => host.readFile(f),
useCaseSensitiveFileNames: host.useCaseSensitiveFileNames(),
getCurrentDirectory: () => host.getCurrentDirectory(),
onUnRecoverableConfigFileDiagnostic: () => undefined
};
}
/**
* Returns the target config filename of a project reference
*/
function resolveProjectReferencePath(host: CompilerHost, ref: ProjectReference): string | undefined {
if (!host.fileExists(ref.path)) {
return combinePaths(ref.path, "tsconfig.json");
}
return ref.path;
}
/* @internal */
/**
* Returns a DiagnosticMessage if we won't include a resolved module due to its extension.
+42 -12
View File
@@ -59,12 +59,15 @@ namespace ts {
watcher: FileWatcher;
/** ref count keeping this directory watch alive */
refCount: number;
/** map of refcount for the subDirectory */
subDirectoryMap?: Map<number>;
}
interface DirectoryOfFailedLookupWatch {
dir: string;
dirPath: Path;
ignore?: true;
subDirectory?: Path;
}
export const maxNumberOfFilesToIterateForInvalidation = 256;
@@ -393,18 +396,20 @@ namespace ts {
}
// Use some ancestor of the root directory
let subDirectory: Path | undefined;
if (rootPath !== undefined) {
while (!isInDirectoryPath(dirPath, rootPath)) {
const parentPath = getDirectoryPath(dirPath);
if (parentPath === dirPath) {
break;
}
subDirectory = dirPath.slice(parentPath.length + directorySeparator.length) as Path;
dirPath = parentPath;
dir = getDirectoryPath(dir);
}
}
return filterFSRootDirectoriesToWatch({ dir, dirPath }, dirPath);
return filterFSRootDirectoriesToWatch({ dir, dirPath, subDirectory }, dirPath);
}
function isPathWithDefaultFailedLookupExtension(path: Path) {
@@ -427,7 +432,7 @@ namespace ts {
let setAtRoot = false;
for (const failedLookupLocation of failedLookupLocations) {
const failedLookupLocationPath = resolutionHost.toPath(failedLookupLocation);
const { dir, dirPath, ignore } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
const { dir, dirPath, ignore , subDirectory } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
if (!ignore) {
// If the failed lookup location path is not one of the supported extensions,
// store it in the custom path
@@ -439,7 +444,7 @@ namespace ts {
setAtRoot = true;
}
else {
setDirectoryWatcher(dir, dirPath);
setDirectoryWatcher(dir, dirPath, subDirectory);
}
}
}
@@ -449,13 +454,20 @@ namespace ts {
}
}
function setDirectoryWatcher(dir: string, dirPath: Path) {
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
function setDirectoryWatcher(dir: string, dirPath: Path, subDirectory?: Path) {
let dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
if (dirWatcher) {
dirWatcher.refCount++;
}
else {
directoryWatchesOfFailedLookups.set(dirPath, { watcher: createDirectoryWatcher(dir, dirPath), refCount: 1 });
dirWatcher = { watcher: createDirectoryWatcher(dir, dirPath), refCount: 1 };
directoryWatchesOfFailedLookups.set(dirPath, dirWatcher);
}
if (subDirectory) {
const subDirectoryMap = dirWatcher.subDirectoryMap || (dirWatcher.subDirectoryMap = createMap());
const existing = subDirectoryMap.get(subDirectory) || 0;
subDirectoryMap.set(subDirectory, existing + 1);
}
}
@@ -473,7 +485,7 @@ namespace ts {
let removeAtRoot = false;
for (const failedLookupLocation of failedLookupLocations) {
const failedLookupLocationPath = resolutionHost.toPath(failedLookupLocation);
const { dirPath, ignore } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
const { dirPath, ignore, subDirectory } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
if (!ignore) {
const refCount = customFailedLookupPaths.get(failedLookupLocationPath);
if (refCount) {
@@ -490,7 +502,7 @@ namespace ts {
removeAtRoot = true;
}
else {
removeDirectoryWatcher(dirPath);
removeDirectoryWatcher(dirPath, subDirectory);
}
}
}
@@ -499,24 +511,42 @@ namespace ts {
}
}
function removeDirectoryWatcher(dirPath: string) {
function removeDirectoryWatcher(dirPath: string, subDirectory?: Path) {
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
if (subDirectory) {
const existing = dirWatcher.subDirectoryMap.get(subDirectory);
if (existing === 1) {
dirWatcher.subDirectoryMap.delete(subDirectory);
}
else {
dirWatcher.subDirectoryMap.set(subDirectory, existing - 1);
}
}
// Do not close the watcher yet since it might be needed by other failed lookup locations.
dirWatcher.refCount--;
}
function inWatchedSubdirectory(dirPath: Path, fileOrDirectoryPath: Path) {
const dirWatcher = directoryWatchesOfFailedLookups.get(dirPath);
if (!dirWatcher || !dirWatcher.subDirectoryMap) return false;
return forEachKey(dirWatcher.subDirectoryMap, subDirectory => {
const fullSubDirectory = `${dirPath}/${subDirectory}` as Path;
return fullSubDirectory === fileOrDirectoryPath || isInDirectoryPath(fullSubDirectory, fileOrDirectoryPath);
});
}
function createDirectoryWatcher(directory: string, dirPath: Path) {
return resolutionHost.watchDirectoryOfFailedLookupLocation(directory, fileOrDirectory => {
const fileOrDirectoryPath = resolutionHost.toPath(fileOrDirectory);
if (cachedDirectoryStructureHost) {
// Since the file existance changed, update the sourceFiles cache
// Since the file existence changed, update the sourceFiles cache
cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
}
// If the files are added to project root or node_modules directory, always run through the invalidation process
// Otherwise run through invalidation only if adding to the immediate directory
if (!allFilesHaveInvalidatedResolution &&
dirPath === rootPath || isNodeModulesDirectory(dirPath) || getDirectoryPath(fileOrDirectoryPath) === dirPath) {
(dirPath === rootPath || isNodeModulesDirectory(dirPath) || getDirectoryPath(fileOrDirectoryPath) === dirPath || inWatchedSubdirectory(dirPath, fileOrDirectoryPath))) {
if (invalidateResolutionOfFailedLookupLocation(fileOrDirectoryPath, dirPath === fileOrDirectoryPath)) {
resolutionHost.onInvalidatedResolution();
}
@@ -660,7 +690,7 @@ namespace ts {
return resolutionHost.watchTypeRootsDirectory(typeRoot, fileOrDirectory => {
const fileOrDirectoryPath = resolutionHost.toPath(fileOrDirectory);
if (cachedDirectoryStructureHost) {
// Since the file existance changed, update the sourceFiles cache
// Since the file existence changed, update the sourceFiles cache
cachedDirectoryStructureHost.addOrDeleteFileOrDirectory(fileOrDirectory, fileOrDirectoryPath);
}
+2 -2
View File
@@ -1,6 +1,6 @@
/* @internal */
namespace ts {
function getModuleTransformer(moduleKind: ModuleKind): TransformerFactory<SourceFile> {
function getModuleTransformer(moduleKind: ModuleKind): TransformerFactory<SourceFile | Bundle> {
switch (moduleKind) {
case ModuleKind.ESNext:
case ModuleKind.ES2015:
@@ -28,7 +28,7 @@ namespace ts {
const jsx = compilerOptions.jsx;
const languageVersion = getEmitScriptTarget(compilerOptions);
const moduleKind = getEmitModuleKind(compilerOptions);
const transformers: TransformerFactory<SourceFile>[] = [];
const transformers: TransformerFactory<SourceFile | Bundle>[] = [];
addRange(transformers, customTransformers && customTransformers.before);
+5 -1
View File
@@ -163,7 +163,11 @@ namespace ts {
const updated = visitNodes(sourceFile.statements, visitDeclarationStatements);
return updateSourceFileNode(sourceFile, filterCandidateImports(updated), /*isDeclarationFile*/ true, /*referencedFiles*/ [], /*typeReferences*/ [], /*hasNoDefaultLib*/ false, /*libReferences*/ []);
}
));
), mapDefined(node.prepends, prepend => {
if (prepend.kind === SyntaxKind.InputFiles) {
return createUnparsedSourceFile(prepend.declarationText);
}
}));
bundle.syntheticFileReferences = [];
bundle.syntheticTypeReferences = getFileReferencesForUsedTypeReferences();
bundle.hasNoDefaultLib = hasNoDefaultLib;
+1 -1
View File
@@ -295,7 +295,7 @@ namespace ts {
*/
let enabledSubstitutions: ES2015SubstitutionFlags;
return transformSourceFile;
return chainBundle(transformSourceFile);
function transformSourceFile(node: SourceFile) {
if (node.isDeclarationFile) {
+1 -1
View File
@@ -3,7 +3,7 @@ namespace ts {
export function transformES2016(context: TransformationContext) {
const { hoistVariableDeclaration } = context;
return transformSourceFile;
return chainBundle(transformSourceFile);
function transformSourceFile(node: SourceFile) {
if (node.isDeclarationFile) {
+1 -1
View File
@@ -40,7 +40,7 @@ namespace ts {
context.onEmitNode = onEmitNode;
context.onSubstituteNode = onSubstituteNode;
return transformSourceFile;
return chainBundle(transformSourceFile);
function transformSourceFile(node: SourceFile) {
if (node.isDeclarationFile) {
+1 -1
View File
@@ -24,7 +24,7 @@ namespace ts {
context.onSubstituteNode = onSubstituteNode;
context.enableSubstitution(SyntaxKind.PropertyAccessExpression);
context.enableSubstitution(SyntaxKind.PropertyAssignment);
return transformSourceFile;
return chainBundle(transformSourceFile);
/**
* Transforms an ES5 source file to ES3.
+31 -13
View File
@@ -26,7 +26,7 @@ namespace ts {
let enclosingFunctionFlags: FunctionFlags;
let enclosingSuperContainerFlags: NodeCheckFlags = 0;
return transformSourceFile;
return chainBundle(transformSourceFile);
function transformSourceFile(node: SourceFile) {
if (node.isDeclarationFile) {
@@ -118,21 +118,38 @@ namespace ts {
}
function visitYieldExpression(node: YieldExpression) {
if (enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator && node.asteriskToken) {
const expression = visitNode(node.expression, visitor, isExpression);
if (enclosingFunctionFlags & FunctionFlags.Async && enclosingFunctionFlags & FunctionFlags.Generator) {
if (node.asteriskToken) {
const expression = visitNode(node.expression, visitor, isExpression);
return setOriginalNode(
setTextRange(
createYield(
createAwaitHelper(context,
updateYield(
node,
node.asteriskToken,
createAsyncDelegatorHelper(
context,
createAsyncValuesHelper(context, expression, expression),
expression
)
)
)
),
node
),
node
);
}
return setOriginalNode(
setTextRange(
createYield(
createAwaitHelper(context,
updateYield(
node,
node.asteriskToken,
createAsyncDelegatorHelper(
context,
createAsyncValuesHelper(context, expression, expression),
expression
)
)
createDownlevelAwait(
node.expression
? visitNode(node.expression, visitor, isExpression)
: createVoidZero()
)
),
node
@@ -140,6 +157,7 @@ namespace ts {
node
);
}
return visitEachChild(node, visitor, context);
}
+1 -1
View File
@@ -289,7 +289,7 @@ namespace ts {
let currentExceptionBlock: ExceptionBlock; // The current exception block.
let withBlockStack: WithBlock[]; // A stack containing `with` blocks.
return transformSourceFile;
return chainBundle(transformSourceFile);
function transformSourceFile(node: SourceFile) {
if (node.isDeclarationFile || (node.transformFlags & TransformFlags.ContainsGenerator) === 0) {
+1 -1
View File
@@ -4,7 +4,7 @@ namespace ts {
const compilerOptions = context.getCompilerOptions();
let currentSourceFile: SourceFile;
return transformSourceFile;
return chainBundle(transformSourceFile);
/**
* Transform JSX-specific syntax in a SourceFile.
+1 -1
View File
@@ -10,7 +10,7 @@ namespace ts {
context.enableSubstitution(SyntaxKind.Identifier);
let currentSourceFile: SourceFile;
return transformSourceFile;
return chainBundle(transformSourceFile);
function transformSourceFile(node: SourceFile) {
if (node.isDeclarationFile) {
+1 -1
View File
@@ -45,7 +45,7 @@ namespace ts {
let noSubstitution: boolean[]; // Set of nodes for which substitution rules should be ignored.
let needUMDDynamicImportHelper: boolean;
return transformSourceFile;
return chainBundle(transformSourceFile);
/**
* Transforms the module aspects of a SourceFile.
+1 -1
View File
@@ -39,7 +39,7 @@ namespace ts {
let enclosingBlockScopedContainer: Node;
let noSubstitution: boolean[]; // Set of nodes for which substitution rules should be ignored.
return transformSourceFile;
return chainBundle(transformSourceFile);
/**
* Transforms the module aspects of a SourceFile.
+17 -1
View File
@@ -88,7 +88,23 @@ namespace ts {
*/
let pendingExpressions: Expression[] | undefined;
return transformSourceFile;
return transformSourceFileOrBundle;
function transformSourceFileOrBundle(node: SourceFile | Bundle) {
if (node.kind === SyntaxKind.Bundle) {
return transformBundle(node);
}
return transformSourceFile(node);
}
function transformBundle(node: Bundle) {
return createBundle(node.sourceFiles.map(transformSourceFile), mapDefined(node.prepends, prepend => {
if (prepend.kind === SyntaxKind.InputFiles) {
return createUnparsedSourceFile(prepend.javascriptText);
}
return prepend;
}));
}
/**
* Transform TypeScript-specific syntax in a SourceFile.
+12
View File
@@ -25,6 +25,18 @@ namespace ts {
return e.propertyName && e.propertyName.escapedText === InternalSymbolName.Default;
}
export function chainBundle(transformSourceFile: (x: SourceFile) => SourceFile): (x: SourceFile | Bundle) => SourceFile | Bundle {
return transformSourceFileOrBundle;
function transformSourceFileOrBundle(node: SourceFile | Bundle) {
return node.kind === SyntaxKind.SourceFile ? transformSourceFile(node) : transformBundle(node);
}
function transformBundle(node: Bundle) {
return createBundle(map(node.sourceFiles, transformSourceFile), node.prepends);
}
}
export function getImportNeedsImportStarHelper(node: ImportDeclaration) {
if (!!getNamespaceDeclarationNode(node)) {
return true;
+13 -6
View File
@@ -120,7 +120,7 @@ namespace ts {
createWatchOfConfigFile(configParseResult, commandLineOptions);
}
else {
performCompilation(configParseResult.fileNames, configParseResult.options, getConfigFileParsingDiagnostics(configParseResult));
performCompilation(configParseResult.fileNames, configParseResult.projectReferences, configParseResult.options, getConfigFileParsingDiagnostics(configParseResult));
}
}
else {
@@ -130,7 +130,7 @@ namespace ts {
createWatchOfFilesAndCompilerOptions(commandLine.fileNames, commandLineOptions);
}
else {
performCompilation(commandLine.fileNames, commandLineOptions);
performCompilation(commandLine.fileNames, /*references*/ undefined, commandLineOptions);
}
}
}
@@ -142,11 +142,18 @@ namespace ts {
}
}
function performCompilation(rootFileNames: string[], compilerOptions: CompilerOptions, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>) {
const compilerHost = createCompilerHost(compilerOptions);
enableStatistics(compilerOptions);
function performCompilation(rootNames: string[], projectReferences: ReadonlyArray<ProjectReference> | undefined, options: CompilerOptions, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>) {
const host = createCompilerHost(options);
enableStatistics(options);
const program = createProgram(rootFileNames, compilerOptions, compilerHost, /*oldProgram*/ undefined, configFileParsingDiagnostics);
const programOptions: CreateProgramOptions = {
rootNames,
options,
projectReferences,
host,
configFileParsingDiagnostics
};
const program = createProgram(programOptions);
const exitStatus = emitFilesAndReportErrors(program, reportDiagnostic, s => sys.write(s + sys.newLine));
reportStatistics(program);
return sys.exit(exitStatus);
+79 -6
View File
@@ -397,6 +397,8 @@ namespace ts {
// Top-level nodes
SourceFile,
Bundle,
UnparsedSource,
InputFiles,
// JSDoc nodes
JSDocTypeExpression,
@@ -1877,7 +1879,7 @@ namespace ts {
}
/**
* A list of comma-seperated expressions. This node is only created by transformations.
* A list of comma-separated expressions. This node is only created by transformations.
*/
export interface CommaListExpression extends Expression {
kind: SyntaxKind.CommaListExpression;
@@ -2602,6 +2604,12 @@ namespace ts {
/* @internal */ resolvedModules: Map<ResolvedModuleFull | undefined>;
/* @internal */ resolvedTypeReferenceDirectiveNames: Map<ResolvedTypeReferenceDirective>;
/* @internal */ imports: ReadonlyArray<StringLiteralLike>;
/**
* When a file's references are redirected due to project reference directives,
* the original names of the references are stored in this array
*/
/* @internal*/
redirectedReferences?: ReadonlyArray<string>;
// Identifier only if `declare global`
/* @internal */ moduleAugmentations: ReadonlyArray<StringLiteral | Identifier>;
/* @internal */ patternAmbientModules?: PatternAmbientModule[];
@@ -2615,12 +2623,24 @@ namespace ts {
export interface Bundle extends Node {
kind: SyntaxKind.Bundle;
prepends: ReadonlyArray<InputFiles | UnparsedSource>;
sourceFiles: ReadonlyArray<SourceFile>;
/* @internal */ syntheticFileReferences?: ReadonlyArray<FileReference>;
/* @internal */ syntheticTypeReferences?: ReadonlyArray<FileReference>;
/* @internal */ hasNoDefaultLib?: boolean;
}
export interface InputFiles extends Node {
kind: SyntaxKind.InputFiles;
javascriptText: string;
declarationText: string;
}
export interface UnparsedSource extends Node {
kind: SyntaxKind.UnparsedSource;
text: string;
}
export interface JsonSourceFile extends SourceFile {
statements: NodeArray<JsonObjectExpressionStatement>;
}
@@ -2752,6 +2772,13 @@ namespace ts {
/* @internal */ isEmittedFile(file: string): boolean;
/* @internal */ getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations | undefined;
getProjectReferences(): (ResolvedProjectReference | undefined)[] | undefined;
}
export interface ResolvedProjectReference {
commandLine: ParsedCommandLine;
sourceFile: SourceFile;
}
/* @internal */
@@ -2762,10 +2789,12 @@ namespace ts {
}
export interface CustomTransformers {
/** Custom transformers to evaluate before built-in transformations. */
/** Custom transformers to evaluate before built-in .js transformations. */
before?: TransformerFactory<SourceFile>[];
/** Custom transformers to evaluate after built-in transformations. */
/** Custom transformers to evaluate after built-in .js transformations. */
after?: TransformerFactory<SourceFile>[];
/** Custom transformers to evaluate after built-in .d.ts transformations. */
afterDeclarations?: TransformerFactory<Bundle | SourceFile>[];
}
export interface SourceMapSpan {
@@ -4176,7 +4205,18 @@ namespace ts {
name: string;
}
export type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]> | PluginImport[] | null | undefined;
export interface ProjectReference {
/** A normalized path on disk */
path: string;
/** The path as the user originally wrote it */
originalPath?: string;
/** True if the output of this reference should be prepended to the output of this project. Only valid for --outFile compilations */
prepend?: boolean;
/** True if it is intended that this reference form a circularity */
circular?: boolean;
}
export type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]> | PluginImport[] | ProjectReference[] | null | undefined;
export interface CompilerOptions {
/*@internal*/ all?: boolean;
@@ -4248,6 +4288,7 @@ namespace ts {
/* @internal */ pretty?: boolean;
reactNamespace?: string;
jsxFactory?: string;
composite?: boolean;
removeComments?: boolean;
rootDir?: string;
rootDirs?: string[];
@@ -4341,12 +4382,13 @@ namespace ts {
ES2017 = 4,
ES2018 = 5,
ESNext = 6,
JSON = 100,
Latest = ESNext,
}
export const enum LanguageVariant {
Standard,
JSX,
JSX
}
/** Either a parsed command line or a parsed tsconfig.json */
@@ -4354,6 +4396,7 @@ namespace ts {
options: CompilerOptions;
typeAcquisition?: TypeAcquisition;
fileNames: string[];
projectReferences?: ReadonlyArray<ProjectReference>;
raw?: any;
errors: Diagnostic[];
wildcardDirectories?: MapLike<WatchDirectoryFlags>;
@@ -4369,6 +4412,7 @@ namespace ts {
/* @internal */
export interface ConfigFileSpecs {
filesSpecs: ReadonlyArray<string>;
referencesSpecs: ReadonlyArray<ProjectReference> | undefined;
/**
* Present to report errors (user specified specs), validatedIncludeSpecs are used for file name matching
*/
@@ -4384,10 +4428,20 @@ namespace ts {
export interface ExpandResult {
fileNames: string[];
projectReferences: ReadonlyArray<ProjectReference> | undefined;
wildcardDirectories: MapLike<WatchDirectoryFlags>;
/* @internal */ spec: ConfigFileSpecs;
}
export interface CreateProgramOptions {
rootNames: ReadonlyArray<string>;
options: CompilerOptions;
projectReferences?: ReadonlyArray<ProjectReference>;
host?: CompilerHost;
oldProgram?: Program;
configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>;
}
/* @internal */
export interface CommandLineOptionBase {
name: string;
@@ -4674,6 +4728,7 @@ namespace ts {
getCanonicalFileName(fileName: string): string;
useCaseSensitiveFileNames(): boolean;
getNewLine(): string;
readDirectory?(rootDir: string, extensions: ReadonlyArray<string>, excludes: ReadonlyArray<string> | undefined, includes: ReadonlyArray<string>, depth?: number): string[];
/*
* CompilerHost must either implement resolveModuleNames (in case if it wants to be completely in charge of
@@ -4912,6 +4967,8 @@ namespace ts {
isEmitBlocked(emitFileName: string): boolean;
getPrependNodes(): ReadonlyArray<InputFiles>;
writeFile: WriteFileCallback;
}
@@ -5063,7 +5120,23 @@ namespace ts {
/*@internal*/ writeNode(hint: EmitHint, node: Node, sourceFile: SourceFile | undefined, writer: EmitTextWriter): void;
/*@internal*/ writeList<T extends Node>(format: ListFormat, list: NodeArray<T>, sourceFile: SourceFile | undefined, writer: EmitTextWriter): void;
/*@internal*/ writeFile(sourceFile: SourceFile, writer: EmitTextWriter): void;
/*@internal*/ writeBundle(bundle: Bundle, writer: EmitTextWriter): void;
/*@internal*/ writeBundle(bundle: Bundle, writer: EmitTextWriter, info?: BundleInfo): void;
}
/**
* When a bundle contains prepended content, we store a file on disk indicating where the non-prepended
* content of that file starts. On a subsequent build where there are no upstream .d.ts changes, we
* read the bundle info file and the original .js file to quickly re-use portion of the file
* that didn't originate in prepended content.
*/
/* @internal */
export interface BundleInfo {
// The offset (in characters, i.e. suitable for .substr) at which the
// non-prepended portion of the emitted file starts.
originalOffset: number;
// The total length of this bundle. Used to ensure we're pulling from
// the same source as we originally wrote.
totalLength: number;
}
export interface PrintHandlers {
+9 -9
View File
@@ -6,13 +6,6 @@ namespace ts {
export const externalHelpersModuleNameText = "tslib";
export interface ReferencePathMatchResult {
fileReference?: FileReference;
diagnosticMessage?: DiagnosticMessage;
isNoDefaultLib?: boolean;
isTypeReferenceDirective?: boolean;
}
export function getDeclarationOfKind<T extends Declaration>(symbol: Symbol, kind: T["kind"]): T {
const declarations = symbol.declarations;
if (declarations) {
@@ -2109,8 +2102,14 @@ namespace ts {
if (isDeclaration(name.parent)) {
return name.parent.name === name;
}
const binExp = name.parent.parent;
return isBinaryExpression(binExp) && getSpecialPropertyAssignmentKind(binExp) !== SpecialPropertyAssignmentKind.None && getNameOfDeclaration(binExp) === name;
else if (isQualifiedName(name.parent)) {
const tag = name.parent.parent;
return isJSDocParameterTag(tag) && tag.name === name.parent;
}
else {
const binExp = name.parent.parent;
return isBinaryExpression(binExp) && getSpecialPropertyAssignmentKind(binExp) !== SpecialPropertyAssignmentKind.None && getNameOfDeclaration(binExp) === name;
}
default:
return false;
}
@@ -2916,6 +2915,7 @@ namespace ts {
sourceMapFilePath: string | undefined;
declarationFilePath: string | undefined;
declarationMapPath: string | undefined;
bundleInfoPath: string | undefined;
}
/**
-42
View File
@@ -86,13 +86,6 @@ namespace ts {
};
}
/**
* Interface extending ParseConfigHost to support ParseConfigFile that reads config file and reports errors
*/
export interface ParseConfigFileHost extends ParseConfigHost, ConfigFileDiagnosticsReporter {
getCurrentDirectory(): string;
}
/** Parses config file using System interface */
export function parseConfigFileWithSystem(configFileName: string, optionsToExtend: CompilerOptions, system: System, reportDiagnostic: DiagnosticReporter) {
const host: ParseConfigFileHost = <any>system;
@@ -102,30 +95,6 @@ namespace ts {
return result;
}
/**
* Reads the config file, reports errors if any and exits if the config file cannot be found
*/
export function getParsedCommandLineOfConfigFile(configFileName: string, optionsToExtend: CompilerOptions, host: ParseConfigFileHost): ParsedCommandLine | undefined {
let configFileText: string;
try {
configFileText = host.readFile(configFileName);
}
catch (e) {
const error = createCompilerDiagnostic(Diagnostics.Cannot_read_file_0_Colon_1, configFileName, e.message);
host.onUnRecoverableConfigFileDiagnostic(error);
return undefined;
}
if (!configFileText) {
const error = createCompilerDiagnostic(Diagnostics.File_0_not_found, configFileName);
host.onUnRecoverableConfigFileDiagnostic(error);
return undefined;
}
const result = parseJsonText(configFileName, configFileText);
const cwd = host.getCurrentDirectory();
return parseJsonSourceFileConfigFileContent(result, host, getNormalizedAbsolutePath(getDirectoryPath(configFileName), cwd), optionsToExtend, getNormalizedAbsolutePath(configFileName, cwd));
}
/**
* Program structure needed to emit the files and report diagnostics
*/
@@ -297,7 +266,6 @@ namespace ts {
}
namespace ts {
export type DiagnosticReporter = (diagnostic: Diagnostic) => void;
export type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string, options: CompilerOptions) => void;
/** Create the program with rootNames and options, if they are undefined, oldProgram and new configFile diagnostics create new program */
export type CreateProgram<T extends BuilderProgram> = (rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: T, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>) => T;
@@ -382,16 +350,6 @@ namespace ts {
options: CompilerOptions;
}
/**
* Reports config file diagnostics
*/
export interface ConfigFileDiagnosticsReporter {
/**
* Reports unrecoverable error when parsing config file
*/
onUnRecoverableConfigFileDiagnostic: DiagnosticReporter;
}
/**
* Host to create watch with config file
*/
+1 -2
View File
@@ -10,8 +10,7 @@ namespace compiler {
export function readProject(host: fakes.ParseConfigHost, project: string | undefined, existingOptions?: ts.CompilerOptions): Project | undefined {
if (project) {
project = host.vfs.stringComparer(vpath.basename(project), "tsconfig.json") === 0 ? project :
vpath.combine(project, "tsconfig.json");
project = vpath.isTsConfigFile(project) ? project : vpath.combine(project, "tsconfig.json");
}
else {
[project] = host.vfs.scanSync(".", "ancestors-or-self", {
+10 -8
View File
@@ -39,9 +39,7 @@ namespace fakes {
public readFile(path: string) {
try {
const content = this.vfs.readFileSync(path, "utf8");
return content === undefined ? undefined :
vpath.extname(path) === ".json" ? utils.removeComments(utils.removeByteOrderMark(content), utils.CommentRemoval.leadingAndTrailing) :
utils.removeByteOrderMark(content);
return content === undefined ? undefined : utils.removeByteOrderMark(content);
}
catch {
return undefined;
@@ -203,6 +201,7 @@ namespace fakes {
public readonly sys: System;
public readonly defaultLibLocation: string;
public readonly outputs: documents.TextDocument[] = [];
private readonly _outputsMap: collections.SortedMap<string, number>;
public readonly traces: string[] = [];
public readonly shouldAssertInvariants = !Harness.lightMode;
@@ -218,6 +217,7 @@ namespace fakes {
this._newLine = ts.getNewLineCharacter(options, () => this.sys.newLine);
this._sourceFiles = new collections.SortedMap<string, ts.SourceFile>({ comparer: sys.vfs.stringComparer, sort: "insertion" });
this._setParentNodes = setParentNodes;
this._outputsMap = new collections.SortedMap(this.vfs.stringComparer);
}
public get vfs() {
@@ -256,6 +256,10 @@ namespace fakes {
return this.sys.getDirectories(path);
}
public readDirectory(path: string, extensions?: ReadonlyArray<string>, exclude?: ReadonlyArray<string>, include?: ReadonlyArray<string>, depth?: number): string[] {
return this.sys.readDirectory(path, extensions, exclude, include, depth);
}
public readFile(path: string): string | undefined {
return this.sys.readFile(path);
}
@@ -267,13 +271,11 @@ namespace fakes {
const document = new documents.TextDocument(fileName, content);
document.meta.set("fileName", fileName);
this.vfs.filemeta(fileName).set("document", document);
const index = this.outputs.findIndex(output => this.vfs.stringComparer(document.file, output.file) === 0);
if (index < 0) {
if (!this._outputsMap.has(document.file)) {
this._outputsMap.set(document.file, this.outputs.length);
this.outputs.push(document);
}
else {
this.outputs[index] = document;
}
this.outputs[this._outputsMap.get(document.file)] = document;
}
public trace(s: string): void {
+23 -71
View File
@@ -957,7 +957,14 @@ namespace FourSlash {
}
public verifyCompletionsAt(markerName: string | ReadonlyArray<string>, expected: ReadonlyArray<FourSlashInterface.ExpectedCompletionEntry>, options?: FourSlashInterface.CompletionsAtOptions) {
this.verifyCompletions({ marker: markerName, exact: expected, isNewIdentifierLocation: options && options.isNewIdentifierLocation, preferences: options, triggerCharacter: options && options.triggerCharacter });
this.verifyCompletions({
marker: markerName,
exact: expected,
isNewIdentifierLocation: options && options.isNewIdentifierLocation,
preferences: options,
// TODO: GH#20090
triggerCharacter: (options && options.triggerCharacter) as ts.CompletionsTriggerCharacter | undefined,
});
}
public verifyCompletionListContains(entryId: ts.Completions.CompletionEntryIdentifier, text?: string, documentation?: string, kind?: string | { kind?: string, kindModifiers?: string }, spanIndex?: number, hasAction?: boolean, options?: FourSlashInterface.VerifyCompletionListContainsOptions) {
@@ -1142,32 +1149,6 @@ namespace FourSlash {
}
}
private verifyReferencesAre(expectedReferences: Range[]) {
const actualReferences = this.getReferencesAtCaret() || [];
if (actualReferences.length > expectedReferences.length) {
// Find the unaccounted-for reference.
for (const actual of actualReferences) {
if (!ts.forEach(expectedReferences, r => r.pos === actual.textSpan.start)) {
this.raiseError(`A reference ${stringify(actual)} is unaccounted for.`);
}
}
// Probably will never reach here.
this.raiseError(`There are ${actualReferences.length} references but only ${expectedReferences.length} were expected.`);
}
for (const reference of expectedReferences) {
const { fileName, pos, end } = reference;
if (reference.marker && reference.marker.data) {
const { isWriteAccess, isDefinition } = reference.marker.data as { isWriteAccess?: boolean, isDefinition?: boolean };
this.verifyReferencesWorker(actualReferences, fileName, pos, end, isWriteAccess, isDefinition);
}
else {
this.verifyReferencesWorker(actualReferences, fileName, pos, end);
}
}
}
private verifyDocumentHighlightsRespectFilesList(files: ReadonlyArray<string>): void {
const startFile = this.activeFile.fileName;
for (const fileName of files) {
@@ -1179,20 +1160,6 @@ namespace FourSlash {
}
}
public verifyReferencesOf(range: Range, references: Range[]) {
this.goToRangeStart(range);
this.verifyDocumentHighlightsRespectFilesList(unique(references, e => e.fileName));
this.verifyReferencesAre(references);
}
public verifyRangesReferenceEachOther(ranges?: Range[]) {
ranges = ranges || this.getRanges();
assert(ranges.length);
for (const range of ranges) {
this.verifyReferencesOf(range, ranges);
}
}
public verifyReferenceGroups(starts: ArrayOrSingle<string> | ArrayOrSingle<Range>, parts: ReadonlyArray<FourSlashInterface.ReferenceGroup> | undefined): void {
interface ReferenceGroupJson {
definition: string | { text: string, range: ts.TextSpan };
@@ -1250,6 +1217,12 @@ namespace FourSlash {
}
}
// Necessary to have this function since `findReferences` isn't implemented in `client.ts`
public verifyGetReferencesForServerTest(expected: ReadonlyArray<ts.ReferenceEntry>): void {
const refs = this.getReferencesAtCaret();
assert.deepEqual(refs, expected);
}
public verifySingleReferenceGroup(definition: FourSlashInterface.ReferenceGroupDefinition, ranges?: Range[]) {
ranges = ranges || this.getRanges();
this.verifyReferenceGroups(ranges, [{ definition, ranges }]);
@@ -1314,23 +1287,6 @@ Actual: ${stringify(fullActual)}`);
TestState.getDisplayPartsJson(expected), this.messageAtLastKnownMarker("referenced symbol definition display parts"));
}
private verifyReferencesWorker(references: ts.ReferenceEntry[], fileName: string, start: number, end: number, isWriteAccess?: boolean, isDefinition?: boolean) {
for (const reference of references) {
if (reference && reference.fileName === fileName && reference.textSpan.start === start && ts.textSpanEnd(reference.textSpan) === end) {
if (typeof isWriteAccess !== "undefined" && reference.isWriteAccess !== isWriteAccess) {
this.raiseError(`verifyReferencesAtPositionListContains failed - item isWriteAccess value does not match, actual: ${reference.isWriteAccess}, expected: ${isWriteAccess}.`);
}
if (typeof isDefinition !== "undefined" && reference.isDefinition !== isDefinition) {
this.raiseError(`verifyReferencesAtPositionListContains failed - item isDefinition value does not match, actual: ${reference.isDefinition}, expected: ${isDefinition}.`);
}
return;
}
}
const missingItem = { fileName, start, end, isWriteAccess, isDefinition };
this.raiseError(`verifyReferencesAtPositionListContains failed - could not find the item: ${stringify(missingItem)} in the returned list: (${stringify(references)})`);
}
private getCompletionListAtCaret(options?: ts.GetCompletionsAtPositionOptions): ts.CompletionInfo {
return this.languageService.getCompletionsAtPosition(this.activeFile.fileName, this.currentCaretPosition, options);
}
@@ -2470,7 +2426,7 @@ Actual: ${stringify(fullActual)}`);
Harness.IO.log(stringify(spans));
}
public verifyOutliningSpans(spans: Range[], kind?: "comment" | "region" | "code") {
public verifyOutliningSpans(spans: Range[], kind?: "comment" | "region" | "code" | "imports") {
const actual = this.languageService.getOutliningSpans(this.activeFile.fileName);
if (actual.length !== spans.length) {
@@ -4210,10 +4166,6 @@ namespace FourSlashInterface {
this.state.verifyTypeOfSymbolAtLocation(range, symbol, expected);
}
public referencesOf(start: FourSlash.Range, references: FourSlash.Range[]) {
this.state.verifyReferencesOf(start, references);
}
public referenceGroups(starts: Many<string> | Many<FourSlash.Range>, parts: ReferenceGroup[]) {
this.state.verifyReferenceGroups(starts, parts);
}
@@ -4222,12 +4174,12 @@ namespace FourSlashInterface {
this.state.verifyNoReferences(markerNameOrRange);
}
public singleReferenceGroup(definition: ReferenceGroupDefinition, ranges?: FourSlash.Range[]) {
this.state.verifySingleReferenceGroup(definition, ranges);
public getReferencesForServerTest(expected: ReadonlyArray<ts.ReferenceEntry>) {
this.state.verifyGetReferencesForServerTest(expected);
}
public rangesReferenceEachOther(ranges?: FourSlash.Range[]) {
this.state.verifyRangesReferenceEachOther(ranges);
public singleReferenceGroup(definition: ReferenceGroupDefinition, ranges?: FourSlash.Range[]) {
this.state.verifySingleReferenceGroup(definition, ranges);
}
public findReferencesDefinitionDisplayPartsAtCaretAre(expected: ts.SymbolDisplayPart[]) {
@@ -4302,7 +4254,7 @@ namespace FourSlashInterface {
this.state.verifyCurrentNameOrDottedNameSpanText(text);
}
public outliningSpansInCurrentFile(spans: FourSlash.Range[], kind?: "comment" | "region" | "code") {
public outliningSpansInCurrentFile(spans: FourSlash.Range[], kind?: "comment" | "region" | "code" | "imports") {
this.state.verifyOutliningSpans(spans, kind);
}
@@ -4774,7 +4726,7 @@ namespace FourSlashInterface {
readonly sourceDisplay?: string;
};
export interface CompletionsAtOptions extends Partial<ts.UserPreferences> {
triggerCharacter?: string;
triggerCharacter?: ts.CompletionsTriggerCharacter;
isNewIdentifierLocation?: boolean;
}
@@ -4785,13 +4737,13 @@ namespace FourSlashInterface {
readonly includes?: Many<ExpectedCompletionEntry>;
readonly excludes?: Many<string | { readonly name: string, readonly source: string }>;
readonly preferences: ts.UserPreferences;
readonly triggerCharacter?: string;
readonly triggerCharacter?: ts.CompletionsTriggerCharacter;
}
export type Many<T> = T | ReadonlyArray<T>;
export interface VerifyCompletionListContainsOptions extends ts.UserPreferences {
triggerCharacter?: string;
triggerCharacter?: ts.CompletionsTriggerCharacter;
sourceDisplay: string;
isRecommended?: true;
insertText?: string;
+27 -47
View File
@@ -21,10 +21,6 @@ namespace RWC {
}
}
function isTsConfigFile(file: { path: string }): boolean {
return file.path.indexOf("tsconfig") !== -1 && file.path.indexOf("json") !== -1;
}
export function runRWCTest(jsonPath: string) {
describe("Testing a rwc project: " + jsonPath, () => {
let inputFiles: Harness.Compiler.TestFile[] = [];
@@ -69,11 +65,10 @@ namespace RWC {
// we will set noEmitOnError flag to be false.
opts.options.noEmitOnError = false;
});
let fileNames = opts.fileNames;
runWithIOLog(ioLog, oldIO => {
let fileNames = opts.fileNames;
const tsconfigFile = ts.forEach(ioLog.filesRead, f => isTsConfigFile(f) ? f : undefined);
runWithIOLog(ioLog, () => {
const tsconfigFile = ts.forEach(ioLog.filesRead, f => vpath.isTsConfigFile(f.path) ? f : undefined);
if (tsconfigFile) {
const tsconfigFileContents = getHarnessCompilerInputUnit(tsconfigFile.path);
tsconfigFiles.push({ unitName: tsconfigFile.path, content: tsconfigFileContents.content });
@@ -103,55 +98,40 @@ namespace RWC {
}
// Add files to compilation
const isInInputList = (resolvedPath: string) => (inputFile: { unitName: string; content: string; }) => inputFile.unitName === resolvedPath;
for (const fileRead of ioLog.filesRead) {
// Check if the file is already added into the set of input files.
const resolvedPath = ts.normalizeSlashes(Harness.IO.resolvePath(fileRead.path));
const inInputList = ts.forEach(inputFiles, isInInputList(resolvedPath));
if (isTsConfigFile(fileRead)) {
continue;
}
if (!Harness.isDefaultLibraryFile(fileRead.path)) {
if (inInputList) {
continue;
}
const normalized = ts.normalizeSlashes(fileRead.path);
if (!uniqueNames.has(normalized) && !Harness.isDefaultLibraryFile(fileRead.path)) {
uniqueNames.set(normalized, true);
otherFiles.push(getHarnessCompilerInputUnit(fileRead.path));
}
else if (!opts.options.noLib && Harness.isDefaultLibraryFile(fileRead.path)) {
if (!inInputList) {
// If useCustomLibraryFile is true, we will use lib.d.ts from json object
// otherwise use the lib.d.ts from built/local
// Majority of RWC code will be using built/local/lib.d.ts instead of
// lib.d.ts inside json file. However, some RWC cases will still use
// their own version of lib.d.ts because they have customized lib.d.ts
if (useCustomLibraryFile) {
inputFiles.push(getHarnessCompilerInputUnit(fileRead.path));
}
else {
// set the flag to put default library to the beginning of the list
inputFiles.unshift(Harness.getDefaultLibraryFile(fileRead.path, oldIO));
}
}
else if (!opts.options.noLib && Harness.isDefaultLibraryFile(fileRead.path) && !uniqueNames.has(normalized) && useCustomLibraryFile) {
// If useCustomLibraryFile is true, we will use lib.d.ts from json object
// otherwise use the lib.d.ts from built/local
// Majority of RWC code will be using built/local/lib.d.ts instead of
// lib.d.ts inside json file. However, some RWC cases will still use
// their own version of lib.d.ts because they have customized lib.d.ts
uniqueNames.set(normalized, true);
inputFiles.push(getHarnessCompilerInputUnit(fileRead.path));
}
}
});
if (useCustomLibraryFile) {
// do not use lib since we already read it in above
opts.options.lib = undefined;
opts.options.noLib = true;
}
// Emit the results
compilerResult = Harness.Compiler.compileFiles(
inputFiles,
otherFiles,
/* harnessOptions */ undefined,
opts.options,
// Since each RWC json file specifies its current directory in its json file, we need
// to pass this information in explicitly instead of acquiring it from the process.
currentDirectory);
compilerOptions = compilerResult.options;
});
// Emit the results
compilerResult = Harness.Compiler.compileFiles(
inputFiles,
otherFiles,
/* harnessOptions */ undefined,
opts.options,
// Since each RWC json file specifies its current directory in its json file, we need
// to pass this information in explicitly instead of acquiring it from the process.
currentDirectory);
compilerOptions = compilerResult.options;
function getHarnessCompilerInputUnit(fileName: string): Harness.Compiler.TestFile {
const unitName = ts.normalizeSlashes(Harness.IO.resolvePath(fileName));
+19 -19
View File
@@ -11,7 +11,7 @@ namespace ts.projectSystem {
}
describe("CompileOnSave affected list", () => {
function sendAffectedFileRequestAndCheckResult(session: server.Session, request: server.protocol.Request, expectedFileList: { projectFileName: string, files: FileOrFolder[] }[]) {
function sendAffectedFileRequestAndCheckResult(session: server.Session, request: server.protocol.Request, expectedFileList: { projectFileName: string, files: File[] }[]) {
const response = session.executeCommand(request).response as server.protocol.CompileOnSaveAffectedFileListSingleProject[];
const actualResult = response.sort((list1, list2) => compareStringsCaseSensitive(list1.projectFileName, list2.projectFileName));
expectedFileList = expectedFileList.sort((list1, list2) => compareStringsCaseSensitive(list1.projectFileName, list2.projectFileName));
@@ -47,12 +47,12 @@ namespace ts.projectSystem {
}
describe("for configured projects", () => {
let moduleFile1: FileOrFolder;
let file1Consumer1: FileOrFolder;
let file1Consumer2: FileOrFolder;
let moduleFile2: FileOrFolder;
let globalFile3: FileOrFolder;
let configFile: FileOrFolder;
let moduleFile1: File;
let file1Consumer1: File;
let file1Consumer2: File;
let moduleFile2: File;
let globalFile3: File;
let configFile: File;
let changeModuleFile1ShapeRequest1: server.protocol.Request;
let changeModuleFile1InternalRequest1: server.protocol.Request;
// A compile on save affected file request using file1
@@ -225,7 +225,7 @@ namespace ts.projectSystem {
openFilesForSession([moduleFile1], session);
sendAffectedFileRequestAndCheckResult(session, moduleFile1FileListRequest, [{ projectFileName: configFile.path, files: [moduleFile1, file1Consumer1, file1Consumer2] }]);
const file1Consumer3: FileOrFolder = {
const file1Consumer3: File = {
path: "/a/b/file1Consumer3.ts",
content: `import {Foo} from "./moduleFile1"; let y = Foo();`
};
@@ -330,7 +330,7 @@ namespace ts.projectSystem {
}`
};
const configFile2: FileOrFolder = {
const configFile2: File = {
path: "/a/tsconfig.json",
content: `{
"compileOnSave": true
@@ -403,7 +403,7 @@ namespace ts.projectSystem {
});
it("should return cascaded affected file list", () => {
const file1Consumer1Consumer1: FileOrFolder = {
const file1Consumer1Consumer1: File = {
path: "/a/b/file1Consumer1Consumer1.ts",
content: `import {y} from "./file1Consumer1";`
};
@@ -428,13 +428,13 @@ namespace ts.projectSystem {
});
it("should work fine for files with circular references", () => {
const file1: FileOrFolder = {
const file1: File = {
path: "/a/b/file1.ts",
content: `
/// <reference path="./file2.ts" />
export var t1 = 10;`
};
const file2: FileOrFolder = {
const file2: File = {
path: "/a/b/file2.ts",
content: `
/// <reference path="./file1.ts" />
@@ -450,11 +450,11 @@ namespace ts.projectSystem {
});
it("should return results for all projects if not specifying projectFileName", () => {
const file1: FileOrFolder = { path: "/a/b/file1.ts", content: "export var t = 10;" };
const file2: FileOrFolder = { path: "/a/b/file2.ts", content: `import {t} from "./file1"; var t2 = 11;` };
const file3: FileOrFolder = { path: "/a/c/file2.ts", content: `import {t} from "../b/file1"; var t3 = 11;` };
const configFile1: FileOrFolder = { path: "/a/b/tsconfig.json", content: `{ "compileOnSave": true }` };
const configFile2: FileOrFolder = { path: "/a/c/tsconfig.json", content: `{ "compileOnSave": true }` };
const file1: File = { path: "/a/b/file1.ts", content: "export var t = 10;" };
const file2: File = { path: "/a/b/file2.ts", content: `import {t} from "./file1"; var t2 = 11;` };
const file3: File = { path: "/a/c/file2.ts", content: `import {t} from "../b/file1"; var t3 = 11;` };
const configFile1: File = { path: "/a/b/tsconfig.json", content: `{ "compileOnSave": true }` };
const configFile2: File = { path: "/a/c/tsconfig.json", content: `{ "compileOnSave": true }` };
const host = createServerHost([file1, file2, file3, configFile1, configFile2]);
const session = createSession(host);
@@ -469,7 +469,7 @@ namespace ts.projectSystem {
});
it("should detect removed code file", () => {
const referenceFile1: FileOrFolder = {
const referenceFile1: File = {
path: "/a/b/referenceFile1.ts",
content: `
/// <reference path="./moduleFile1.ts" />
@@ -490,7 +490,7 @@ namespace ts.projectSystem {
});
it("should detect non-existing code file", () => {
const referenceFile1: FileOrFolder = {
const referenceFile1: File = {
path: "/a/b/referenceFile1.ts",
content: `
/// <reference path="./moduleFile2.ts" />
@@ -14,7 +14,7 @@ namespace ts {
const { options: actualCompilerOptions, errors: actualErrors} = convertCompilerOptionsFromJson(json.compilerOptions, "/apath/", configFileName);
const parsedCompilerOptions = JSON.stringify(actualCompilerOptions);
const expectedCompilerOptions = JSON.stringify(expectedResult.compilerOptions);
const expectedCompilerOptions = JSON.stringify({ ...expectedResult.compilerOptions, configFilePath: configFileName });
assert.equal(parsedCompilerOptions, expectedCompilerOptions);
const expectedErrors = expectedResult.errors;
+4 -4
View File
@@ -446,11 +446,11 @@ import { React, Other } from "react";
},
reactLibFile);
function testOrganizeImports(testName: string, testFile: TestFSWithWatch.FileOrFolder, ...otherFiles: TestFSWithWatch.FileOrFolder[]) {
function testOrganizeImports(testName: string, testFile: TestFSWithWatch.File, ...otherFiles: TestFSWithWatch.File[]) {
it(testName, () => runBaseline(`organizeImports/${testName}.ts`, testFile, ...otherFiles));
}
function runBaseline(baselinePath: string, testFile: TestFSWithWatch.FileOrFolder, ...otherFiles: TestFSWithWatch.FileOrFolder[]) {
function runBaseline(baselinePath: string, testFile: TestFSWithWatch.File, ...otherFiles: TestFSWithWatch.File[]) {
const { path: testPath, content: testContent } = testFile;
const languageService = makeLanguageService(testFile, ...otherFiles);
const changes = languageService.organizeImports({ type: "file", fileName: testPath }, testFormatOptions, defaultPreferences);
@@ -468,7 +468,7 @@ import { React, Other } from "react";
});
}
function makeLanguageService(...files: TestFSWithWatch.FileOrFolder[]) {
function makeLanguageService(...files: TestFSWithWatch.File[]) {
const host = projectSystem.createServerHost(files);
const projectService = projectSystem.createProjectService(host, { useSingleInferredProject: true });
projectService.setCompilerOptionsForInferredProjects({ jsx: files.some(f => f.path.endsWith("x")) ? JsxEmit.React : JsxEmit.None });
@@ -555,4 +555,4 @@ import { React, Other } from "react";
}
}
});
}
}
+291
View File
@@ -0,0 +1,291 @@
/// <reference path="../harness.ts" />
/// <reference path="../../compiler/commandLineParser.ts" />
namespace ts {
interface TestProjectSpecification {
configFileName?: string;
references?: ReadonlyArray<string | ProjectReference>;
files: { [fileName: string]: string };
outputFiles?: { [fileName: string]: string };
config?: object;
options?: Partial<CompilerOptions>;
}
interface TestSpecification {
[path: string]: TestProjectSpecification;
}
function assertHasError(message: string, errors: ReadonlyArray<Diagnostic>, diag: DiagnosticMessage) {
if (!errors.some(e => e.code === diag.code)) {
const errorString = errors.map(e => ` ${e.file ? e.file.fileName : "[global]"}: ${e.messageText}`).join("\r\n");
assert(false, `${message}: Did not find any diagnostic for ${diag.message} in:\r\n${errorString}`);
}
}
function assertNoErrors(message: string, errors: ReadonlyArray<Diagnostic>) {
if (errors && errors.length > 0) {
assert(false, `${message}: Expected no errors, but found:\r\n${errors.map(e => ` ${e.messageText}`).join("\r\n")}`);
}
}
function combineAllPaths(...paths: string[]) {
let result = paths[0];
for (let i = 1; i < paths.length; i++) {
result = combinePaths(result, paths[i]);
}
return result;
}
const emptyModule = "export { };";
/**
* Produces the text of a source file which imports all of the
* specified module names
*/
function moduleImporting(...names: string[]) {
return names.map((n, i) => `import * as mod_${i} from ${n}`).join("\r\n");
}
function testProjectReferences(spec: TestSpecification, entryPointConfigFileName: string, checkResult: (prog: Program, host: fakes.CompilerHost) => void) {
const files = createMap<string>();
for (const key in spec) {
const sp = spec[key];
const configFileName = combineAllPaths("/", key, sp.configFileName || "tsconfig.json");
const options = {
compilerOptions: {
composite: true,
outDir: "bin",
...sp.options
},
references: (sp.references || []).map(r => {
if (typeof r === "string") {
return { path: r };
}
return r;
}),
...sp.config
};
const configContent = JSON.stringify(options);
const outDir = options.compilerOptions.outDir;
files.set(configFileName, configContent);
for (const sourceFile of Object.keys(sp.files)) {
files.set(sourceFile, sp.files[sourceFile]);
}
if (sp.outputFiles) {
for (const outFile of Object.keys(sp.outputFiles)) {
files.set(combineAllPaths("/", key, outDir, outFile), sp.outputFiles[outFile]);
}
}
}
const vfsys = new vfs.FileSystem(false, { files: { "/lib.d.ts": TestFSWithWatch.libFile.content! } });
files.forEach((v, k) => {
vfsys.mkdirpSync(getDirectoryPath(k));
vfsys.writeFileSync(k, v);
});
const host = new fakes.CompilerHost(new fakes.System(vfsys));
const { config, error } = readConfigFile(entryPointConfigFileName, name => host.readFile(name));
// We shouldn't have any errors about invalid tsconfig files in these tests
assert(config && !error, flattenDiagnosticMessageText(error && error.messageText, "\n"));
const file = parseJsonConfigFileContent(config, parseConfigHostFromCompilerHost(host), getDirectoryPath(entryPointConfigFileName), {}, entryPointConfigFileName);
file.options.configFilePath = entryPointConfigFileName;
const prog = createProgram({
rootNames: file.fileNames,
options: file.options,
host,
projectReferences: file.projectReferences
});
checkResult(prog, host);
}
describe("project-references meta check", () => {
it("default setup was created correctly", () => {
const spec: TestSpecification = {
"/primary": {
files: { "/primary/a.ts": emptyModule },
references: []
},
"/reference": {
files: { "/secondary/b.ts": moduleImporting("../primary/a") },
references: ["../primary"]
}
};
testProjectReferences(spec, "/primary/tsconfig.json", prog => {
assert.isTrue(!!prog, "Program should exist");
assertNoErrors("Sanity check should not produce errors", prog.getOptionsDiagnostics());
});
});
});
/**
* Validate that we enforce the basic settings constraints for referenced projects
*/
describe("project-references constraint checking for settings", () => {
it("errors when declaration = false", () => {
const spec: TestSpecification = {
"/primary": {
files: { "/primary/a.ts": emptyModule },
references: [],
options: {
declaration: false
}
}
};
testProjectReferences(spec, "/primary/tsconfig.json", program => {
const errs = program.getOptionsDiagnostics();
assertHasError("Reports an error about the wrong decl setting", errs, Diagnostics.Composite_projects_may_not_disable_declaration_emit);
});
});
it("errors when the referenced project doesn't have composite:true", () => {
const spec: TestSpecification = {
"/primary": {
files: { "/primary/a.ts": emptyModule },
references: [],
options: {
composite: false
}
},
"/reference": {
files: { "/secondary/b.ts": moduleImporting("../primary/a") },
references: ["../primary"]
}
};
testProjectReferences(spec, "/reference/tsconfig.json", program => {
const errs = program.getOptionsDiagnostics();
assertHasError("Reports an error about 'composite' not being set", errs, Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true);
});
});
it("errors when the file list is not exhaustive", () => {
const spec: TestSpecification = {
"/primary": {
files: {
"/primary/a.ts": "import * as b from './b'",
"/primary/b.ts": "export {}"
},
config: {
files: ["a.ts"]
}
}
};
testProjectReferences(spec, "/primary/tsconfig.json", program => {
const errs = program.getOptionsDiagnostics();
assertHasError("Reports an error about b.ts not being in the list", errs, Diagnostics.File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern);
});
});
it("errors when the referenced project doesn't exist", () => {
const spec: TestSpecification = {
"/primary": {
files: { "/primary/a.ts": emptyModule },
references: ["../foo"]
}
};
testProjectReferences(spec, "/primary/tsconfig.json", program => {
const errs = program.getOptionsDiagnostics();
assertHasError("Reports an error about a missing file", errs, Diagnostics.File_0_does_not_exist);
});
});
it("errors when a prepended project reference doesn't set outFile", () => {
const spec: TestSpecification = {
"/primary": {
files: { "/primary/a.ts": emptyModule },
references: [{ path: "../someProj", prepend: true }]
},
"/someProj": {
files: { "/someProj/b.ts": "const x = 100;" }
}
};
testProjectReferences(spec, "/primary/tsconfig.json", program => {
const errs = program.getOptionsDiagnostics();
assertHasError("Reports an error about outFile not being set", errs, Diagnostics.Cannot_prepend_project_0_because_it_does_not_have_outFile_set);
});
});
it("errors when a prepended project reference output doesn't exist", () => {
const spec: TestSpecification = {
"/primary": {
files: { "/primary/a.ts": "const y = x;" },
references: [{ path: "../someProj", prepend: true }]
},
"/someProj": {
files: { "/someProj/b.ts": "const x = 100;" },
options: { outFile: "foo.js" }
}
};
testProjectReferences(spec, "/primary/tsconfig.json", program => {
const errs = program.getOptionsDiagnostics();
assertHasError("Reports an error about outFile being missing", errs, Diagnostics.Output_file_0_from_project_1_does_not_exist);
});
});
});
/**
* Path mapping behavior
*/
describe("project-references path mapping", () => {
it("redirects to the output .d.ts file", () => {
const spec: TestSpecification = {
"/alpha": {
files: { "/alpha/a.ts": "export const m: number = 3;" },
references: [],
outputFiles: { "a.d.ts": emptyModule }
},
"/beta": {
files: { "/beta/b.ts": "import { m } from '../alpha/a'" },
references: ["../alpha"]
}
};
testProjectReferences(spec, "/beta/tsconfig.json", program => {
assertNoErrors("File setup should be correct", program.getOptionsDiagnostics());
assertHasError("Found a type error", program.getSemanticDiagnostics(), Diagnostics.Module_0_has_no_exported_member_1);
});
});
});
describe("project-references nice-behavior", () => {
it("issues a nice error when the input file is missing", () => {
const spec: TestSpecification = {
"/alpha": {
files: { "/alpha/a.ts": "export const m: number = 3;" },
references: []
},
"/beta": {
files: { "/beta/b.ts": "import { m } from '../alpha/a'" },
references: ["../alpha"]
}
};
testProjectReferences(spec, "/beta/tsconfig.json", program => {
assertHasError("Issues a useful error", program.getSemanticDiagnostics(), Diagnostics.Output_file_0_has_not_been_built_from_source_file_1);
});
});
});
/**
* 'composite' behavior
*/
describe("project-references behavior changes under composite: true", () => {
it("doesn't infer the rootDir from source paths", () => {
const spec: TestSpecification = {
"/alpha": {
files: { "/alpha/src/a.ts": "export const m: number = 3;" },
options: {
declaration: true,
outDir: "bin"
},
references: []
}
};
testProjectReferences(spec, "/alpha/tsconfig.json", (program, host) => {
program.emit();
assert.deepEqual(host.outputs.map(e => e.file).sort(), ["/alpha/bin/src/a.d.ts", "/alpha/bin/src/a.js"]);
});
});
});
}
+19 -19
View File
@@ -884,7 +884,7 @@ namespace ts {
});
});
type FileOrFolder = TestFSWithWatch.FileOrFolder;
type File = TestFSWithWatch.File;
import createTestSystem = TestFSWithWatch.createWatchedSystem;
import libFile = TestFSWithWatch.libFile;
@@ -920,22 +920,22 @@ namespace ts {
verifyProgramIsUptoDate(program, fileNames, options);
}
function verifyProgram(files: FileOrFolder[], rootFiles: string[], options: CompilerOptions, configFile: string) {
function verifyProgram(files: File[], rootFiles: string[], options: CompilerOptions, configFile: string) {
const system = createTestSystem(files);
verifyProgramWithoutConfigFile(system, rootFiles, options);
verifyProgramWithConfigFile(system, configFile);
}
it("has empty options", () => {
const file1: FileOrFolder = {
const file1: File = {
path: "/a/b/file1.ts",
content: "let x = 1"
};
const file2: FileOrFolder = {
const file2: File = {
path: "/a/b/file2.ts",
content: "let y = 1"
};
const configFile: FileOrFolder = {
const configFile: File = {
path: "/a/b/tsconfig.json",
content: "{}"
};
@@ -944,19 +944,19 @@ namespace ts {
it("has lib specified in the options", () => {
const compilerOptions: CompilerOptions = { lib: ["es5", "es2015.promise"] };
const app: FileOrFolder = {
const app: File = {
path: "/src/app.ts",
content: "var x: Promise<string>;"
};
const configFile: FileOrFolder = {
const configFile: File = {
path: "/src/tsconfig.json",
content: JSON.stringify({ compilerOptions })
};
const es5Lib: FileOrFolder = {
const es5Lib: File = {
path: "/compiler/lib.es5.d.ts",
content: "declare const eval: any"
};
const es2015Promise: FileOrFolder = {
const es2015Promise: File = {
path: "/compiler/lib.es2015.promise.d.ts",
content: "declare class Promise<T> {}"
};
@@ -975,26 +975,26 @@ namespace ts {
]
}
};
const app: FileOrFolder = {
const app: File = {
path: "/src/packages/framework/app.ts",
content: 'import classc from "module1/lib/file1";\
import classD from "module3/file3";\
let x = new classc();\
let y = new classD();'
};
const module1: FileOrFolder = {
const module1: File = {
path: "/src/packages/mail/data/module1/lib/file1.ts",
content: 'import classc from "module2/file2";export default classc;',
};
const module2: FileOrFolder = {
const module2: File = {
path: "/src/packages/mail/data/module1/lib/module2/file2.ts",
content: 'class classc { method2() { return "hello"; } }\nexport default classc',
};
const module3: FileOrFolder = {
const module3: File = {
path: "/src/packages/styles/module3/file3.ts",
content: "class classD { method() { return 10; } }\nexport default classD;"
};
const configFile: FileOrFolder = {
const configFile: File = {
path: "/src/tsconfig.json",
content: JSON.stringify({ compilerOptions })
};
@@ -1013,26 +1013,26 @@ namespace ts {
]
}
};
const app: FileOrFolder = {
const app: File = {
path: "/src/packages/framework/app.ts",
content: 'import classc from "module1/lib/file1";\
import classD from "module3/file3";\
let x = new classc();\
let y = new classD();'
};
const module1: FileOrFolder = {
const module1: File = {
path: "/src/packages/mail/data/module1/lib/file1.ts",
content: 'import classc from "module2/file2";export default classc;',
};
const module2: FileOrFolder = {
const module2: File = {
path: "/src/packages/mail/data/module1/lib/module2/file2.ts",
content: 'class classc { method2() { return "hello"; } }\nexport default classc',
};
const module3: FileOrFolder = {
const module3: File = {
path: "/src/packages/styles/module3/file3.ts",
content: "class classD { method() { return 10; } }\nexport default classD;"
};
const configFile: FileOrFolder = {
const configFile: File = {
path: "/src/tsconfig.json",
content: JSON.stringify({ compilerOptions, include: ["packages/**/*.ts"] })
};
+38 -3
View File
@@ -42,7 +42,7 @@ namespace ts.projectSystem {
const et = new TestServerEventManager([...files, notIncludedFile, tsconfig]);
et.service.openClientFile(files[0].path);
et.assertProjectInfoTelemetryEvent({
fileStats: { ts: 2, tsx: 1, js: 1, jsx: 1, dts: 1 },
fileStats: fileStats({ ts: 2, tsx: 1, js: 1, jsx: 1, dts: 1 }),
compilerOptions,
include: true,
});
@@ -234,9 +234,44 @@ namespace ts.projectSystem {
languageServiceEnabled: false,
});
});
describe("open files telemetry", () => {
it("sends event for inferred project", () => {
const ajs = makeFile("/a.js", "// @ts-check\nconst x = 0;");
const bjs = makeFile("/b.js");
const et = new TestServerEventManager([ajs, bjs]);
et.service.openClientFile(ajs.path);
et.assertOpenFileTelemetryEvent({ checkJs: true });
et.service.openClientFile(bjs.path);
et.assertOpenFileTelemetryEvent({ checkJs: false });
// No repeated send for opening a file seen before.
et.service.openClientFile(bjs.path);
et.assertNoOpenFilesTelemetryEvent();
});
it("not for '.ts' file", () => {
const ats = makeFile("/a.ts", "");
const et = new TestServerEventManager([ats]);
et.service.openClientFile(ats.path);
et.assertNoOpenFilesTelemetryEvent();
});
it("even for project with 'ts-check' in config", () => {
const file = makeFile("/a.js");
const compilerOptions: CompilerOptions = { checkJs: true };
const jsconfig = makeFile("/jsconfig.json", { compilerOptions });
const et = new TestServerEventManager([jsconfig, file]);
et.service.openClientFile(file.path);
et.assertOpenFileTelemetryEvent({ checkJs: false });
});
});
});
function makeFile(path: string, content: {} = ""): FileOrFolder {
return { path, content: isString(content) ? "" : JSON.stringify(content) };
function makeFile(path: string, content: {} = ""): File {
return { path, content: isString(content) ? content : JSON.stringify(content) };
}
}
+20
View File
@@ -250,6 +250,26 @@ namespace ts {
}
}
});
testBaseline("transformDeclarationFile", () => {
return baselineDeclarationTransform(`var oldName = undefined;`, {
transformers: {
afterDeclarations: [replaceIdentifiersNamedOldNameWithNewName]
},
compilerOptions: {
newLine: NewLineKind.CarriageReturnLineFeed,
declaration: true
}
});
});
function baselineDeclarationTransform(text: string, opts: TranspileOptions) {
const fs = vfs.createFromFileSystem(Harness.IO, /*caseSensitive*/ true, { documents: [new documents.TextDocument("/.src/index.ts", text)] });
const host = new fakes.CompilerHost(fs, opts.compilerOptions);
const program = createProgram(["/.src/index.ts"], opts.compilerOptions, host);
program.emit(program.getSourceFiles()[1], (p, s, bom) => host.writeFile(p, s, bom), /*cancellationToken*/ undefined, /*onlyDts*/ true, opts.transformers);
return fs.readFileSync("/.src/index.d.ts").toString();
}
});
}
+78 -77
View File
@@ -4,7 +4,8 @@
namespace ts.tscWatch {
import WatchedSystem = TestFSWithWatch.TestServerHost;
type FileOrFolder = TestFSWithWatch.FileOrFolder;
type File = TestFSWithWatch.File;
type SymLink = TestFSWithWatch.SymLink;
import createWatchedSystem = TestFSWithWatch.createWatchedSystem;
import checkArray = TestFSWithWatch.checkArray;
import libFile = TestFSWithWatch.libFile;
@@ -33,7 +34,7 @@ namespace ts.tscWatch {
return () => watch.getCurrentProgram().getProgram();
}
function getEmittedLineForMultiFileOutput(file: FileOrFolder, host: WatchedSystem) {
function getEmittedLineForMultiFileOutput(file: File, host: WatchedSystem) {
return `TSFILE: ${file.path.replace(".ts", ".js")}${host.newLine}`;
}
@@ -41,11 +42,11 @@ namespace ts.tscWatch {
return `TSFILE: ${filename}${host.newLine}`;
}
interface FileOrFolderEmit extends FileOrFolder {
interface FileOrFolderEmit extends File {
output?: string;
}
function getFileOrFolderEmit(file: FileOrFolder, getOutput?: (file: FileOrFolder) => string): FileOrFolderEmit {
function getFileOrFolderEmit(file: File, getOutput?: (file: File) => string): FileOrFolderEmit {
const result = file as FileOrFolderEmit;
if (getOutput) {
result.output = getOutput(file);
@@ -202,7 +203,7 @@ namespace ts.tscWatch {
return getDiagnosticOfFileFrom(file, text, start, length, message);
}
function getUnknownCompilerOption(program: Program, configFile: FileOrFolder, option: string) {
function getUnknownCompilerOption(program: Program, configFile: File, option: string) {
const quotedOption = `"${option}"`;
return getDiagnosticOfFile(program.getCompilerOptions().configFile, configFile.content.indexOf(quotedOption), quotedOption.length, Diagnostics.Unknown_compiler_option_0, option);
}
@@ -218,23 +219,23 @@ namespace ts.tscWatch {
text, start, length, message);
}
function getDiagnosticModuleNotFoundOfFile(program: Program, file: FileOrFolder, moduleName: string) {
function getDiagnosticModuleNotFoundOfFile(program: Program, file: File, moduleName: string) {
const quotedModuleName = `"${moduleName}"`;
return getDiagnosticOfFileFromProgram(program, file.path, file.content.indexOf(quotedModuleName), quotedModuleName.length, Diagnostics.Cannot_find_module_0, moduleName);
}
describe("tsc-watch program updates", () => {
const commonFile1: FileOrFolder = {
const commonFile1: File = {
path: "/a/b/commonFile1.ts",
content: "let x = 1"
};
const commonFile2: FileOrFolder = {
const commonFile2: File = {
path: "/a/b/commonFile2.ts",
content: "let y = 1"
};
it("create watch without config file", () => {
const appFile: FileOrFolder = {
const appFile: File = {
path: "/a/b/c/app.ts",
content: `
import {f} from "./module"
@@ -242,7 +243,7 @@ namespace ts.tscWatch {
`
};
const moduleFile: FileOrFolder = {
const moduleFile: File = {
path: "/a/b/c/module.d.ts",
content: `export let x: number`
};
@@ -277,7 +278,7 @@ namespace ts.tscWatch {
});
it("create configured project without file list", () => {
const configFile: FileOrFolder = {
const configFile: File = {
path: "/a/b/tsconfig.json",
content: `
{
@@ -287,15 +288,15 @@ namespace ts.tscWatch {
]
}`
};
const file1: FileOrFolder = {
const file1: File = {
path: "/a/b/c/f1.ts",
content: "let x = 1"
};
const file2: FileOrFolder = {
const file2: File = {
path: "/a/b/d/f2.ts",
content: "let y = 1"
};
const file3: FileOrFolder = {
const file3: File = {
path: "/a/b/e/f3.ts",
content: "let z = 1"
};
@@ -315,7 +316,7 @@ namespace ts.tscWatch {
// });
it("add new files to a configured program without file list", () => {
const configFile: FileOrFolder = {
const configFile: File = {
path: "/a/b/tsconfig.json",
content: `{}`
};
@@ -333,7 +334,7 @@ namespace ts.tscWatch {
});
it("should ignore non-existing files specified in the config file", () => {
const configFile: FileOrFolder = {
const configFile: File = {
path: "/a/b/tsconfig.json",
content: `{
"compilerOptions": {},
@@ -352,7 +353,7 @@ namespace ts.tscWatch {
});
it("handle recreated files correctly", () => {
const configFile: FileOrFolder = {
const configFile: File = {
path: "/a/b/tsconfig.json",
content: `{}`
};
@@ -373,7 +374,7 @@ namespace ts.tscWatch {
it("handles the missing files - that were added to program because they were added with ///<ref", () => {
const commonFile2Name = "commonFile2.ts";
const file1: FileOrFolder = {
const file1: File = {
path: "/a/b/commonFile1.ts",
content: `/// <reference path="${commonFile2Name}"/>
let x = y`
@@ -396,7 +397,7 @@ namespace ts.tscWatch {
});
it("should reflect change in config file", () => {
const configFile: FileOrFolder = {
const configFile: File = {
path: "/a/b/tsconfig.json",
content: `{
"compilerOptions": {},
@@ -419,7 +420,7 @@ namespace ts.tscWatch {
});
it("works correctly when config file is changed but its content havent", () => {
const configFile: FileOrFolder = {
const configFile: File = {
path: "/a/b/tsconfig.json",
content: `{
"compilerOptions": {},
@@ -441,14 +442,14 @@ namespace ts.tscWatch {
});
it("files explicitly excluded in config file", () => {
const configFile: FileOrFolder = {
const configFile: File = {
path: "/a/b/tsconfig.json",
content: `{
"compilerOptions": {},
"exclude": ["/a/c"]
}`
};
const excludedFile1: FileOrFolder = {
const excludedFile1: File = {
path: "/a/c/excluedFile1.ts",
content: `let t = 1;`
};
@@ -459,19 +460,19 @@ namespace ts.tscWatch {
});
it("should properly handle module resolution changes in config file", () => {
const file1: FileOrFolder = {
const file1: File = {
path: "/a/b/file1.ts",
content: `import { T } from "module1";`
};
const nodeModuleFile: FileOrFolder = {
const nodeModuleFile: File = {
path: "/a/b/node_modules/module1.ts",
content: `export interface T {}`
};
const classicModuleFile: FileOrFolder = {
const classicModuleFile: File = {
path: "/a/module1.ts",
content: `export interface T {}`
};
const configFile: FileOrFolder = {
const configFile: File = {
path: "/a/b/tsconfig.json",
content: `{
"compilerOptions": {
@@ -499,7 +500,7 @@ namespace ts.tscWatch {
});
it("should tolerate config file errors and still try to build a project", () => {
const configFile: FileOrFolder = {
const configFile: File = {
path: "/a/b/tsconfig.json",
content: `{
"compilerOptions": {
@@ -1117,15 +1118,15 @@ namespace ts.tscWatch {
it("should not trigger recompilation because of program emit", () => {
const proj = "/user/username/projects/myproject";
const file1: FileOrFolder = {
const file1: File = {
path: `${proj}/file1.ts`,
content: "export const c = 30;"
};
const file2: FileOrFolder = {
const file2: File = {
path: `${proj}/src/file2.ts`,
content: `import {c} from "file1"; export const d = 30;`
};
const tsconfig: FileOrFolder = {
const tsconfig: File = {
path: `${proj}/tsconfig.json`,
content: JSON.stringify({
compilerOptions: {
@@ -1153,7 +1154,7 @@ namespace ts.tscWatch {
one();
}
}`;
const file: FileOrFolder = {
const file: File = {
path: "/a/b/file.ts",
content: getFileContent(/*asModule*/ false)
};
@@ -1174,11 +1175,11 @@ namespace ts.tscWatch {
it("watched files when file is deleted and new file is added as part of change", () => {
const projectLocation = "/home/username/project";
const file: FileOrFolder = {
const file: File = {
path: `${projectLocation}/src/file1.ts`,
content: "var a = 10;"
};
const configFile: FileOrFolder = {
const configFile: File = {
path: `${projectLocation}/tsconfig.json`,
content: "{}"
};
@@ -1211,7 +1212,7 @@ namespace ts.tscWatch {
})
};
let getOutput: (file: FileOrFolder) => string;
let getOutput: (file: File) => string;
if (out) {
config.content = JSON.stringify({
compilerOptions: { listEmittedFiles: true, out }
@@ -1266,23 +1267,23 @@ namespace ts.tscWatch {
});
function verifyFilesEmittedOnce(useOutFile: boolean) {
const file1: FileOrFolder = {
const file1: File = {
path: "/a/b/output/AnotherDependency/file1.d.ts",
content: "declare namespace Common.SomeComponent.DynamicMenu { enum Z { Full = 0, Min = 1, Average = 2, } }"
};
const file2: FileOrFolder = {
const file2: File = {
path: "/a/b/dependencies/file2.d.ts",
content: "declare namespace Dependencies.SomeComponent { export class SomeClass { version: string; } }"
};
const file3: FileOrFolder = {
const file3: File = {
path: "/a/b/project/src/main.ts",
content: "namespace Main { export function fooBar() {} }"
};
const file4: FileOrFolder = {
const file4: File = {
path: "/a/b/project/src/main2.ts",
content: "namespace main.file4 { import DynamicMenu = Common.SomeComponent.DynamicMenu; export function foo(a: DynamicMenu.z) { } }"
};
const configFile: FileOrFolder = {
const configFile: File = {
path: "/a/b/project/tsconfig.json",
content: JSON.stringify({
compilerOptions: useOutFile ?
@@ -1334,16 +1335,16 @@ namespace ts.tscWatch {
/** list of the files that will be emitted for first compilation */
firstCompilationEmitFiles?: string[];
/** get the emit file for file - default is multi file emit line */
getEmitLine?(file: FileOrFolder, host: WatchedSystem): string;
getEmitLine?(file: File, host: WatchedSystem): string;
/** Additional files and folders to add */
getAdditionalFileOrFolder?(): FileOrFolder[];
getAdditionalFileOrFolder?(): File[];
/** initial list of files to emit if not the default list */
firstReloadFileList?: string[];
}
function getInitialState({ configObj = {}, firstCompilationEmitFiles, getEmitLine, getAdditionalFileOrFolder, firstReloadFileList }: InitialStateParams = {}) {
const host = createWatchedSystem([]);
const getOutputName = getEmitLine ? (file: FileOrFolder) => getEmitLine(file, host) :
(file: FileOrFolder) => getEmittedLineForMultiFileOutput(file, host);
const getOutputName = getEmitLine ? (file: File) => getEmitLine(file, host) :
(file: File) => getEmittedLineForMultiFileOutput(file, host);
const moduleFile1 = getFileOrFolderEmit({
path: moduleFile1Path,
@@ -1555,7 +1556,7 @@ namespace ts.tscWatch {
});
it("should return cascaded affected file list", () => {
const file1Consumer1Consumer1: FileOrFolder = {
const file1Consumer1Consumer1: File = {
path: "/a/b/file1Consumer1Consumer1.ts",
content: `import {y} from "./file1Consumer1";`
};
@@ -1582,13 +1583,13 @@ namespace ts.tscWatch {
it("should work fine for files with circular references", () => {
// TODO: do not exit on such errors? Just continue to watch the files for update in watch mode
const file1: FileOrFolder = {
const file1: File = {
path: "/a/b/file1.ts",
content: `
/// <reference path="./file2.ts" />
export var t1 = 10;`
};
const file2: FileOrFolder = {
const file2: File = {
path: "/a/b/file2.ts",
content: `
/// <reference path="./file1.ts" />
@@ -1611,7 +1612,7 @@ namespace ts.tscWatch {
});
it("should detect removed code file", () => {
const referenceFile1: FileOrFolder = {
const referenceFile1: File = {
path: "/a/b/referenceFile1.ts",
content: `
/// <reference path="./moduleFile1.ts" />
@@ -1632,7 +1633,7 @@ namespace ts.tscWatch {
});
it("should detect non-existing code file", () => {
const referenceFile1: FileOrFolder = {
const referenceFile1: File = {
path: "/a/b/referenceFile1.ts",
content: `
/// <reference path="./moduleFile2.ts" />
@@ -1659,7 +1660,7 @@ namespace ts.tscWatch {
});
describe("tsc-watch emit file content", () => {
interface EmittedFile extends FileOrFolder {
interface EmittedFile extends File {
shouldBeWritten: boolean;
}
function getEmittedFiles(files: FileOrFolderEmit[], contents: string[]): EmittedFile[] {
@@ -1684,8 +1685,8 @@ namespace ts.tscWatch {
}
}
function verifyEmittedFileContents(newLine: string, inputFiles: FileOrFolder[], initialEmittedFileContents: string[],
modifyFiles: (files: FileOrFolderEmit[], emitedFiles: EmittedFile[]) => FileOrFolderEmit[], configFile?: FileOrFolder) {
function verifyEmittedFileContents(newLine: string, inputFiles: File[], initialEmittedFileContents: string[],
modifyFiles: (files: FileOrFolderEmit[], emitedFiles: EmittedFile[]) => FileOrFolderEmit[], configFile?: File) {
const host = createWatchedSystem([], { newLine });
const files = concatenate(
map(inputFiles, file => getFileOrFolderEmit(file, fileToConvert => getEmittedLineForMultiFileOutput(fileToConvert, host))),
@@ -1778,15 +1779,15 @@ namespace ts.tscWatch {
it("Elides const enums correctly in incremental compilation", () => {
const currentDirectory = "/user/someone/projects/myproject";
const file1: FileOrFolder = {
const file1: File = {
path: `${currentDirectory}/file1.ts`,
content: "export const enum E1 { V = 1 }"
};
const file2: FileOrFolder = {
const file2: File = {
path: `${currentDirectory}/file2.ts`,
content: `import { E1 } from "./file1"; export const enum E2 { V = E1.V }`
};
const file3: FileOrFolder = {
const file3: File = {
path: `${currentDirectory}/file3.ts`,
content: `import { E2 } from "./file2"; const v: E2 = E2.V;`
};
@@ -1808,12 +1809,12 @@ namespace ts.tscWatch {
it("file is deleted and created as part of change", () => {
const projectLocation = "/home/username/project";
const file: FileOrFolder = {
const file: File = {
path: `${projectLocation}/app/file.ts`,
content: "var a = 10;"
};
const fileJs = `${projectLocation}/app/file.js`;
const configFile: FileOrFolder = {
const configFile: File = {
path: `${projectLocation}/tsconfig.json`,
content: JSON.stringify({
include: [
@@ -2101,19 +2102,19 @@ declare module "fs" {
it("works when reusing program with files from external library", () => {
interface ExpectedFile { path: string; isExpectedToEmit?: boolean; content?: string; }
const configDir = "/a/b/projects/myProject/src/";
const file1: FileOrFolder = {
const file1: File = {
path: configDir + "file1.ts",
content: 'import module1 = require("module1");\nmodule1("hello");'
};
const file2: FileOrFolder = {
const file2: File = {
path: configDir + "file2.ts",
content: 'import module11 = require("module1");\nmodule11("hello");'
};
const module1: FileOrFolder = {
const module1: File = {
path: "/a/b/projects/myProject/node_modules/module1/index.js",
content: "module.exports = options => { return options.toString(); }"
};
const configFile: FileOrFolder = {
const configFile: File = {
path: configDir + "tsconfig.json",
content: JSON.stringify({
compilerOptions: {
@@ -2169,7 +2170,7 @@ declare module "fs" {
};
}
function createExpectedEmittedFile(file: FileOrFolder): ExpectedFile {
function createExpectedEmittedFile(file: File): ExpectedFile {
return {
path: removeFileExtension(file.path.replace(configDir, outDirFolder)) + Extension.Js,
isExpectedToEmit: true,
@@ -2180,11 +2181,11 @@ declare module "fs" {
it("works when renaming node_modules folder that already contains @types folder", () => {
const currentDirectory = "/user/username/projects/myproject";
const file: FileOrFolder = {
const file: File = {
path: `${currentDirectory}/a.ts`,
content: `import * as q from "qqq";`
};
const module: FileOrFolder = {
const module: File = {
path: `${currentDirectory}/node_modules2/@types/qqq/index.d.ts`,
content: "export {}"
};
@@ -2203,7 +2204,7 @@ declare module "fs" {
describe("tsc-watch with when module emit is specified as node", () => {
it("when instead of filechanged recursive directory watcher is invoked", () => {
const configFile: FileOrFolder = {
const configFile: File = {
path: "/a/rootFolder/project/tsconfig.json",
content: JSON.stringify({
compilerOptions: {
@@ -2217,11 +2218,11 @@ declare module "fs" {
})
};
const outputFolder = "/a/rootFolder/project/Static/scripts/";
const file1: FileOrFolder = {
const file1: File = {
path: "/a/rootFolder/project/Scripts/TypeScript.ts",
content: "var z = 10;"
};
const file2: FileOrFolder = {
const file2: File = {
path: "/a/rootFolder/project/Scripts/Javascript.js",
content: "var zz = 10;"
};
@@ -2299,7 +2300,7 @@ declare module "fs" {
describe("tsc-watch with different polling/non polling options", () => {
it("watchFile using dynamic priority polling", () => {
const projectFolder = "/a/username/project";
const file1: FileOrFolder = {
const file1: File = {
path: `${projectFolder}/typescript.ts`,
content: "var z = 10;"
};
@@ -2362,11 +2363,11 @@ declare module "fs" {
function verifyRenamingFileInSubFolder(tscWatchDirectory: TestFSWithWatch.Tsc_WatchDirectory) {
const projectFolder = "/a/username/project";
const projectSrcFolder = `${projectFolder}/src`;
const configFile: FileOrFolder = {
const configFile: File = {
path: `${projectFolder}/tsconfig.json`,
content: "{}"
};
const file: FileOrFolder = {
const file: File = {
path: `${projectSrcFolder}/file1.ts`,
content: ""
};
@@ -2428,35 +2429,35 @@ declare module "fs" {
it("when there are symlinks to folders in recursive folders", () => {
const cwd = "/home/user/projects/myproject";
const file1: FileOrFolder = {
const file1: File = {
path: `${cwd}/src/file.ts`,
content: `import * as a from "a"`
};
const tsconfig: FileOrFolder = {
const tsconfig: File = {
path: `${cwd}/tsconfig.json`,
content: `{ "compilerOptions": { "extendedDiagnostics": true, "traceResolution": true }}`
};
const realA: FileOrFolder = {
const realA: File = {
path: `${cwd}/node_modules/reala/index.d.ts`,
content: `export {}`
};
const realB: FileOrFolder = {
const realB: File = {
path: `${cwd}/node_modules/realb/index.d.ts`,
content: `export {}`
};
const symLinkA: FileOrFolder = {
const symLinkA: SymLink = {
path: `${cwd}/node_modules/a`,
symLink: `${cwd}/node_modules/reala`
};
const symLinkB: FileOrFolder = {
const symLinkB: SymLink = {
path: `${cwd}/node_modules/b`,
symLink: `${cwd}/node_modules/realb`
};
const symLinkBInA: FileOrFolder = {
const symLinkBInA: SymLink = {
path: `${cwd}/node_modules/reala/node_modules/b`,
symLink: `${cwd}/node_modules/b`
};
const symLinkAInB: FileOrFolder = {
const symLinkAInB: SymLink = {
path: `${cwd}/node_modules/realb/node_modules/a`,
symLink: `${cwd}/node_modules/a`
};
File diff suppressed because it is too large Load Diff
+11 -11
View File
@@ -30,7 +30,7 @@ namespace ts.projectSystem {
}
}
function executeCommand(self: Installer, host: TestServerHost, installedTypings: string[] | string, typingFiles: FileOrFolder[], cb: TI.RequestCompletedAction): void {
function executeCommand(self: Installer, host: TestServerHost, installedTypings: string[] | string, typingFiles: File[], cb: TI.RequestCompletedAction): void {
self.addPostExecAction(installedTypings, success => {
for (const file of typingFiles) {
host.ensureFileOrFolder(file);
@@ -417,7 +417,7 @@ namespace ts.projectSystem {
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
const installedTypings: string[] = [];
const typingFiles: FileOrFolder[] = [];
const typingFiles: File[] = [];
executeCommand(this, host, installedTypings, typingFiles, cb);
}
})();
@@ -460,7 +460,7 @@ namespace ts.projectSystem {
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
const installedTypings: string[] = [];
const typingFiles: FileOrFolder[] = [];
const typingFiles: File[] = [];
executeCommand(this, host, installedTypings, typingFiles, cb);
}
})();
@@ -697,7 +697,7 @@ namespace ts.projectSystem {
super(host, { throttleLimit: 1, typesRegistry: createTypesRegistry("commander", "jquery", "lodash", "cordova", "gulp", "grunt") });
}
installWorker(_requestId: number, args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {
let typingFiles: (FileOrFolder & { typings: string })[] = [];
let typingFiles: (File & { typings: string })[] = [];
if (args.indexOf(typingsName("commander")) >= 0) {
typingFiles = [commander, jquery, lodash, cordova];
}
@@ -1193,7 +1193,7 @@ namespace ts.projectSystem {
}
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction) {
const installedTypings: string[] = [];
const typingFiles: FileOrFolder[] = [];
const typingFiles: File[] = [];
executeCommand(this, host, installedTypings, typingFiles, cb);
}
})();
@@ -1656,12 +1656,12 @@ namespace ts.projectSystem {
return foooResolution;
}
function verifyUnresolvedImportResolutions(appContents: string, typingNames: string[], typingFiles: FileOrFolder[]) {
const app: FileOrFolder = {
function verifyUnresolvedImportResolutions(appContents: string, typingNames: string[], typingFiles: File[]) {
const app: File = {
path: appPath,
content: `${appContents}import * as x from "fooo";`
};
const fooo: FileOrFolder = {
const fooo: File = {
path: foooPath,
content: `export var x: string;`
};
@@ -1697,15 +1697,15 @@ namespace ts.projectSystem {
});
it("correctly invalidate the resolutions with typing names that are trimmed", () => {
const fooAA: FileOrFolder = {
const fooAA: File = {
path: `${globalTypingsCacheLocation}/node_modules/foo/a/a.d.ts`,
content: "export function a (): void;"
};
const fooAB: FileOrFolder = {
const fooAB: File = {
path: `${globalTypingsCacheLocation}/node_modules/foo/a/b.d.ts`,
content: "export function b (): void;"
};
const fooAC: FileOrFolder = {
const fooAC: File = {
path: `${globalTypingsCacheLocation}/node_modules/foo/a/c.d.ts`,
content: "export function c (): void;"
};
-25
View File
@@ -2,31 +2,6 @@
* Common utilities
*/
namespace utils {
const leadingCommentRegExp = /^(\s*\/\*[^]*?\*\/\s*|\s*\/\/[^\r\n\u2028\u2029]*[\r\n\u2028\u2029]*)+/;
const trailingCommentRegExp = /(\s*\/\*[^]*?\*\/\s*|\s*\/\/[^\r\n\u2028\u2029]*[\r\n\u2028\u2029]*)+$/;
const leadingAndTrailingCommentRegExp = /^(\s*\/\*[^]*?\*\/\s*|\s*\/\/[^\r\n\u2028\u2029]*[\r\n\u2028\u2029]*)+|(\s*\/\*[^]*?\*\/\s*|\s*\/\/[^\r\n\u2028\u2029]*[\r\n\u2028\u2029]*)+$/g;
const allCommentRegExp = /(['"])(?:(?!\1).|\\[^])*\1|(\/\*[^]*?\*\/|\/\/[^\r\n\u2028\u2029]*[\r\n\u2028\u2029]*)/g;
export const enum CommentRemoval {
leading,
trailing,
leadingAndTrailing,
all
}
export function removeComments(text: string, removal: CommentRemoval) {
switch (removal) {
case CommentRemoval.leading:
return text.replace(leadingCommentRegExp, "");
case CommentRemoval.trailing:
return text.replace(trailingCommentRegExp, "");
case CommentRemoval.leadingAndTrailing:
return text.replace(leadingAndTrailingCommentRegExp, "");
case CommentRemoval.all:
return text.replace(allCommentRegExp, (match, quote) => quote ? match : "");
}
}
const testPathPrefixRegExp = /(?:(file:\/{3})|\/)\.(ts|lib|src)\//g;
export function removeTestPathPrefixes(text: string, retainTrailingDirectorySeparator?: boolean) {
return text !== undefined ? text.replace(testPathPrefixRegExp, (_, scheme) => scheme || (retainTrailingDirectorySeparator ? "/" : "")) : undefined;
+36 -31
View File
@@ -332,35 +332,20 @@ namespace vfs {
}
}
private _depth: string[] = [];
/**
* Make a directory and all of its parent paths (if they don't exist).
*/
public mkdirpSync(path: string) {
try {
this._depth.push(path);
path = this._resolve(path);
this.mkdirSync(path);
}
catch (e) {
if (e.code === "ENOENT") {
if (this._depth.length > 10) {
console.log(`path: ${path}`);
console.log(`dirname: ${vpath.dirname(path)}`);
console.log(this._depth);
throw e;
}
this.mkdirpSync(vpath.dirname(path));
this.mkdirSync(path);
path = this._resolve(path);
const result = this._walk(path, /*noFollow*/ true, (error, result) => {
if (error.code === "ENOENT") {
this._mkdir(result);
return "retry";
}
else if (e.code !== "EEXIST") {
throw e;
}
}
finally {
this._depth.pop();
}
return "throw";
});
if (!result.node) this._mkdir(result);
}
/**
@@ -464,9 +449,11 @@ namespace vfs {
public mkdirSync(path: string) {
if (this.isReadonly) throw createIOError("EROFS");
const { parent, links, node: existingNode, basename } = this._walk(this._resolve(path), /*noFollow*/ true);
if (existingNode) throw createIOError("EEXIST");
this._mkdir(this._walk(this._resolve(path), /*noFollow*/ true));
}
private _mkdir({ parent, links, node: existingNode, basename }: WalkResult) {
if (existingNode) throw createIOError("EEXIST");
const time = this.time();
const node = this._mknod(parent ? parent.dev : ++devCount, S_IFDIR, /*mode*/ 0o777, time);
this._addLink(parent, links, basename, node, time);
@@ -810,17 +797,18 @@ namespace vfs {
* @param path The path to follow.
* @param noFollow A value indicating whether to *not* dereference a symbolic link at the
* end of a path.
* @param allowPartial A value indicating whether to return a partial result if the node
* at the end of the path cannot be found.
*
* @link http://man7.org/linux/man-pages/man7/path_resolution.7.html
*/
private _walk(path: string, noFollow?: boolean): WalkResult {
private _walk(path: string, noFollow?: boolean, onError?: (error: NodeJS.ErrnoException, fragment: WalkResult) => "retry" | "throw"): WalkResult;
private _walk(path: string, noFollow?: boolean, onError?: (error: NodeJS.ErrnoException, fragment: WalkResult) => "stop" | "retry" | "throw"): WalkResult | undefined;
private _walk(path: string, noFollow?: boolean, onError?: (error: NodeJS.ErrnoException, fragment: WalkResult) => "stop" | "retry" | "throw"): WalkResult | undefined {
let links = this._getRootLinks();
let parent: DirectoryInode | undefined;
let components = vpath.parse(path);
let step = 0;
let depth = 0;
let retry = false;
while (true) {
if (depth >= 40) throw createIOError("ELOOP");
const lastStep = step === components.length - 1;
@@ -830,7 +818,8 @@ namespace vfs {
return { realpath: vpath.format(components), basename, parent, links, node };
}
if (node === undefined) {
throw createIOError("ENOENT");
if (trapError(createIOError("ENOENT"), node)) continue;
return undefined;
}
if (isSymlink(node)) {
const dirname = vpath.format(components.slice(0, step));
@@ -840,15 +829,30 @@ namespace vfs {
components = vpath.parse(symlink).concat(components.slice(step + 1));
step = 0;
depth++;
retry = false;
continue;
}
if (isDirectory(node)) {
links = this._getLinks(node);
parent = node;
step++;
retry = false;
continue;
}
throw createIOError("ENOTDIR");
if (trapError(createIOError("ENOTDIR"), node)) continue;
return undefined;
}
function trapError(error: NodeJS.ErrnoException, node?: Inode) {
const realpath = vpath.format(components.slice(0, step + 1));
const basename = components[step];
const result = !retry && onError ? onError(error, { realpath, basename, parent, links, node }) : "throw";
if (result === "stop") return false;
if (result === "retry") {
retry = true;
return true;
}
throw error;
}
}
@@ -1118,6 +1122,7 @@ namespace vfs {
export function createIOError(code: keyof typeof IOErrorMessages) {
const err: NodeJS.ErrnoException = new Error(`${code}: ${IOErrorMessages[code]}`);
err.code = code;
if (Error.captureStackTrace) Error.captureStackTrace(err, createIOError);
return err;
}
+116 -79
View File
@@ -1,7 +1,7 @@
/// <reference path="harness.ts" />
namespace ts.TestFSWithWatch {
export const libFile: FileOrFolder = {
export const libFile: File = {
path: "/a/lib/lib.d.ts",
content: `/// <reference no-default-lib="true"/>
interface Boolean {}
@@ -39,7 +39,7 @@ interface Array<T> {}`
environmentVariables?: Map<string>;
}
export function createWatchedSystem(fileOrFolderList: ReadonlyArray<FileOrFolder>, params?: TestServerHostCreationParameters): TestServerHost {
export function createWatchedSystem(fileOrFolderList: ReadonlyArray<FileOrFolderOrSymLink>, params?: TestServerHostCreationParameters): TestServerHost {
if (!params) {
params = {};
}
@@ -54,7 +54,7 @@ interface Array<T> {}`
return host;
}
export function createServerHost(fileOrFolderList: ReadonlyArray<FileOrFolder>, params?: TestServerHostCreationParameters): TestServerHost {
export function createServerHost(fileOrFolderList: ReadonlyArray<FileOrFolderOrSymLink>, params?: TestServerHostCreationParameters): TestServerHost {
if (!params) {
params = {};
}
@@ -69,42 +69,61 @@ interface Array<T> {}`
return host;
}
export interface FileOrFolder {
export interface File {
path: string;
content?: string;
content: string;
fileSize?: number;
symLink?: string;
}
interface FSEntry {
export interface Folder {
path: string;
}
export interface SymLink {
path: string;
symLink: string;
}
export type FileOrFolderOrSymLink = File | Folder | SymLink;
function isFile(fileOrFolderOrSymLink: FileOrFolderOrSymLink): fileOrFolderOrSymLink is File {
return isString((<File>fileOrFolderOrSymLink).content);
}
function isSymLink(fileOrFolderOrSymLink: FileOrFolderOrSymLink): fileOrFolderOrSymLink is SymLink {
return isString((<SymLink>fileOrFolderOrSymLink).symLink);
}
interface FSEntryBase {
path: Path;
fullPath: string;
modifiedTime: Date;
}
interface File extends FSEntry {
interface FsFile extends FSEntryBase {
content: string;
fileSize?: number;
}
interface Folder extends FSEntry {
interface FsFolder extends FSEntryBase {
entries: SortedArray<FSEntry>;
}
interface SymLink extends FSEntry {
interface FsSymLink extends FSEntryBase {
symLink: string;
}
function isFolder(s: FSEntry): s is Folder {
return s && isArray((<Folder>s).entries);
type FSEntry = FsFile | FsFolder | FsSymLink;
function isFsFolder(s: FSEntry): s is FsFolder {
return s && isArray((<FsFolder>s).entries);
}
function isFile(s: FSEntry): s is File {
return s && isString((<File>s).content);
function isFsFile(s: FSEntry): s is FsFile {
return s && isString((<FsFile>s).content);
}
function isSymLink(s: FSEntry): s is SymLink {
return s && isString((<SymLink>s).symLink);
function isFsSymLink(s: FSEntry): s is FsSymLink {
return s && isString((<FsSymLink>s).symLink);
}
function invokeWatcherCallbacks<T>(callbacks: T[], invokeCallback: (cb: T) => void): void {
@@ -306,12 +325,12 @@ interface Array<T> {}`
private readonly dynamicPriorityWatchFile: HostWatchFile;
private readonly customRecursiveWatchDirectory: HostWatchDirectory | undefined;
constructor(public withSafeList: boolean, public useCaseSensitiveFileNames: boolean, executingFilePath: string, currentDirectory: string, fileOrFolderList: ReadonlyArray<FileOrFolder>, public readonly newLine = "\n", public readonly useWindowsStylePath?: boolean, private readonly environmentVariables?: Map<string>) {
constructor(public withSafeList: boolean, public useCaseSensitiveFileNames: boolean, executingFilePath: string, currentDirectory: string, fileOrFolderorSymLinkList: ReadonlyArray<FileOrFolderOrSymLink>, public readonly newLine = "\n", public readonly useWindowsStylePath?: boolean, private readonly environmentVariables?: Map<string>) {
this.getCanonicalFileName = createGetCanonicalFileName(useCaseSensitiveFileNames);
this.toPath = s => toPath(s, currentDirectory, this.getCanonicalFileName);
this.executingFilePath = this.getHostSpecificPath(executingFilePath);
this.currentDirectory = this.getHostSpecificPath(currentDirectory);
this.reloadFS(fileOrFolderList);
this.reloadFS(fileOrFolderorSymLinkList);
this.dynamicPriorityWatchFile = this.environmentVariables && this.environmentVariables.get("TSC_WATCHFILE") === "DynamicPriorityPolling" ?
createDynamicPriorityPollingWatchFile(this) :
undefined;
@@ -373,12 +392,12 @@ interface Array<T> {}`
return new Date(this.time);
}
reloadFS(fileOrFolderList: ReadonlyArray<FileOrFolder>, options?: Partial<ReloadWatchInvokeOptions>) {
reloadFS(fileOrFolderOrSymLinkList: ReadonlyArray<FileOrFolderOrSymLink>, options?: Partial<ReloadWatchInvokeOptions>) {
const mapNewLeaves = createMap<true>();
const isNewFs = this.fs.size === 0;
fileOrFolderList = fileOrFolderList.concat(this.withSafeList ? safeList : []);
const filesOrFoldersToLoad: ReadonlyArray<FileOrFolder> = !this.useWindowsStylePath ? fileOrFolderList :
fileOrFolderList.map<FileOrFolder>(f => {
fileOrFolderOrSymLinkList = fileOrFolderOrSymLinkList.concat(this.withSafeList ? safeList : []);
const filesOrFoldersToLoad: ReadonlyArray<FileOrFolderOrSymLink> = !this.useWindowsStylePath ? fileOrFolderOrSymLinkList :
fileOrFolderOrSymLinkList.map<FileOrFolderOrSymLink>(f => {
const result = clone(f);
result.path = this.getHostSpecificPath(f.path);
return result;
@@ -389,8 +408,8 @@ interface Array<T> {}`
// If its a change
const currentEntry = this.fs.get(path);
if (currentEntry) {
if (isFile(currentEntry)) {
if (isString(fileOrDirectory.content)) {
if (isFsFile(currentEntry)) {
if (isFile(fileOrDirectory)) {
// Update file
if (currentEntry.content !== fileOrDirectory.content) {
this.modifyFile(fileOrDirectory.path, fileOrDirectory.content, options);
@@ -400,12 +419,12 @@ interface Array<T> {}`
// TODO: Changing from file => folder/Symlink
}
}
else if (isSymLink(currentEntry)) {
else if (isFsSymLink(currentEntry)) {
// TODO: update symlinks
}
else {
// Folder
if (isString(fileOrDirectory.content)) {
if (isFile(fileOrDirectory)) {
// TODO: Changing from folder => file
}
else {
@@ -424,7 +443,7 @@ interface Array<T> {}`
// If this entry is not from the new file or folder
if (!mapNewLeaves.get(path)) {
// Leaf entries that arent in new list => remove these
if (isFile(fileOrDirectory) || isSymLink(fileOrDirectory) || isFolder(fileOrDirectory) && fileOrDirectory.entries.length === 0) {
if (isFsFile(fileOrDirectory) || isFsSymLink(fileOrDirectory) || isFsFolder(fileOrDirectory) && fileOrDirectory.entries.length === 0) {
this.removeFileOrFolder(fileOrDirectory, folder => !mapNewLeaves.get(folder.path));
}
}
@@ -435,7 +454,7 @@ interface Array<T> {}`
modifyFile(filePath: string, content: string, options?: Partial<ReloadWatchInvokeOptions>) {
const path = this.toFullPath(filePath);
const currentEntry = this.fs.get(path);
if (!currentEntry || !isFile(currentEntry)) {
if (!currentEntry || !isFsFile(currentEntry)) {
throw new Error(`file not present: ${filePath}`);
}
@@ -459,7 +478,7 @@ interface Array<T> {}`
renameFolder(folderName: string, newFolderName: string) {
const fullPath = getNormalizedAbsolutePath(folderName, this.currentDirectory);
const path = this.toPath(fullPath);
const folder = this.fs.get(path) as Folder;
const folder = this.fs.get(path) as FsFolder;
Debug.assert(!!folder);
// Only remove the folder
@@ -467,19 +486,19 @@ interface Array<T> {}`
// Add updated folder with new folder name
const newFullPath = getNormalizedAbsolutePath(newFolderName, this.currentDirectory);
const newFolder = this.toFolder(newFullPath);
const newFolder = this.toFsFolder(newFullPath);
const newPath = newFolder.path;
const basePath = getDirectoryPath(path);
Debug.assert(basePath !== path);
Debug.assert(basePath === getDirectoryPath(newPath));
const baseFolder = this.fs.get(basePath) as Folder;
const baseFolder = this.fs.get(basePath) as FsFolder;
this.addFileOrFolderInFolder(baseFolder, newFolder);
// Invoke watches for files in the folder as deleted (from old path)
this.renameFolderEntries(folder, newFolder);
}
private renameFolderEntries(oldFolder: Folder, newFolder: Folder) {
private renameFolderEntries(oldFolder: FsFolder, newFolder: FsFolder) {
for (const entry of oldFolder.entries) {
this.fs.delete(entry.path);
this.invokeFileWatcher(entry.fullPath, FileWatcherEventKind.Deleted);
@@ -491,38 +510,38 @@ interface Array<T> {}`
}
this.fs.set(entry.path, entry);
this.invokeFileWatcher(entry.fullPath, FileWatcherEventKind.Created);
if (isFolder(entry)) {
if (isFsFolder(entry)) {
this.renameFolderEntries(entry, entry);
}
}
}
ensureFileOrFolder(fileOrDirectory: FileOrFolder, ignoreWatchInvokedWithTriggerAsFileCreate?: boolean) {
if (isString(fileOrDirectory.content)) {
const file = this.toFile(fileOrDirectory);
ensureFileOrFolder(fileOrDirectoryOrSymLink: FileOrFolderOrSymLink, ignoreWatchInvokedWithTriggerAsFileCreate?: boolean) {
if (isFile(fileOrDirectoryOrSymLink)) {
const file = this.toFsFile(fileOrDirectoryOrSymLink);
// file may already exist when updating existing type declaration file
if (!this.fs.get(file.path)) {
const baseFolder = this.ensureFolder(getDirectoryPath(file.fullPath));
this.addFileOrFolderInFolder(baseFolder, file, ignoreWatchInvokedWithTriggerAsFileCreate);
}
}
else if (isString(fileOrDirectory.symLink)) {
const symLink = this.toSymLink(fileOrDirectory);
else if (isSymLink(fileOrDirectoryOrSymLink)) {
const symLink = this.toFsSymLink(fileOrDirectoryOrSymLink);
Debug.assert(!this.fs.get(symLink.path));
const baseFolder = this.ensureFolder(getDirectoryPath(symLink.fullPath));
this.addFileOrFolderInFolder(baseFolder, symLink, ignoreWatchInvokedWithTriggerAsFileCreate);
}
else {
const fullPath = getNormalizedAbsolutePath(fileOrDirectory.path, this.currentDirectory);
const fullPath = getNormalizedAbsolutePath(fileOrDirectoryOrSymLink.path, this.currentDirectory);
this.ensureFolder(fullPath);
}
}
private ensureFolder(fullPath: string): Folder {
private ensureFolder(fullPath: string): FsFolder {
const path = this.toPath(fullPath);
let folder = this.fs.get(path) as Folder;
let folder = this.fs.get(path) as FsFolder;
if (!folder) {
folder = this.toFolder(fullPath);
folder = this.toFsFolder(fullPath);
const baseFullPath = getDirectoryPath(fullPath);
if (fullPath !== baseFullPath) {
// Add folder in the base folder
@@ -535,11 +554,11 @@ interface Array<T> {}`
this.fs.set(path, folder);
}
}
Debug.assert(isFolder(folder));
Debug.assert(isFsFolder(folder));
return folder;
}
private addFileOrFolderInFolder(folder: Folder, fileOrDirectory: File | Folder | SymLink, ignoreWatch?: boolean) {
private addFileOrFolderInFolder(folder: FsFolder, fileOrDirectory: FsFile | FsFolder | FsSymLink, ignoreWatch?: boolean) {
insertSorted(folder.entries, fileOrDirectory, (a, b) => compareStringsCaseSensitive(getBaseFileName(a.path), getBaseFileName(b.path)));
folder.modifiedTime = this.now();
this.fs.set(fileOrDirectory.path, fileOrDirectory);
@@ -551,9 +570,9 @@ interface Array<T> {}`
this.invokeDirectoryWatcher(folder.fullPath, fileOrDirectory.fullPath);
}
private removeFileOrFolder(fileOrDirectory: File | Folder | SymLink, isRemovableLeafFolder: (folder: Folder) => boolean, isRenaming?: boolean) {
private removeFileOrFolder(fileOrDirectory: FsFile | FsFolder | FsSymLink, isRemovableLeafFolder: (folder: FsFolder) => boolean, isRenaming?: boolean) {
const basePath = getDirectoryPath(fileOrDirectory.path);
const baseFolder = this.fs.get(basePath) as Folder;
const baseFolder = this.fs.get(basePath) as FsFolder;
if (basePath !== fileOrDirectory.path) {
Debug.assert(!!baseFolder);
baseFolder.modifiedTime = this.now();
@@ -562,7 +581,7 @@ interface Array<T> {}`
this.fs.delete(fileOrDirectory.path);
this.invokeFileWatcher(fileOrDirectory.fullPath, FileWatcherEventKind.Deleted);
if (isFolder(fileOrDirectory)) {
if (isFsFolder(fileOrDirectory)) {
Debug.assert(fileOrDirectory.entries.length === 0 || isRenaming);
const relativePath = this.getRelativePathToDirectory(fileOrDirectory.fullPath, fileOrDirectory.fullPath);
// Invoke directory and recursive directory watcher for the folder
@@ -582,6 +601,24 @@ interface Array<T> {}`
}
}
removeFolder(folderPath: string, recursive?: boolean) {
const path = this.toFullPath(folderPath);
const currentEntry = this.fs.get(path) as FsFolder;
Debug.assert(isFsFolder(currentEntry));
if (recursive && currentEntry.entries.length) {
const subEntries = currentEntry.entries.slice();
subEntries.forEach(fsEntry => {
if (isFsFolder(fsEntry)) {
this.removeFolder(fsEntry.fullPath, recursive);
}
else {
this.removeFileOrFolder(fsEntry, returnFalse);
}
});
}
this.removeFileOrFolder(currentEntry, returnFalse);
}
// For overriding the methods
invokeWatchedDirectoriesCallback(folderFullPath: string, relativePath: string) {
invokeWatcherCallbacks(this.watchedDirectories.get(this.toPath(folderFullPath)), cb => this.directoryCallback(cb, relativePath));
@@ -626,7 +663,7 @@ interface Array<T> {}`
}
}
private toFsEntry(path: string): FSEntry {
private toFsEntry(path: string): FSEntryBase {
const fullPath = getNormalizedAbsolutePath(path, this.currentDirectory);
return {
path: this.toPath(fullPath),
@@ -635,23 +672,23 @@ interface Array<T> {}`
};
}
private toFile(fileOrDirectory: FileOrFolder): File {
const file = this.toFsEntry(fileOrDirectory.path) as File;
file.content = fileOrDirectory.content;
file.fileSize = fileOrDirectory.fileSize;
return file;
private toFsFile(file: File): FsFile {
const fsFile = this.toFsEntry(file.path) as FsFile;
fsFile.content = file.content;
fsFile.fileSize = file.fileSize;
return fsFile;
}
private toSymLink(fileOrDirectory: FileOrFolder): SymLink {
const symLink = this.toFsEntry(fileOrDirectory.path) as SymLink;
symLink.symLink = getNormalizedAbsolutePath(fileOrDirectory.symLink, getDirectoryPath(symLink.fullPath));
return symLink;
private toFsSymLink(symLink: SymLink): FsSymLink {
const fsSymLink = this.toFsEntry(symLink.path) as FsSymLink;
fsSymLink.symLink = getNormalizedAbsolutePath(symLink.symLink, getDirectoryPath(fsSymLink.fullPath));
return fsSymLink;
}
private toFolder(path: string): Folder {
const folder = this.toFsEntry(path) as Folder;
folder.entries = [] as SortedArray<FSEntry>;
return folder;
private toFsFolder(path: string): FsFolder {
const fsFolder = this.toFsEntry(path) as FsFolder;
fsFolder.entries = [] as SortedArray<FSEntry>;
return fsFolder;
}
private getRealFsEntry<T extends FSEntry>(isFsEntry: (fsEntry: FSEntry) => fsEntry is T, path: Path, fsEntry = this.fs.get(path)): T | undefined {
@@ -659,7 +696,7 @@ interface Array<T> {}`
return fsEntry;
}
if (isSymLink(fsEntry)) {
if (isFsSymLink(fsEntry)) {
return this.getRealFsEntry(isFsEntry, this.toPath(fsEntry.symLink));
}
@@ -676,20 +713,20 @@ interface Array<T> {}`
return undefined;
}
private isFile(fsEntry: FSEntry) {
private isFsFile(fsEntry: FSEntry) {
return !!this.getRealFile(fsEntry.path, fsEntry);
}
private getRealFile(path: Path, fsEntry?: FSEntry): File | undefined {
return this.getRealFsEntry(isFile, path, fsEntry);
private getRealFile(path: Path, fsEntry?: FSEntry): FsFile | undefined {
return this.getRealFsEntry(isFsFile, path, fsEntry);
}
private isFolder(fsEntry: FSEntry) {
private isFsFolder(fsEntry: FSEntry) {
return !!this.getRealFolder(fsEntry.path, fsEntry);
}
private getRealFolder(path: Path, fsEntry = this.fs.get(path)): Folder | undefined {
return this.getRealFsEntry(isFolder, path, fsEntry);
private getRealFolder(path: Path, fsEntry = this.fs.get(path)): FsFolder | undefined {
return this.getRealFsEntry(isFsFolder, path, fsEntry);
}
fileExists(s: string) {
@@ -711,7 +748,7 @@ interface Array<T> {}`
getFileSize(s: string) {
const path = this.toFullPath(s);
const entry = this.fs.get(path);
if (isFile(entry)) {
if (isFsFile(entry)) {
return entry.fileSize ? entry.fileSize : entry.content.length;
}
return undefined;
@@ -726,7 +763,7 @@ interface Array<T> {}`
const path = this.toFullPath(s);
const folder = this.getRealFolder(path);
if (folder) {
return mapDefined(folder.entries, entry => this.isFolder(entry) ? getBaseFileName(entry.fullPath) : undefined);
return mapDefined(folder.entries, entry => this.isFsFolder(entry) ? getBaseFileName(entry.fullPath) : undefined);
}
Debug.fail(folder ? "getDirectories called on file" : "getDirectories called on missing folder");
return [];
@@ -739,10 +776,10 @@ interface Array<T> {}`
const folder = this.getRealFolder(this.toPath(dir));
if (folder) {
folder.entries.forEach((entry) => {
if (this.isFolder(entry)) {
if (this.isFsFolder(entry)) {
directories.push(getBaseFileName(entry.fullPath));
}
else if (this.isFile(entry)) {
else if (this.isFsFile(entry)) {
files.push(getBaseFileName(entry.fullPath));
}
else {
@@ -840,24 +877,24 @@ interface Array<T> {}`
}
createDirectory(directoryName: string): void {
const folder = this.toFolder(directoryName);
const folder = this.toFsFolder(directoryName);
// base folder has to be present
const base = getDirectoryPath(folder.path);
const baseFolder = this.fs.get(base) as Folder;
Debug.assert(isFolder(baseFolder));
const baseFolder = this.fs.get(base) as FsFolder;
Debug.assert(isFsFolder(baseFolder));
Debug.assert(!this.fs.get(folder.path));
this.addFileOrFolderInFolder(baseFolder, folder);
}
writeFile(path: string, content: string): void {
const file = this.toFile({ path, content });
const file = this.toFsFile({ path, content });
// base folder has to be present
const base = getDirectoryPath(file.path);
const folder = this.fs.get(base) as Folder;
Debug.assert(isFolder(folder));
const folder = this.fs.get(base) as FsFolder;
Debug.assert(isFsFolder(folder));
this.addFileOrFolderInFolder(folder, file);
}
@@ -885,7 +922,7 @@ interface Array<T> {}`
const dirFullPath = this.realpath(getDirectoryPath(fullPath));
const realFullPath = combinePaths(dirFullPath, getBaseFileName(fullPath));
const fsEntry = this.fs.get(this.toPath(realFullPath));
if (isSymLink(fsEntry)) {
if (isFsSymLink(fsEntry)) {
return this.realpath(fsEntry.symLink);
}
+4
View File
@@ -124,4 +124,8 @@ namespace vpath {
return isDeclaration(path)
&& basename(path).startsWith("lib.");
}
export function isTsConfigFile(path: string): boolean {
return path.indexOf("tsconfig") !== -1 && path.indexOf("json") !== -1;
}
}
+5
View File
@@ -201,6 +201,11 @@ declare var WScript: {
Sleep(intTime: number): void;
};
/**
* WSH is an alias for WScript under Windows Script Host
*/
declare var WSH: typeof WScript;
/**
* Represents an Automation SAFEARRAY
*/
@@ -2520,6 +2520,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_all_require_to_import_95048" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[将所有 "require" 转换为 "import"]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_all_to_default_imports_95035" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all to default imports]]></Val>
@@ -2547,6 +2556,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_require_to_import_95047" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[将 "require" 转换为 "import"]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_to_ES6_module_95017" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert to ES6 module]]></Val>
@@ -7428,6 +7446,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_option_1343" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA["import.meta" 元属性仅允许对 "target" 和 "module" 编译器选项使用 "ESNext"。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary_2527" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The inferred type of '{0}' references an inaccessible '{1}' type. A type annotation is necessary.]]></Val>
@@ -9366,6 +9393,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";require_call_may_be_converted_to_an_import_80005" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['require' call may be converted to an import.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[可将“要求”调用转换为导入。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0_6107" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['rootDirs' option is set, using it to resolve relative module name '{0}'.]]></Val>
@@ -2523,6 +2523,9 @@
<Item ItemId=";Convert_all_require_to_import_95048" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[將所有 'require' 轉換至 'import']]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -2556,6 +2559,9 @@
<Item ItemId=";Convert_require_to_import_95047" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[將 'require' 轉換至 'import']]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -4296,6 +4302,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Include_modules_imported_with_json_extension_6197" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Include modules imported with '.json' extension]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Index_signature_in_type_0_only_permits_reading_2542" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Index signature in type '{0}' only permits reading.]]></Val>
@@ -5592,6 +5604,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy_5070" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Options_Colon_6027" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Options:]]></Val>
@@ -7443,6 +7461,9 @@
<Item ItemId=";The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_option_1343" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[只有在為 'target' 及 'module' 編譯器選項使用 'ESNext' 時,才允許 'import.meta' 中繼屬性。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -9387,6 +9408,9 @@
<Item ItemId=";require_call_may_be_converted_to_an_import_80005" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['require' call may be converted to an import.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['require' 呼叫可能會轉換為匯入。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -2529,6 +2529,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_all_require_to_import_95048" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Převést všechna volání require na import]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_all_to_default_imports_95035" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all to default imports]]></Val>
@@ -2556,6 +2565,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_require_to_import_95047" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Převést require na import]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_to_ES6_module_95017" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert to ES6 module]]></Val>
@@ -4293,6 +4311,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Include_modules_imported_with_json_extension_6197" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Include modules imported with '.json' extension]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Index_signature_in_type_0_only_permits_reading_2542" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Index signature in type '{0}' only permits reading.]]></Val>
@@ -5589,6 +5613,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy_5070" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Options_Colon_6027" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Options:]]></Val>
@@ -7437,6 +7467,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_option_1343" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Metavlastnost import.meta je povolená, jenom když se pro možnosti kompilátoru target a module použije ESNext.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary_2527" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The inferred type of '{0}' references an inaccessible '{1}' type. A type annotation is necessary.]]></Val>
@@ -9375,6 +9414,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";require_call_may_be_converted_to_an_import_80005" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['require' call may be converted to an import.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Volání require se dá převést na import.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0_6107" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['rootDirs' option is set, using it to resolve relative module name '{0}'.]]></Val>
@@ -2520,6 +2520,9 @@
<Item ItemId=";Convert_all_require_to_import_95048" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Alle Aufrufe von "require" in "import" konvertieren]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -2553,6 +2556,9 @@
<Item ItemId=";Convert_require_to_import_95047" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA["require" in "import" konvertieren]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -4293,6 +4299,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Include_modules_imported_with_json_extension_6197" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Include modules imported with '.json' extension]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Index_signature_in_type_0_only_permits_reading_2542" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Index signature in type '{0}' only permits reading.]]></Val>
@@ -5589,6 +5601,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy_5070" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Options_Colon_6027" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Options:]]></Val>
@@ -7437,6 +7455,9 @@
<Item ItemId=";The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_option_1343" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Die Metaeigenschaft "import.meta" ist nur bei Verwendung von "ESNext" für die Compileroptionen "target" und "module" zulässig.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -9381,6 +9402,9 @@
<Item ItemId=";require_call_may_be_converted_to_an_import_80005" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['require' call may be converted to an import.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Der Aufruf von "require" kann in einen Aufruf von "import" konvertiert werden.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -2529,6 +2529,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_all_require_to_import_95048" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Convertir todas las repeticiones de "require" en "import"]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_all_to_default_imports_95035" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all to default imports]]></Val>
@@ -2556,6 +2565,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_require_to_import_95047" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Convertir "require" en "import"]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_to_ES6_module_95017" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert to ES6 module]]></Val>
@@ -4293,6 +4311,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Include_modules_imported_with_json_extension_6197" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Include modules imported with '.json' extension]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Index_signature_in_type_0_only_permits_reading_2542" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Index signature in type '{0}' only permits reading.]]></Val>
@@ -5589,6 +5613,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy_5070" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Options_Colon_6027" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Options:]]></Val>
@@ -7440,6 +7470,9 @@
<Item ItemId=";The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_option_1343" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[La propiedad Meta "import.meta" solo se admite si se usa "ESNext" para las opciones del compilador "target" y "module".]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -9381,6 +9414,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";require_call_may_be_converted_to_an_import_80005" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['require' call may be converted to an import.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[La llamada a "require" puede convertirse en una importación.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0_6107" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['rootDirs' option is set, using it to resolve relative module name '{0}'.]]></Val>
@@ -2529,6 +2529,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_all_require_to_import_95048" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Convertir tous les 'require' en 'import']]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_all_to_default_imports_95035" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all to default imports]]></Val>
@@ -2556,6 +2565,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_require_to_import_95047" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Convertir 'require' en 'import']]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_to_ES6_module_95017" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert to ES6 module]]></Val>
@@ -4293,6 +4311,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Include_modules_imported_with_json_extension_6197" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Include modules imported with '.json' extension]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Index_signature_in_type_0_only_permits_reading_2542" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Index signature in type '{0}' only permits reading.]]></Val>
@@ -5589,6 +5613,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy_5070" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Options_Colon_6027" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Options:]]></Val>
@@ -7440,6 +7470,9 @@
<Item ItemId=";The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_option_1343" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[La métapropriété 'import.meta' est uniquement autorisée avec 'ESNext' pour les options de compilateur 'target' et 'module'.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -9381,6 +9414,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";require_call_may_be_converted_to_an_import_80005" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['require' call may be converted to an import.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[L'appel de 'require' peut être converti en import.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0_6107" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['rootDirs' option is set, using it to resolve relative module name '{0}'.]]></Val>
@@ -2520,6 +2520,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_all_require_to_import_95048" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Convertire tutte le occorrenze di 'require' in 'import']]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_all_to_default_imports_95035" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all to default imports]]></Val>
@@ -2547,6 +2556,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_require_to_import_95047" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Convertire 'require' in 'import']]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_to_ES6_module_95017" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert to ES6 module]]></Val>
@@ -4284,6 +4302,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Include_modules_imported_with_json_extension_6197" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Include modules imported with '.json' extension]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Index_signature_in_type_0_only_permits_reading_2542" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Index signature in type '{0}' only permits reading.]]></Val>
@@ -5580,6 +5604,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy_5070" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Options_Colon_6027" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Options:]]></Val>
@@ -7428,6 +7458,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_option_1343" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[La metaproprietà 'import.meta' è consentita solo se si usa 'ESNext' per le opzioni 'target' e 'module' del compilatore.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary_2527" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The inferred type of '{0}' references an inaccessible '{1}' type. A type annotation is necessary.]]></Val>
@@ -9366,6 +9405,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";require_call_may_be_converted_to_an_import_80005" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['require' call may be converted to an import.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[La chiamata a 'require' può essere convertita in un'importazione.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0_6107" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['rootDirs' option is set, using it to resolve relative module name '{0}'.]]></Val>
@@ -2523,6 +2523,9 @@
<Item ItemId=";Convert_all_require_to_import_95048" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['require' をすべて 'import' に変換]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -2556,6 +2559,9 @@
<Item ItemId=";Convert_require_to_import_95047" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['require' を 'import' に変換]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -4296,6 +4302,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Include_modules_imported_with_json_extension_6197" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Include modules imported with '.json' extension]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Index_signature_in_type_0_only_permits_reading_2542" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Index signature in type '{0}' only permits reading.]]></Val>
@@ -5592,6 +5604,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy_5070" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Options_Colon_6027" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Options:]]></Val>
@@ -7443,6 +7461,9 @@
<Item ItemId=";The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_option_1343" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['Import.meta' メタ プロパティでは、'target' および 'module' コンパイラ オプションに対して 'ESNext' のみが許可されています。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -9387,6 +9408,9 @@
<Item ItemId=";require_call_may_be_converted_to_an_import_80005" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['require' call may be converted to an import.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['require' の呼び出しはインポートに変換される可能性があります。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -1107,6 +1107,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";All_destructured_elements_are_unused_6198" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[All destructured elements are unused.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";All_imports_in_import_declaration_are_unused_6192" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[All imports in import declaration are unused.]]></Val>
@@ -2043,6 +2049,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Cannot_prepend_project_0_because_it_does_not_have_outFile_set_6308" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Cannot prepend project '{0}' because it does not have 'outFile' set]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Cannot_re_export_a_type_when_the_isolatedModules_flag_is_provided_1205" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Cannot re-export a type when the '--isolatedModules' flag is provided.]]></Val>
@@ -2421,6 +2433,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Composite_projects_may_not_disable_declaration_emit_6304" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Composite projects may not disable declaration emit.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Computed_property_names_are_not_allowed_in_enums_1164" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Computed property names are not allowed in enums.]]></Val>
@@ -2523,6 +2541,9 @@
<Item ItemId=";Convert_all_require_to_import_95048" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[모든 'require'를 'import'로 변환]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -2556,6 +2577,9 @@
<Item ItemId=";Convert_require_to_import_95047" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['require'를 'import'로 변환]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -3138,6 +3162,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Enable_project_compilation_6302" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Enable project compilation]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Enable_strict_checking_of_function_types_6186" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Enable strict checking of function types.]]></Val>
@@ -3693,6 +3723,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";File_0_is_not_in_project_file_list_Projects_must_list_all_files_or_use_an_include_pattern_6307" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[File '{0}' is not in project file list. Projects must list all files or use an 'include' pattern.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";File_0_is_not_under_rootDir_1_rootDir_is_expected_to_contain_all_source_files_6059" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[File '{0}' is not under 'rootDir' '{1}'. 'rootDir' is expected to contain all source files.]]></Val>
@@ -4296,6 +4332,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Include_modules_imported_with_json_extension_6197" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Include modules imported with '.json' extension]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Index_signature_in_type_0_only_permits_reading_2542" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Index signature in type '{0}' only permits reading.]]></Val>
@@ -5592,6 +5634,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy_5070" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Options_Colon_6027" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Options:]]></Val>
@@ -5610,6 +5658,18 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Output_file_0_from_project_1_does_not_exist_6309" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Output file '{0}' from project '{1}' does not exist]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Output_file_0_has_not_been_built_from_source_file_1_6305" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Output file '{0}' has not been built from source file '{1}'.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Overload_signature_is_not_compatible_with_function_implementation_2394" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Overload signature is not compatible with function implementation.]]></Val>
@@ -6006,6 +6066,18 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Project_references_may_not_form_a_circular_graph_Cycle_detected_Colon_0_6202" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Project references may not form a circular graph. Cycle detected: {0}]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Projects_to_reference_6300" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Projects to reference]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Property_0_does_not_exist_on_const_enum_1_2479" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Property '{0}' does not exist on 'const' enum '{1}'.]]></Val>
@@ -6432,6 +6504,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Referenced_project_0_must_have_setting_composite_Colon_true_6306" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Referenced project '{0}' must have setting "composite": true.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Remove_declaration_for_Colon_0_90004" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Remove declaration for: '{0}']]></Val>
@@ -6444,6 +6522,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Remove_destructuring_90009" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Remove destructuring]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Remove_import_from_0_90005" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Remove import from '{0}']]></Val>
@@ -7443,6 +7527,9 @@
<Item ItemId=";The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_option_1343" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['import.meta' 메타 속성은 'target' 및 'module' 컴파일러 옵션에 'ESNext'를 사용해야만 허용됩니다.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -9387,6 +9474,9 @@
<Item ItemId=";require_call_may_be_converted_to_an_import_80005" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['require' call may be converted to an import.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['require' 호출이 가져오기로 변환될 수 있습니다.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -2510,6 +2510,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_all_require_to_import_95048" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Konwertuj wszystkie wywołania „require” na wywołania „import”]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_all_to_default_imports_95035" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all to default imports]]></Val>
@@ -2537,6 +2546,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_require_to_import_95047" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Konwertuj wywołanie „require” na wywołanie „import”]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_to_ES6_module_95017" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert to ES6 module]]></Val>
@@ -4274,6 +4292,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Include_modules_imported_with_json_extension_6197" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Include modules imported with '.json' extension]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Index_signature_in_type_0_only_permits_reading_2542" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Index signature in type '{0}' only permits reading.]]></Val>
@@ -5570,6 +5594,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy_5070" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Options_Colon_6027" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Options:]]></Val>
@@ -7415,6 +7445,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_option_1343" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Metawłaściwość „import.meta” jest dozwolona tylko w przypadku podania wartości „ESNext” dla opcji kompilatora „target” i „module”.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary_2527" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The inferred type of '{0}' references an inaccessible '{1}' type. A type annotation is necessary.]]></Val>
@@ -9353,6 +9392,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";require_call_may_be_converted_to_an_import_80005" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['require' call may be converted to an import.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Wywołanie „require” może zostać przekonwertowane na wywołanie import.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0_6107" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['rootDirs' option is set, using it to resolve relative module name '{0}'.]]></Val>
@@ -2510,6 +2510,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_all_require_to_import_95048" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Converter todos os 'require' em 'import']]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_all_to_default_imports_95035" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all to default imports]]></Val>
@@ -2537,6 +2546,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_require_to_import_95047" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Converter 'require' em 'import']]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_to_ES6_module_95017" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert to ES6 module]]></Val>
@@ -4274,6 +4292,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Include_modules_imported_with_json_extension_6197" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Include modules imported with '.json' extension]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Index_signature_in_type_0_only_permits_reading_2542" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Index signature in type '{0}' only permits reading.]]></Val>
@@ -5570,6 +5594,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy_5070" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Options_Colon_6027" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Options:]]></Val>
@@ -7418,6 +7448,9 @@
<Item ItemId=";The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_option_1343" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[A metapropriedade 'import.meta' é permitida apenas usando 'ESNext' para as opções de compilador 'target' e 'module'.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -9359,6 +9392,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";require_call_may_be_converted_to_an_import_80005" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['require' call may be converted to an import.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[A chamada 'require' pode ser convertida em uma importação.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0_6107" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['rootDirs' option is set, using it to resolve relative module name '{0}'.]]></Val>
@@ -2519,6 +2519,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_all_require_to_import_95048" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Преобразовать все "require" в "import"]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_all_to_default_imports_95035" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all to default imports]]></Val>
@@ -2546,6 +2555,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_require_to_import_95047" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Преобразовать "require" в "import"]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Convert_to_ES6_module_95017" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert to ES6 module]]></Val>
@@ -4283,6 +4301,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Include_modules_imported_with_json_extension_6197" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Include modules imported with '.json' extension]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Index_signature_in_type_0_only_permits_reading_2542" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Index signature in type '{0}' only permits reading.]]></Val>
@@ -5579,6 +5603,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy_5070" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Options_Colon_6027" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Options:]]></Val>
@@ -7427,6 +7457,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_option_1343" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Метасвойство "import.meta" разрешено только при использовании "ESNext" для параметров компилятора "target" и "module".]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";The_inferred_type_of_0_references_an_inaccessible_1_type_A_type_annotation_is_necessary_2527" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The inferred type of '{0}' references an inaccessible '{1}' type. A type annotation is necessary.]]></Val>
@@ -9365,6 +9404,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";require_call_may_be_converted_to_an_import_80005" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['require' call may be converted to an import.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Вызов "require" можно преобразовать в "import".]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";rootDirs_option_is_set_using_it_to_resolve_relative_module_name_0_6107" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['rootDirs' option is set, using it to resolve relative module name '{0}'.]]></Val>
@@ -2516,6 +2516,9 @@
<Item ItemId=";Convert_all_require_to_import_95048" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert all 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Tüm 'require' öğelerini 'import' olarak dönüştür]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -2549,6 +2552,9 @@
<Item ItemId=";Convert_require_to_import_95047" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Convert 'require' to 'import']]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['require' öğesini 'import' olarak dönüştür]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -4289,6 +4295,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Include_modules_imported_with_json_extension_6197" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Include modules imported with '.json' extension]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Index_signature_in_type_0_only_permits_reading_2542" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Index signature in type '{0}' only permits reading.]]></Val>
@@ -5585,6 +5597,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Option_resolveJsonModule_cannot_be_specified_without_node_module_resolution_strategy_5070" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Option '--resolveJsonModule' cannot be specified without 'node' module resolution strategy.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Options_Colon_6027" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Options:]]></Val>
@@ -7436,6 +7454,9 @@
<Item ItemId=";The_import_meta_meta_property_is_only_allowed_using_ESNext_for_the_target_and_module_compiler_option_1343" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[The 'import.meta' meta-property is only allowed using 'ESNext' for the 'target' and 'module' compiler options.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['import.meta' meta özelliğine yalnızca 'target' ve 'module' derleyici seçenekleri için 'ESNext' kullanıldığında izin verilir.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
@@ -9380,6 +9401,9 @@
<Item ItemId=";require_call_may_be_converted_to_an_import_80005" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA['require' call may be converted to an import.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['require' çağrısı bir import olarak dönüştürülebilir.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
+5
View File
@@ -139,6 +139,11 @@ namespace ts.server {
this.processRequest(CommandNames.Change, args);
}
toLineColumnOffset(fileName: string, position: number) {
const { line, offset } = this.positionToOneBasedLineOffset(fileName, position);
return { line, character: offset };
}
getQuickInfoAtPosition(fileName: string, position: number): QuickInfo {
const args = this.createFileLocationRequestArgs(fileName, position);
+40 -4
View File
@@ -6,6 +6,7 @@ namespace ts.server {
export const ConfigFileDiagEvent = "configFileDiag";
export const ProjectLanguageServiceStateEvent = "projectLanguageServiceState";
export const ProjectInfoTelemetryEvent = "projectInfo";
export const OpenFileInfoTelemetryEvent = "openFileInfo";
// tslint:enable variable-name
export interface ProjectsUpdatedInBackgroundEvent {
@@ -55,6 +56,20 @@ namespace ts.server {
readonly version: string;
}
/**
* Info that we may send about a file that was just opened.
* Info about a file will only be sent once per session, even if the file changes in ways that might affect the info.
* Currently this is only sent for '.js' files.
*/
export interface OpenFileInfoTelemetryEvent {
readonly eventName: typeof OpenFileInfoTelemetryEvent;
readonly data: OpenFileInfoTelemetryEventData;
}
export interface OpenFileInfoTelemetryEventData {
readonly info: OpenFileInfo;
}
export interface ProjectInfoTypeAcquisitionData {
readonly enable: boolean;
// Actual values of include/exclude entries are scrubbed.
@@ -70,7 +85,11 @@ namespace ts.server {
readonly dts: number;
}
export type ProjectServiceEvent = ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent;
export interface OpenFileInfo {
readonly checkJs: boolean;
}
export type ProjectServiceEvent = ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent | OpenFileInfoTelemetryEvent;
export type ProjectServiceEventHandler = (event: ProjectServiceEvent) => void;
@@ -325,6 +344,9 @@ namespace ts.server {
* Container of all known scripts
*/
private readonly filenameToScriptInfo = createMap<ScriptInfo>();
// Set of all '.js' files ever opened.
private readonly allJsFilesForOpenFileTelemetry = createMap<true>();
/**
* Map to the real path of the infos
*/
@@ -577,7 +599,8 @@ namespace ts.server {
return this.pendingProjectUpdates.has(project.getProjectName());
}
private sendProjectsUpdatedInBackgroundEvent() {
/* @internal */
sendProjectsUpdatedInBackgroundEvent() {
if (!this.eventHandler) {
return;
}
@@ -1330,7 +1353,8 @@ namespace ts.server {
configHasExcludeProperty: parsedCommandLine.raw.exclude !== undefined,
wildcardDirectories: createMapFromTemplate(parsedCommandLine.wildcardDirectories),
typeAcquisition: parsedCommandLine.typeAcquisition,
compileOnSave: parsedCommandLine.compileOnSave
compileOnSave: parsedCommandLine.compileOnSave,
projectReferences: parsedCommandLine.projectReferences
};
return { projectOptions, configFileErrors: errors, configFileSpecs: parsedCommandLine.configFileSpecs };
@@ -1463,7 +1487,8 @@ namespace ts.server {
projectOptions.compilerOptions,
lastFileExceededProgramSize,
projectOptions.compileOnSave === undefined ? false : projectOptions.compileOnSave,
cachedDirectoryStructureHost);
cachedDirectoryStructureHost,
projectOptions.projectReferences);
project.configFileSpecs = configFileSpecs;
// TODO: We probably should also watch the configFiles that are extended
@@ -1588,6 +1613,7 @@ namespace ts.server {
// Update the project
project.configFileSpecs = configFileSpecs;
project.setProjectErrors(configFileErrors);
project.updateReferences(projectOptions.projectReferences);
const lastFileExceededProgramSize = this.getFilenameForExceededTotalSizeLimitForNonTsFiles(project.canonicalConfigFilePath, projectOptions.compilerOptions, projectOptions.files, fileNamePropertyReader);
if (lastFileExceededProgramSize) {
project.disableLanguageService(lastFileExceededProgramSize);
@@ -2091,9 +2117,19 @@ namespace ts.server {
this.printProjects();
this.telemetryOnOpenFile(info);
return { configFileName, configFileErrors };
}
private telemetryOnOpenFile(scriptInfo: ScriptInfo): void {
if (!this.eventHandler || !scriptInfo.isJavaScript() || !addToSeen(this.allJsFilesForOpenFileTelemetry, scriptInfo.path)) {
return;
}
const info: OpenFileInfo = { checkJs: !!scriptInfo.getDefaultProject().getSourceFile(scriptInfo.path).checkJsDirective };
this.eventHandler({ eventName: OpenFileInfoTelemetryEvent, data: { info } });
}
/**
* Close file whose contents is managed by the client
* @param filename is absolute pathname
+24 -3
View File
@@ -6,9 +6,12 @@ namespace ts.server {
External
}
/* @internal */
export type Mutable<T> = { -readonly [K in keyof T]: T[K]; };
/* @internal */
export function countEachFileTypes(infos: ScriptInfo[]): FileStats {
const result = { js: 0, jsx: 0, ts: 0, tsx: 0, dts: 0 };
const result: Mutable<FileStats> = { js: 0, jsx: 0, ts: 0, tsx: 0, dts: 0 };
for (const info of infos) {
switch (info.scriptKind) {
case ScriptKind.JS:
@@ -164,7 +167,7 @@ namespace ts.server {
return hasOneOrMoreJsAndNoTsFiles(this);
}
public static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {} {
public static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {} | undefined {
const resolvedPath = normalizeSlashes(host.resolvePath(combinePaths(initialDir, "node_modules")));
log(`Loading ${moduleName} from ${initialDir} (resolved to ${resolvedPath})`);
const result = host.require(resolvedPath, moduleName);
@@ -265,6 +268,10 @@ namespace ts.server {
return this.projectStateVersion.toString();
}
getProjectReferences(): ReadonlyArray<ProjectReference> | undefined {
return undefined;
}
getScriptFileNames() {
if (!this.rootFiles) {
return ts.emptyArray;
@@ -1102,6 +1109,11 @@ namespace ts.server {
}
}
/** Starts a new check for diagnostics. Call this if some file has updated that would cause diagnostics to be changed. */
refreshDiagnostics() {
this.projectService.sendProjectsUpdatedInBackgroundEvent();
}
private enableProxy(pluginModuleFactory: PluginModuleFactory, configEntry: PluginImport) {
try {
if (typeof pluginModuleFactory !== "function") {
@@ -1283,7 +1295,8 @@ namespace ts.server {
compilerOptions: CompilerOptions,
lastFileExceededProgramSize: string | undefined,
public compileOnSaveEnabled: boolean,
cachedDirectoryStructureHost: CachedDirectoryStructureHost) {
cachedDirectoryStructureHost: CachedDirectoryStructureHost,
private projectReferences: ReadonlyArray<ProjectReference> | undefined) {
super(configFileName,
ProjectKind.Configured,
projectService,
@@ -1325,6 +1338,14 @@ namespace ts.server {
return asNormalizedPath(this.getProjectName());
}
getProjectReferences(): ReadonlyArray<ProjectReference> | undefined {
return this.projectReferences;
}
updateReferences(refs: ReadonlyArray<ProjectReference> | undefined) {
this.projectReferences = refs;
}
enablePlugins() {
const host = this.projectService.host;
const options = this.getCompilationSettings();
+4 -1
View File
@@ -1765,6 +1765,8 @@ namespace ts.server.protocol {
arguments: FormatOnKeyRequestArgs;
}
export type CompletionsTriggerCharacter = "." | '"' | "'" | "`" | "/" | "@" | "<";
/**
* Arguments for completions messages.
*/
@@ -1773,7 +1775,7 @@ namespace ts.server.protocol {
* Optional prefix to apply to possible completions.
*/
prefix?: string;
triggerCharacter?: string;
triggerCharacter?: CompletionsTriggerCharacter;
/**
* @deprecated Use UserPreferences.includeCompletionsForModuleExports
*/
@@ -2734,6 +2736,7 @@ namespace ts.server.protocol {
project?: string;
reactNamespace?: string;
removeComments?: boolean;
references?: ProjectReference[];
rootDir?: string;
rootDirs?: string[];
skipLibCheck?: boolean;
+5 -3
View File
@@ -699,12 +699,14 @@ namespace ts.server {
}
private toFileSpan(fileName: string, textSpan: TextSpan, project: Project): protocol.FileSpan {
const scriptInfo = project.getScriptInfo(fileName);
const ls = project.getLanguageService();
const start = ls.toLineColumnOffset(fileName, textSpan.start);
const end = ls.toLineColumnOffset(fileName, textSpanEnd(textSpan));
return {
file: fileName,
start: scriptInfo.positionToLineOffset(textSpan.start),
end: scriptInfo.positionToLineOffset(textSpanEnd(textSpan))
start: { line: start.line + 1, offset: start.character + 1 },
end: { line: end.line + 1, offset: end.character + 1 }
};
}
+1 -1
View File
@@ -11,7 +11,7 @@ namespace ts.server {
enqueueInstallTypingsRequest(p: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>): void;
attach(projectService: ProjectService): void;
onProjectClosed(p: Project): void;
readonly globalTypingsCacheLocation: string;
readonly globalTypingsCacheLocation: string | undefined;
}
export const nullTypingsInstaller: ITypingsInstaller = {
@@ -2,7 +2,8 @@
namespace ts.server.typingsInstaller {
const fs: {
appendFileSync(file: string, content: string): void
appendFileSync(file: string, content: string): void;
existsSync(path: string): boolean;
} = require("fs");
const path: {
@@ -32,11 +33,12 @@ namespace ts.server.typingsInstaller {
/** Used if `--npmLocation` is not passed. */
function getDefaultNPMLocation(processName: string) {
if (path.basename(processName).indexOf("node") === 0) {
return `"${path.join(path.dirname(process.argv[0]), "npm")}"`;
}
else {
return "npm";
const npmPath = `"${path.join(path.dirname(process.argv[0]), "npm")}"`;
if (fs.existsSync(npmPath)) {
return npmPath;
}
}
return "npm";
}
interface TypesRegistryFile {
+2
View File
@@ -128,6 +128,8 @@ namespace ts.server {
configHasFilesProperty: boolean;
configHasIncludeProperty: boolean;
configHasExcludeProperty: boolean;
projectReferences: ReadonlyArray<ProjectReference> | undefined;
/**
* these fields can be present in the project file
*/
+13 -33
View File
@@ -192,13 +192,17 @@ namespace ts.codefix {
changes.deleteNode(sourceFile, assignment.parent);
}
else {
let newNodes = isObjectLiteralExpression(right) ? tryChangeModuleExportsObject(right) : undefined;
let changedToDefaultExport = false;
if (!newNodes) {
([newNodes, changedToDefaultExport] = convertModuleExportsToExportDefault(right, checker));
const replacement = isObjectLiteralExpression(right) ? tryChangeModuleExportsObject(right)
: isRequireCall(right, /*checkArgumentIsStringLiteralLike*/ true) ? convertReExportAll(right.arguments[0], checker)
: undefined;
if (replacement) {
changes.replaceNodeWithNodes(sourceFile, assignment.parent, replacement[0]);
return replacement[1];
}
else {
changes.replaceRangeWithText(sourceFile, createTextRange(left.getStart(sourceFile), right.pos), "export default");
return true;
}
changes.replaceNodeWithNodes(sourceFile, assignment.parent, newNodes);
return changedToDefaultExport;
}
}
else if (isExportsOrModuleExportsOrAlias(sourceFile, left.expression)) {
@@ -212,8 +216,8 @@ namespace ts.codefix {
* Convert `module.exports = { ... }` to individual exports..
* We can't always do this if the module has interesting members -- then it will be a default export instead.
*/
function tryChangeModuleExportsObject(object: ObjectLiteralExpression): ReadonlyArray<Statement> | undefined {
return mapAllOrFail(object.properties, prop => {
function tryChangeModuleExportsObject(object: ObjectLiteralExpression): [ReadonlyArray<Statement>, ModuleExportsChanged] | undefined {
const statements = mapAllOrFail(object.properties, prop => {
switch (prop.kind) {
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
@@ -229,6 +233,7 @@ namespace ts.codefix {
Debug.assertNever(prop);
}
});
return statements && [statements, true];
}
function convertNamedExport(
@@ -256,31 +261,6 @@ namespace ts.codefix {
}
}
function convertModuleExportsToExportDefault(exported: Expression, checker: TypeChecker): [ReadonlyArray<Statement>, ModuleExportsChanged] {
const modifiers = [createToken(SyntaxKind.ExportKeyword), createToken(SyntaxKind.DefaultKeyword)];
switch (exported.kind) {
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction: {
// `module.exports = function f() {}` --> `export default function f() {}`
const fn = exported as FunctionExpression | ArrowFunction;
return [[functionExpressionToDeclaration(fn.name && fn.name.text, modifiers, fn)], true];
}
case SyntaxKind.ClassExpression: {
// `module.exports = class C {}` --> `export default class C {}`
const cls = exported as ClassExpression;
return [[classExpressionToDeclaration(cls.name && cls.name.text, modifiers, cls)], true];
}
case SyntaxKind.CallExpression:
if (isRequireCall(exported, /*checkArgumentIsStringLiteralLike*/ true)) {
return convertReExportAll(exported.arguments[0], checker);
}
// falls through
default:
// `module.exports = 0;` --> `export default 0;`
return [[createExportAssignment(/*decorators*/ undefined, /*modifiers*/ undefined, /*isExportEquals*/ false, exported)], true];
}
}
function convertReExportAll(reExported: StringLiteralLike, checker: TypeChecker): [ReadonlyArray<Statement>, ModuleExportsChanged] {
// `module.exports = require("x");` ==> `export * from "x"; export { default } from "x";`
const moduleSpecifier = reExported.text;
+43 -1
View File
@@ -8,6 +8,7 @@ namespace ts.codefix {
Diagnostics._0_is_declared_but_never_used.code,
Diagnostics.Property_0_is_declared_but_its_value_is_never_read.code,
Diagnostics.All_imports_in_import_declaration_are_unused.code,
Diagnostics.All_destructured_elements_are_unused.code,
];
registerCodeFix({
errorCodes,
@@ -18,6 +19,10 @@ namespace ts.codefix {
const changes = textChanges.ChangeTracker.with(context, t => t.deleteNode(sourceFile, importDecl));
return [createCodeFixAction(fixName, changes, [Diagnostics.Remove_import_from_0, showModuleSpecifier(importDecl)], fixIdDelete, Diagnostics.Delete_all_unused_declarations)];
}
const delDestructure = textChanges.ChangeTracker.with(context, t => tryDeleteFullDestructure(t, sourceFile, context.span.start));
if (delDestructure.length) {
return [createCodeFixAction(fixName, delDestructure, Diagnostics.Remove_destructuring, fixIdDelete, Diagnostics.Delete_all_unused_declarations)];
}
const token = getToken(sourceFile, textSpanEnd(context.span));
const result: CodeFixAction[] = [];
@@ -50,7 +55,9 @@ namespace ts.codefix {
changes.deleteNode(sourceFile, importDecl);
}
else {
tryDeleteDeclaration(changes, sourceFile, token);
if (!tryDeleteFullDestructure(changes, sourceFile, diag.start!)) {
tryDeleteDeclaration(changes, sourceFile, token);
}
}
break;
default:
@@ -65,6 +72,26 @@ namespace ts.codefix {
return startToken.kind === SyntaxKind.ImportKeyword ? tryCast(startToken.parent, isImportDeclaration) : undefined;
}
function tryDeleteFullDestructure(changes: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number): boolean {
const startToken = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false);
if (startToken.kind !== SyntaxKind.OpenBraceToken || !isObjectBindingPattern(startToken.parent)) return false;
const decl = startToken.parent.parent;
switch (decl.kind) {
case SyntaxKind.VariableDeclaration:
tryDeleteVariableDeclaration(changes, sourceFile, decl);
break;
case SyntaxKind.Parameter:
changes.deleteNodeInList(sourceFile, decl);
break;
case SyntaxKind.BindingElement:
changes.deleteNode(sourceFile, decl);
break;
default:
return Debug.assertNever(decl);
}
return true;
}
function getToken(sourceFile: SourceFile, pos: number): Node {
const token = findPrecedingToken(pos, sourceFile);
// this handles var ["computed"] = 12;
@@ -171,6 +198,21 @@ namespace ts.codefix {
}
break;
case SyntaxKind.BindingElement: {
const pattern = (parent as BindingElement).parent;
switch (pattern.kind) {
case SyntaxKind.ArrayBindingPattern:
changes.deleteNode(sourceFile, parent); // Don't delete ','
break;
case SyntaxKind.ObjectBindingPattern:
changes.deleteNodeInList(sourceFile, parent);
break;
default:
return Debug.assertNever(pattern);
}
break;
}
// handle case where 'import a = A;'
case SyntaxKind.ImportEqualsDeclaration:
const importEquals = getAncestor(identifier, SyntaxKind.ImportEqualsDeclaration);
+8 -4
View File
@@ -25,7 +25,7 @@ namespace ts.Completions {
const enum GlobalsSearch { Continue, Success, Fail }
export function getCompletionsAtPosition(host: LanguageServiceHost, program: Program, log: Log, sourceFile: SourceFile, position: number, preferences: UserPreferences, triggerCharacter: string | undefined): CompletionInfo | undefined {
export function getCompletionsAtPosition(host: LanguageServiceHost, program: Program, log: Log, sourceFile: SourceFile, position: number, preferences: UserPreferences, triggerCharacter: CompletionsTriggerCharacter | undefined): CompletionInfo | undefined {
const typeChecker = program.getTypeChecker();
const compilerOptions = program.getCompilerOptions();
if (isInReferenceComment(sourceFile, position)) {
@@ -81,7 +81,7 @@ namespace ts.Completions {
return { isGlobalCompletion: false, isMemberCompletion: true, isNewIdentifierLocation: completion.hasIndexSignature, entries };
}
case StringLiteralCompletionKind.Types: {
const entries = completion.types.map(type => ({ name: type.value, kindModifiers: ScriptElementKindModifier.none, kind: ScriptElementKind.typeElement, sortText: "0" }));
const entries = completion.types.map(type => ({ name: type.value, kindModifiers: ScriptElementKindModifier.none, kind: ScriptElementKind.string, sortText: "0" }));
return { isGlobalCompletion: false, isMemberCompletion: false, isNewIdentifierLocation: completion.isNewIdentifier, entries };
}
default:
@@ -2208,8 +2208,12 @@ namespace ts.Completions {
return !!type.getStringIndexType() || !!type.getNumberIndexType();
}
function isValidTrigger(sourceFile: SourceFile, triggerCharacter: string, contextToken: Node, position: number): boolean {
function isValidTrigger(sourceFile: SourceFile, triggerCharacter: CompletionsTriggerCharacter, contextToken: Node, position: number): boolean {
switch (triggerCharacter) {
case ".":
case "/":
case "@":
return true;
case '"':
case "'":
case "`":
@@ -2219,7 +2223,7 @@ namespace ts.Completions {
// Opening JSX tag
return contextToken.kind === SyntaxKind.LessThanToken && contextToken.parent.kind !== SyntaxKind.BinaryExpression;
default:
return Debug.fail(triggerCharacter);
return Debug.assertNever(triggerCharacter);
}
}
+33
View File
@@ -74,6 +74,10 @@ namespace ts.DocumentHighlights {
case SyntaxKind.GetKeyword:
case SyntaxKind.SetKeyword:
return getFromAllDeclarations(isAccessor, [SyntaxKind.GetKeyword, SyntaxKind.SetKeyword]);
case SyntaxKind.AwaitKeyword:
return useParent(node.parent, isAwaitExpression, getAsyncAndAwaitOccurrences);
case SyntaxKind.AsyncKeyword:
return highlightSpans(getAsyncAndAwaitOccurrences(node));
default:
return isModifierKind(node.kind) && (isDeclaration(node.parent) || isVariableStatement(node.parent))
? highlightSpans(getModifierOccurrences(node.kind, node.parent))
@@ -368,6 +372,35 @@ namespace ts.DocumentHighlights {
return keywords;
}
function getAsyncAndAwaitOccurrences(node: Node): Node[] | undefined {
const func = <FunctionLikeDeclaration>getContainingFunction(node);
if (!func) {
return undefined;
}
const keywords: Node[] = [];
if (func.modifiers) {
func.modifiers.forEach(modifier => {
pushKeywordIf(keywords, modifier, SyntaxKind.AsyncKeyword);
});
}
forEachChild(func, aggregate);
return keywords;
function aggregate(node: Node): void {
if (isAwaitExpression(node)) {
pushKeywordIf(keywords, node.getFirstToken(), SyntaxKind.AwaitKeyword);
}
// Do not cross function boundaries.
if (!isFunctionLike(node) && !isClassLike(node) && !isInterfaceDeclaration(node) && !isModuleDeclaration(node) && !isTypeAliasDeclaration(node) && !isTypeNode(node)) {
forEachChild(node, aggregate);
}
}
}
function getIfElseOccurrences(ifStatement: IfStatement, sourceFile: SourceFile): HighlightSpan[] {
const keywords = getIfElseKeywords(ifStatement, sourceFile);
const result: HighlightSpan[] = [];
+2 -1
View File
@@ -172,9 +172,10 @@ namespace ts {
const bucket = getBucketForCompilationSettings(key, /*createIfMissing*/ true);
let entry = bucket.get(path);
const scriptTarget = scriptKind === ScriptKind.JSON ? ScriptTarget.JSON : compilationSettings.target;
if (!entry) {
// Have never seen this file with these settings. Create a new source file for it.
const sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, compilationSettings.target, version, /*setNodeParents*/ false, scriptKind);
const sourceFile = createLanguageServiceSourceFile(fileName, scriptSnapshot, scriptTarget, version, /*setNodeParents*/ false, scriptKind);
entry = {
sourceFile,
+3 -2
View File
@@ -119,7 +119,7 @@ namespace ts.FindAllReferences {
const { node } = def;
const symbol = checker.getSymbolAtLocation(node);
const displayParts = symbol && SymbolDisplay.getSymbolDisplayPartsDocumentationAndSymbolKind(
checker, symbol, node.getSourceFile(), getContainerNode(node), node).displayParts;
checker, symbol, node.getSourceFile(), getContainerNode(node), node).displayParts || [textPart("this")];
return { node, name: "this", kind: ScriptElementKind.variableElement, displayParts };
}
case "string": {
@@ -272,6 +272,8 @@ namespace ts.FindAllReferences.Core {
case SyntaxKind.ImportDeclaration:
case SyntaxKind.ExportDeclaration:
return true;
case SyntaxKind.LiteralType:
return isImportTypeNode(node.parent.parent);
case SyntaxKind.CallExpression:
return isRequireCall(node.parent as CallExpression, /*checkArgumentIsStringLiteralLike*/ false) || isImportCall(node.parent as CallExpression);
default:
@@ -407,7 +409,6 @@ namespace ts.FindAllReferences.Core {
return firstDefined(symbol.declarations, decl => {
if (!decl.parent) {
// Assertions for GH#21814. We should be handling SourceFile symbols in `getReferencedSymbolsForModule` instead of getting here.
Debug.assert(decl.kind === SyntaxKind.SourceFile);
Debug.fail(`Unexpected symbol at ${Debug.showSyntaxKind(node)}: ${Debug.showSymbol(symbol)}`);
}
return isTypeLiteralNode(decl.parent) && isUnionTypeNode(decl.parent.parent)
+12 -8
View File
@@ -327,9 +327,10 @@ namespace ts.formatting {
export function getContainingList(node: Node, sourceFile: SourceFile): NodeArray<Node> {
if (node.parent) {
const { end } = node;
switch (node.parent.kind) {
case SyntaxKind.TypeReference:
return getListIfStartEndIsInListRange((<TypeReferenceNode>node.parent).typeArguments, node.getStart(sourceFile), node.getEnd());
return getListIfStartEndIsInListRange((<TypeReferenceNode>node.parent).typeArguments, node.getStart(sourceFile), end);
case SyntaxKind.ObjectLiteralExpression:
return (<ObjectLiteralExpression>node.parent).properties;
case SyntaxKind.ArrayLiteralExpression:
@@ -344,22 +345,25 @@ namespace ts.formatting {
case SyntaxKind.ConstructorType:
case SyntaxKind.ConstructSignature: {
const start = node.getStart(sourceFile);
return getListIfStartEndIsInListRange((<SignatureDeclaration>node.parent).typeParameters, start, node.getEnd()) ||
getListIfStartEndIsInListRange((<SignatureDeclaration>node.parent).parameters, start, node.getEnd());
return getListIfStartEndIsInListRange((<SignatureDeclaration>node.parent).typeParameters, start, end) ||
getListIfStartEndIsInListRange((<SignatureDeclaration>node.parent).parameters, start, end);
}
case SyntaxKind.ClassDeclaration:
return getListIfStartEndIsInListRange((<ClassDeclaration>node.parent).typeParameters, node.getStart(sourceFile), node.getEnd());
return getListIfStartEndIsInListRange((<ClassDeclaration>node.parent).typeParameters, node.getStart(sourceFile), end);
case SyntaxKind.NewExpression:
case SyntaxKind.CallExpression: {
const start = node.getStart(sourceFile);
return getListIfStartEndIsInListRange((<CallExpression>node.parent).typeArguments, start, node.getEnd()) ||
getListIfStartEndIsInListRange((<CallExpression>node.parent).arguments, start, node.getEnd());
return getListIfStartEndIsInListRange((<CallExpression>node.parent).typeArguments, start, end) ||
getListIfStartEndIsInListRange((<CallExpression>node.parent).arguments, start, end);
}
case SyntaxKind.VariableDeclarationList:
return getListIfStartEndIsInListRange((<VariableDeclarationList>node.parent).declarations, node.getStart(sourceFile), node.getEnd());
return getListIfStartEndIsInListRange((<VariableDeclarationList>node.parent).declarations, node.getStart(sourceFile), end);
case SyntaxKind.NamedImports:
case SyntaxKind.NamedExports:
return getListIfStartEndIsInListRange((<NamedImportsOrExports>node.parent).elements, node.getStart(sourceFile), node.getEnd());
return getListIfStartEndIsInListRange((<NamedImportsOrExports>node.parent).elements, node.getStart(sourceFile), end);
case SyntaxKind.ObjectBindingPattern:
case SyntaxKind.ArrayBindingPattern:
return getListIfStartEndIsInListRange((<ObjectBindingPattern | ArrayBindingPattern>node.parent).elements, node.getStart(sourceFile), end);
}
}
return undefined;
+1 -1
View File
@@ -45,7 +45,7 @@ namespace ts {
if (checker.getSymbolAtLocation(importStringLiteral)) continue;
const resolved = program.getResolvedModuleWithFailedLookupLocationsFromCache(importStringLiteral.text, sourceFile.fileName);
if (contains(resolved.failedLookupLocations, oldFilePath)) {
if (resolved && contains(resolved.failedLookupLocations, oldFilePath)) {
result.push({ sourceFile, toUpdate: importStringLiteral });
}
}
+26 -6
View File
@@ -9,7 +9,27 @@ namespace ts.OutliningElementsCollector {
function addNodeOutliningSpans(sourceFile: SourceFile, cancellationToken: CancellationToken, out: Push<OutliningSpan>): void {
let depthRemaining = 40;
sourceFile.forEachChild(function walk(n) {
let current = 0;
const statements = sourceFile.statements;
const n = statements.length;
while (current < n) {
while (current < n && !isAnyImportSyntax(statements[current])) {
visitNonImportNode(statements[current]);
current++;
}
if (current === n) break;
const firstImport = current;
while (current < n && isAnyImportSyntax(statements[current])) {
addOutliningForLeadingCommentsForNode(statements[current], sourceFile, cancellationToken, out);
current++;
}
const lastImport = current - 1;
if (lastImport !== firstImport) {
out.push(createOutliningSpanFromBounds(findChildOfKind(statements[firstImport], SyntaxKind.ImportKeyword, sourceFile)!.getStart(sourceFile), statements[lastImport].getEnd(), OutliningSpanKind.Imports));
}
}
function visitNonImportNode(n: Node) {
if (depthRemaining === 0) return;
cancellationToken.throwIfCancellationRequested();
@@ -23,17 +43,17 @@ namespace ts.OutliningElementsCollector {
depthRemaining--;
if (isIfStatement(n) && n.elseStatement && isIfStatement(n.elseStatement)) {
// Consider an 'else if' to be on the same depth as the 'if'.
walk(n.expression);
walk(n.thenStatement);
visitNonImportNode(n.expression);
visitNonImportNode(n.thenStatement);
depthRemaining++;
walk(n.elseStatement);
visitNonImportNode(n.elseStatement);
depthRemaining--;
}
else {
n.forEachChild(walk);
n.forEachChild(visitNonImportNode);
}
depthRemaining++;
});
}
}
function addRegionOutliningSpans(sourceFile: SourceFile, out: Push<OutliningSpan>): void {
+10 -3
View File
@@ -27,7 +27,7 @@ namespace ts.Completions.PathCompletions {
const scriptDirectory = getDirectoryPath(scriptPath);
if (isPathRelativeToScript(literalValue) || isRootedDiskPath(literalValue)) {
const extensions = getSupportedExtensions(compilerOptions);
const extensions = getSupportedExtensionsForModuleResolution(compilerOptions);
if (compilerOptions.rootDirs) {
return getCompletionEntriesForDirectoryFragmentWithRootDirs(
compilerOptions.rootDirs, literalValue, scriptDirectory, extensions, /*includeExtensions*/ false, compilerOptions, host, scriptPath);
@@ -42,6 +42,13 @@ namespace ts.Completions.PathCompletions {
}
}
function getSupportedExtensionsForModuleResolution(compilerOptions: CompilerOptions) {
const extensions = getSupportedExtensions(compilerOptions);
return compilerOptions.resolveJsonModule && getEmitModuleResolutionKind(compilerOptions) === ModuleResolutionKind.NodeJs ?
extensions.concat(Extension.Json) :
extensions;
}
/**
* Takes a script path and returns paths for all potential folders that could be merged with its
* containing folder via the "rootDirs" compiler option
@@ -122,7 +129,7 @@ namespace ts.Completions.PathCompletions {
continue;
}
const foundFileName = includeExtensions ? getBaseFileName(filePath) : removeFileExtension(getBaseFileName(filePath));
const foundFileName = includeExtensions || fileExtensionIs(filePath, Extension.Json) ? getBaseFileName(filePath) : removeFileExtension(getBaseFileName(filePath));
if (!foundFiles.has(foundFileName)) {
foundFiles.set(foundFileName, true);
@@ -162,7 +169,7 @@ namespace ts.Completions.PathCompletions {
const result: NameAndKind[] = [];
const fileExtensions = getSupportedExtensions(compilerOptions);
const fileExtensions = getSupportedExtensionsForModuleResolution(compilerOptions);
if (baseUrl) {
const projectDir = compilerOptions.project || host.getCurrentDirectory();
const absolute = isRootedDiskPath(baseUrl) ? baseUrl : combinePaths(projectDir, baseUrl);
+1 -1
View File
@@ -1,7 +1,7 @@
namespace ts {
export function preProcessFile(sourceText: string, readImportFiles = true, detectJavaScriptImports = false): PreProcessedFileInfo {
const pragmaContext: PragmaContext = {
languageVersion: ScriptTarget.ES5, // controls weather the token scanner considers unicode identifiers or not - shouldn't matter, since we're only using it for trivia
languageVersion: ScriptTarget.ES5, // controls whether the token scanner considers unicode identifiers or not - shouldn't matter, since we're only using it for trivia
pragmas: undefined,
checkJsDirective: undefined,
referencedFiles: [],
@@ -49,7 +49,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
: undefined;
const fieldModifiers = isInClassLike ? getModifiers(isJS, isStatic, SyntaxKind.PrivateKeyword) : undefined;
updateFieldDeclaration(changeTracker, file, declaration, fieldName, fieldModifiers, container);
updateFieldDeclaration(changeTracker, file, declaration, fieldName, fieldModifiers);
const getAccessor = generateGetAccessor(fieldName, accessorName, type, accessorModifiers, isStatic, container);
const setAccessor = generateSetAccessor(fieldName, accessorName, type, accessorModifiers, isStatic, container);
@@ -60,7 +60,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
const edits = changeTracker.getChanges();
const renameFilename = file.fileName;
const renameLocationOffset = isIdentifier(fieldName) ? 0 : -1;
const renameLocation = renameLocationOffset + getRenameLocation(edits, renameFilename, fieldName.text, /*isDeclaredBeforeUse*/ false);
const renameLocation = renameLocationOffset + getRenameLocation(edits, renameFilename, fieldName.text, /*preferLastLocation*/ isParameter(declaration));
return { renameFilename, renameLocation, edits };
}
@@ -163,26 +163,12 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
changeTracker.replaceNode(file, declaration, property);
}
function updateParameterPropertyDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: ParameterDeclaration, fieldName: AcceptedNameType, modifiers: ModifiersArray | undefined, classLikeContainer: ClassLikeDeclaration) {
const property = createProperty(
declaration.decorators,
modifiers,
fieldName,
declaration.questionToken,
declaration.type,
declaration.initializer
);
changeTracker.insertNodeAtClassStart(file, classLikeContainer, property);
changeTracker.deleteNodeInList(file, declaration);
}
function updatePropertyAssignmentDeclaration (changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: PropertyAssignment, fieldName: AcceptedNameType) {
function updatePropertyAssignmentDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: PropertyAssignment, fieldName: AcceptedNameType) {
const assignment = updatePropertyAssignment(declaration, fieldName, declaration.initializer);
changeTracker.replacePropertyAssignment(file, declaration, assignment);
}
function updateFieldDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: AcceptedDeclaration, fieldName: AcceptedNameType, modifiers: ModifiersArray | undefined, container: ContainerDeclaration) {
function updateFieldDeclaration(changeTracker: textChanges.ChangeTracker, file: SourceFile, declaration: AcceptedDeclaration, fieldName: AcceptedNameType, modifiers: ModifiersArray | undefined) {
if (isPropertyDeclaration(declaration)) {
updatePropertyDeclaration(changeTracker, file, declaration, fieldName, modifiers);
}
@@ -190,7 +176,8 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
updatePropertyAssignmentDeclaration(changeTracker, file, declaration, fieldName);
}
else {
updateParameterPropertyDeclaration(changeTracker, file, declaration, fieldName, modifiers, <ClassLikeDeclaration>container);
changeTracker.replaceNode(file, declaration,
updateParameter(declaration, declaration.decorators, modifiers, declaration.dotDotDotToken, cast(fieldName, isIdentifier), declaration.questionToken, declaration.type, declaration.initializer));
}
}
+30 -3
View File
@@ -879,6 +879,10 @@ namespace ts {
return this._compilationSettings;
}
public getProjectReferences(): ReadonlyArray<ProjectReference> | undefined {
return this.host.getProjectReferences && this.host.getProjectReferences();
}
private createEntry(fileName: string, path: Path) {
let entry: CachedHostFileInformation;
const scriptSnapshot = this.host.getScriptSnapshot(fileName);
@@ -913,9 +917,18 @@ namespace ts {
}
public getRootFileNames(): string[] {
return arrayFrom(this.fileNameToEntry.values(), entry => {
return isString(entry) ? entry : entry.hostFileName;
const names: string[] = [];
this.fileNameToEntry.forEach(entry => {
if (isString(entry)) {
names.push(entry);
}
else {
if (entry.scriptKind !== ScriptKind.JSON) {
names.push(entry.hostFileName);
}
}
});
return names;
}
public getVersion(path: Path): string {
@@ -1242,7 +1255,14 @@ namespace ts {
}
const documentRegistryBucketKey = documentRegistry.getKeyForCompilationSettings(newSettings);
program = createProgram(rootFileNames, newSettings, compilerHost, program);
const options: CreateProgramOptions = {
rootNames: rootFileNames,
options: newSettings,
host: compilerHost,
oldProgram: program,
projectReferences: hostCache.getProjectReferences()
};
program = createProgram(options);
// hostCache is captured in the closure for 'getOrCreateSourceFile' but it should not be used past this point.
// It needs to be cleared to allow all collected snapshots to be released
@@ -1502,6 +1522,12 @@ namespace ts {
return checker.getSymbolAtLocation(node);
}
function toLineColumnOffset(fileName: string, position: number) {
const path = toPath(fileName, currentDirectory, getCanonicalFileName);
const file = program.getSourceFile(path) || sourcemappedFileCache.get(path);
return file.getLineAndCharacterOfPosition(position);
}
// Sometimes tools can sometimes see the following line as a source mapping url comment, so we mangle it a bit (the [M])
const sourceMapCommentRegExp = /^\/\/[@#] source[M]appingURL=(.+)$/gm;
const base64UrlRegExp = /^data:(?:application\/json(?:;charset=[uU][tT][fF]-8);base64,([A-Za-z0-9+\/=]+)$)?/;
@@ -2266,6 +2292,7 @@ namespace ts {
getProgram,
getApplicableRefactors,
getEditsForRefactor,
toLineColumnOffset
};
}
+17 -11
View File
@@ -442,19 +442,25 @@ namespace ts.textChanges {
public insertNodeAtClassStart(sourceFile: SourceFile, cls: ClassLikeDeclaration, newElement: ClassElement): void {
const clsStart = cls.getStart(sourceFile);
let prefix = "";
let suffix = this.newLineCharacter;
if (addToSeen(this.classesWithNodesInsertedAtStart, getNodeId(cls), cls)) {
prefix = this.newLineCharacter;
// For `class C {\n}`, don't add the trailing "\n"
if (cls.members.length === 0 && !(positionsAreOnSameLine as any)(...getClassBraceEnds(cls, sourceFile), sourceFile)) { // TODO: GH#4130 remove 'as any'
suffix = "";
}
}
const indentation = formatting.SmartIndenter.findFirstNonWhitespaceColumn(getLineStartPositionForPosition(clsStart, sourceFile), clsStart, sourceFile, this.formatContext.options)
+ this.formatContext.options.indentSize;
this.insertNodeAt(sourceFile, cls.members.pos, newElement, { indentation, prefix, suffix });
this.insertNodeAt(sourceFile, cls.members.pos, newElement, { indentation, ...this.getInsertNodeAtClassStartPrefixSuffix(sourceFile, cls) });
}
private getInsertNodeAtClassStartPrefixSuffix(sourceFile: SourceFile, cls: ClassLikeDeclaration): { prefix: string, suffix: string } {
if (cls.members.length === 0) {
if (addToSeen(this.classesWithNodesInsertedAtStart, getNodeId(cls), cls)) {
// For `class C {\n}`, don't add the trailing "\n"
const shouldSuffix = (positionsAreOnSameLine as any)(...getClassBraceEnds(cls, sourceFile), sourceFile); // TODO: GH#4130 remove 'as any'
return { prefix: this.newLineCharacter, suffix: shouldSuffix ? this.newLineCharacter : "" };
}
else {
return { prefix: "", suffix: this.newLineCharacter };
}
}
else {
return { prefix: this.newLineCharacter, suffix: "" };
}
}
public insertNodeAfter(sourceFile: SourceFile, after: Node, newNode: Node): this {
+18 -2
View File
@@ -181,6 +181,7 @@ namespace ts {
getScriptKind?(fileName: string): ScriptKind;
getScriptVersion(fileName: string): string;
getScriptSnapshot(fileName: string): IScriptSnapshot | undefined;
getProjectReferences?(): ReadonlyArray<ProjectReference> | undefined;
getLocalizedDiagnosticMessages?(): any;
getCancellationToken?(): HostCancellationToken;
getCurrentDirectory(): string;
@@ -322,6 +323,8 @@ namespace ts {
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
toLineColumnOffset?(fileName: string, position: number): LineAndCharacter;
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray<number>, formatOptions: FormatCodeSettings, preferences: UserPreferences): ReadonlyArray<CodeFixAction>;
getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: {}, formatOptions: FormatCodeSettings, preferences: UserPreferences): CombinedCodeActions;
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
@@ -357,9 +360,11 @@ namespace ts {
export type OrganizeImportsScope = CombinedCodeFixScope;
export type CompletionsTriggerCharacter = "." | '"' | "'" | "`" | "/" | "@" | "<";
export interface GetCompletionsAtPositionOptions extends UserPreferences {
/** If the editor is asking for completions because a certain character was typed, and not because the user explicitly requested them, this should be set. */
triggerCharacter?: string;
triggerCharacter?: CompletionsTriggerCharacter;
/** @deprecated Use includeCompletionsForModuleExports */
includeExternalModuleExports?: boolean;
/** @deprecated Use includeCompletionsWithInsertText */
@@ -826,9 +831,17 @@ namespace ts {
}
export const enum OutliningSpanKind {
/** Single or multi-line comments */
Comment = "comment",
/** Sections marked by '// #region' and '// #endregion' comments */
Region = "region",
Code = "code"
/** Declarations and expressions */
Code = "code",
/** Contiguous blocks of import declarations */
Imports = "imports"
}
export const enum OutputFileType {
@@ -989,6 +1002,9 @@ namespace ts {
* <JsxTagName attribute1 attribute2={0} />
*/
jsxAttribute = "JSX attribute",
/** String literal */
string = "string",
}
export const enum ScriptElementKindModifier {
+9 -9
View File
@@ -940,22 +940,22 @@ namespace ts {
break;
case SyntaxKind.CloseBraceToken:
// This can be object type, skip untill we find the matching open brace token
// Skip untill the matching open brace token
// This can be object type, skip until we find the matching open brace token
// Skip until the matching open brace token
token = findPrecedingMatchingToken(token, SyntaxKind.OpenBraceToken, sourceFile);
if (!token) return false;
break;
case SyntaxKind.CloseParenToken:
// This can be object type, skip untill we find the matching open brace token
// Skip untill the matching open brace token
// This can be object type, skip until we find the matching open brace token
// Skip until the matching open brace token
token = findPrecedingMatchingToken(token, SyntaxKind.OpenParenToken, sourceFile);
if (!token) return false;
break;
case SyntaxKind.CloseBracketToken:
// This can be object type, skip untill we find the matching open brace token
// Skip untill the matching open brace token
// This can be object type, skip until we find the matching open brace token
// Skip until the matching open brace token
token = findPrecedingMatchingToken(token, SyntaxKind.OpenBracketToken, sourceFile);
if (!token) return false;
break;
@@ -1538,7 +1538,7 @@ namespace ts {
* user was before extracting it.
*/
/* @internal */
export function getRenameLocation(edits: ReadonlyArray<FileTextChanges>, renameFilename: string, name: string, isDeclaredBeforeUse: boolean): number {
export function getRenameLocation(edits: ReadonlyArray<FileTextChanges>, renameFilename: string, name: string, preferLastLocation: boolean): number {
let delta = 0;
let lastPos = -1;
for (const { fileName, textChanges } of edits) {
@@ -1550,7 +1550,7 @@ namespace ts {
lastPos = span.start + delta + index;
// If the reference comes first, return immediately.
if (!isDeclaredBeforeUse) {
if (!preferLastLocation) {
return lastPos;
}
}
@@ -1559,7 +1559,7 @@ namespace ts {
}
// If the declaration comes first, return the position of the last occurrence.
Debug.assert(isDeclaredBeforeUse);
Debug.assert(preferLastLocation);
Debug.assert(lastPos >= 0);
return lastPos;
}
+145 -54
View File
@@ -337,32 +337,34 @@ declare namespace ts {
EnumMember = 272,
SourceFile = 273,
Bundle = 274,
JSDocTypeExpression = 275,
JSDocAllType = 276,
JSDocUnknownType = 277,
JSDocNullableType = 278,
JSDocNonNullableType = 279,
JSDocOptionalType = 280,
JSDocFunctionType = 281,
JSDocVariadicType = 282,
JSDocComment = 283,
JSDocTypeLiteral = 284,
JSDocTag = 285,
JSDocAugmentsTag = 286,
JSDocClassTag = 287,
JSDocParameterTag = 288,
JSDocReturnTag = 289,
JSDocTypeTag = 290,
JSDocTemplateTag = 291,
JSDocTypedefTag = 292,
JSDocPropertyTag = 293,
SyntaxList = 294,
NotEmittedStatement = 295,
PartiallyEmittedExpression = 296,
CommaListExpression = 297,
MergeDeclarationMarker = 298,
EndOfDeclarationMarker = 299,
Count = 300,
UnparsedSource = 275,
InputFiles = 276,
JSDocTypeExpression = 277,
JSDocAllType = 278,
JSDocUnknownType = 279,
JSDocNullableType = 280,
JSDocNonNullableType = 281,
JSDocOptionalType = 282,
JSDocFunctionType = 283,
JSDocVariadicType = 284,
JSDocComment = 285,
JSDocTypeLiteral = 286,
JSDocTag = 287,
JSDocAugmentsTag = 288,
JSDocClassTag = 289,
JSDocParameterTag = 290,
JSDocReturnTag = 291,
JSDocTypeTag = 292,
JSDocTemplateTag = 293,
JSDocTypedefTag = 294,
JSDocPropertyTag = 295,
SyntaxList = 296,
NotEmittedStatement = 297,
PartiallyEmittedExpression = 298,
CommaListExpression = 299,
MergeDeclarationMarker = 300,
EndOfDeclarationMarker = 301,
Count = 302,
FirstAssignment = 58,
LastAssignment = 70,
FirstCompoundAssignment = 59,
@@ -388,10 +390,10 @@ declare namespace ts {
FirstBinaryOperator = 27,
LastBinaryOperator = 70,
FirstNode = 145,
FirstJSDocNode = 275,
LastJSDocNode = 293,
FirstJSDocTagNode = 285,
LastJSDocTagNode = 293
FirstJSDocNode = 277,
LastJSDocNode = 295,
FirstJSDocTagNode = 287,
LastJSDocTagNode = 295
}
enum NodeFlags {
None = 0,
@@ -1150,7 +1152,7 @@ declare namespace ts {
kind: SyntaxKind.NotEmittedStatement;
}
/**
* A list of comma-seperated expressions. This node is only created by transformations.
* A list of comma-separated expressions. This node is only created by transformations.
*/
interface CommaListExpression extends Expression {
kind: SyntaxKind.CommaListExpression;
@@ -1646,8 +1648,18 @@ declare namespace ts {
}
interface Bundle extends Node {
kind: SyntaxKind.Bundle;
prepends: ReadonlyArray<InputFiles | UnparsedSource>;
sourceFiles: ReadonlyArray<SourceFile>;
}
interface InputFiles extends Node {
kind: SyntaxKind.InputFiles;
javascriptText: string;
declarationText: string;
}
interface UnparsedSource extends Node {
kind: SyntaxKind.UnparsedSource;
text: string;
}
interface JsonSourceFile extends SourceFile {
statements: NodeArray<JsonObjectExpressionStatement>;
}
@@ -1717,12 +1729,19 @@ declare namespace ts {
*/
getTypeChecker(): TypeChecker;
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
getProjectReferences(): (ResolvedProjectReference | undefined)[] | undefined;
}
interface ResolvedProjectReference {
commandLine: ParsedCommandLine;
sourceFile: SourceFile;
}
interface CustomTransformers {
/** Custom transformers to evaluate before built-in transformations. */
/** Custom transformers to evaluate before built-in .js transformations. */
before?: TransformerFactory<SourceFile>[];
/** Custom transformers to evaluate after built-in transformations. */
/** Custom transformers to evaluate after built-in .js transformations. */
after?: TransformerFactory<SourceFile>[];
/** Custom transformers to evaluate after built-in .d.ts transformations. */
afterDeclarations?: TransformerFactory<Bundle | SourceFile>[];
}
interface SourceMapSpan {
/** Line number in the .js file. */
@@ -2336,7 +2355,17 @@ declare namespace ts {
interface PluginImport {
name: string;
}
type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]> | PluginImport[] | null | undefined;
interface ProjectReference {
/** A normalized path on disk */
path: string;
/** The path as the user originally wrote it */
originalPath?: string;
/** True if the output of this reference should be prepended to the output of this project. Only valid for --outFile compilations */
prepend?: boolean;
/** True if it is intended that this reference form a circularity */
circular?: boolean;
}
type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]> | PluginImport[] | ProjectReference[] | null | undefined;
interface CompilerOptions {
allowJs?: boolean;
allowSyntheticDefaultImports?: boolean;
@@ -2392,6 +2421,7 @@ declare namespace ts {
project?: string;
reactNamespace?: string;
jsxFactory?: string;
composite?: boolean;
removeComments?: boolean;
rootDir?: string;
rootDirs?: string[];
@@ -2467,6 +2497,7 @@ declare namespace ts {
ES2017 = 4,
ES2018 = 5,
ESNext = 6,
JSON = 100,
Latest = 6
}
enum LanguageVariant {
@@ -2478,6 +2509,7 @@ declare namespace ts {
options: CompilerOptions;
typeAcquisition?: TypeAcquisition;
fileNames: string[];
projectReferences?: ReadonlyArray<ProjectReference>;
raw?: any;
errors: Diagnostic[];
wildcardDirectories?: MapLike<WatchDirectoryFlags>;
@@ -2489,8 +2521,17 @@ declare namespace ts {
}
interface ExpandResult {
fileNames: string[];
projectReferences: ReadonlyArray<ProjectReference> | undefined;
wildcardDirectories: MapLike<WatchDirectoryFlags>;
}
interface CreateProgramOptions {
rootNames: ReadonlyArray<string>;
options: CompilerOptions;
projectReferences?: ReadonlyArray<ProjectReference>;
host?: CompilerHost;
oldProgram?: Program;
configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>;
}
interface ModuleResolutionHost {
fileExists(fileName: string): boolean;
readFile(fileName: string): string | undefined;
@@ -2581,6 +2622,7 @@ declare namespace ts {
getCanonicalFileName(fileName: string): string;
useCaseSensitiveFileNames(): boolean;
getNewLine(): string;
readDirectory?(rootDir: string, extensions: ReadonlyArray<string>, excludes: ReadonlyArray<string> | undefined, includes: ReadonlyArray<string>, depth?: number): string[];
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): (ResolvedModule | undefined)[];
/**
* This method is a companion for 'resolveModuleNames' and is used to resolve 'types' references to actual type declaration files
@@ -3747,8 +3789,10 @@ declare namespace ts {
function updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression): PartiallyEmittedExpression;
function createCommaList(elements: ReadonlyArray<Expression>): CommaListExpression;
function updateCommaList(node: CommaListExpression, elements: ReadonlyArray<Expression>): CommaListExpression;
function createBundle(sourceFiles: ReadonlyArray<SourceFile>): Bundle;
function updateBundle(node: Bundle, sourceFiles: ReadonlyArray<SourceFile>): Bundle;
function createBundle(sourceFiles: ReadonlyArray<SourceFile>, prepends?: ReadonlyArray<UnparsedSource | InputFiles>): Bundle;
function createUnparsedSourceFile(text: string): UnparsedSource;
function createInputFiles(javascript: string, declaration: string): InputFiles;
function updateBundle(node: Bundle, sourceFiles: ReadonlyArray<SourceFile>, prepends?: ReadonlyArray<UnparsedSource>): Bundle;
function createImmediatelyInvokedFunctionExpression(statements: ReadonlyArray<Statement>): CallExpression;
function createImmediatelyInvokedFunctionExpression(statements: ReadonlyArray<Statement>, param: ParameterDeclaration, paramValue: Expression): CallExpression;
function createImmediatelyInvokedArrowFunction(statements: ReadonlyArray<Statement>): CallExpression;
@@ -3955,6 +3999,7 @@ declare namespace ts {
* @param configFileParsingDiagnostics - error during config file parsing
* @returns A 'Program' object.
*/
function createProgram(createProgramOptions: CreateProgramOptions): Program;
function createProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): Program;
}
declare namespace ts {
@@ -4094,7 +4139,6 @@ declare namespace ts {
function createAbstractBuilder(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): BuilderProgram;
}
declare namespace ts {
type DiagnosticReporter = (diagnostic: Diagnostic) => void;
type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string, options: CompilerOptions) => void;
/** Create the program with rootNames and options, if they are undefined, oldProgram and new configFile diagnostics create new program */
type CreateProgram<T extends BuilderProgram> = (rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: T, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>) => T;
@@ -4157,15 +4201,6 @@ declare namespace ts {
/** Compiler options */
options: CompilerOptions;
}
/**
* Reports config file diagnostics
*/
interface ConfigFileDiagnosticsReporter {
/**
* Reports unrecoverable error when parsing config file
*/
onUnRecoverableConfigFileDiagnostic: DiagnosticReporter;
}
/**
* Host to create watch with config file
*/
@@ -4212,6 +4247,26 @@ declare namespace ts {
}
declare namespace ts {
function parseCommandLine(commandLine: ReadonlyArray<string>, readFile?: (path: string) => string | undefined): ParsedCommandLine;
type DiagnosticReporter = (diagnostic: Diagnostic) => void;
/**
* Reports config file diagnostics
*/
interface ConfigFileDiagnosticsReporter {
/**
* Reports unrecoverable error when parsing config file
*/
onUnRecoverableConfigFileDiagnostic: DiagnosticReporter;
}
/**
* Interface extending ParseConfigHost to support ParseConfigFile that reads config file and reports errors
*/
interface ParseConfigFileHost extends ParseConfigHost, ConfigFileDiagnosticsReporter {
getCurrentDirectory(): string;
}
/**
* Reads the config file, reports errors if any and exits if the config file cannot be found
*/
function getParsedCommandLineOfConfigFile(configFileName: string, optionsToExtend: CompilerOptions, host: ParseConfigFileHost): ParsedCommandLine | undefined;
/**
* Read tsconfig.json file
* @param fileName The path to the config file
@@ -4385,6 +4440,7 @@ declare namespace ts {
getScriptKind?(fileName: string): ScriptKind;
getScriptVersion(fileName: string): string;
getScriptSnapshot(fileName: string): IScriptSnapshot | undefined;
getProjectReferences?(): ReadonlyArray<ProjectReference> | undefined;
getLocalizedDiagnosticMessages?(): any;
getCancellationToken?(): HostCancellationToken;
getCurrentDirectory(): string;
@@ -4462,6 +4518,7 @@ declare namespace ts {
getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion;
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean;
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
toLineColumnOffset?(fileName: string, position: number): LineAndCharacter;
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray<number>, formatOptions: FormatCodeSettings, preferences: UserPreferences): ReadonlyArray<CodeFixAction>;
getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: {}, formatOptions: FormatCodeSettings, preferences: UserPreferences): CombinedCodeActions;
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
@@ -4486,9 +4543,10 @@ declare namespace ts {
fileName: string;
}
type OrganizeImportsScope = CombinedCodeFixScope;
type CompletionsTriggerCharacter = "." | '"' | "'" | "`" | "/" | "@" | "<";
interface GetCompletionsAtPositionOptions extends UserPreferences {
/** If the editor is asking for completions because a certain character was typed, and not because the user explicitly requested them, this should be set. */
triggerCharacter?: string;
triggerCharacter?: CompletionsTriggerCharacter;
/** @deprecated Use includeCompletionsForModuleExports */
includeExternalModuleExports?: boolean;
/** @deprecated Use includeCompletionsWithInsertText */
@@ -4892,9 +4950,14 @@ declare namespace ts {
kind: OutliningSpanKind;
}
enum OutliningSpanKind {
/** Single or multi-line comments */
Comment = "comment",
/** Sections marked by '// #region' and '// #endregion' comments */
Region = "region",
Code = "code"
/** Declarations and expressions */
Code = "code",
/** Contiguous blocks of import declarations */
Imports = "imports"
}
enum OutputFileType {
JavaScript = 0,
@@ -5018,7 +5081,9 @@ declare namespace ts {
/**
* <JsxTagName attribute1 attribute2={0} />
*/
jsxAttribute = "JSX attribute"
jsxAttribute = "JSX attribute",
/** String literal */
string = "string"
}
enum ScriptElementKindModifier {
none = "",
@@ -5378,6 +5443,7 @@ declare namespace ts.server {
configHasFilesProperty: boolean;
configHasIncludeProperty: boolean;
configHasExcludeProperty: boolean;
projectReferences: ReadonlyArray<ProjectReference> | undefined;
/**
* these fields can be present in the project file
*/
@@ -6716,6 +6782,7 @@ declare namespace ts.server.protocol {
command: CommandTypes.Formatonkey;
arguments: FormatOnKeyRequestArgs;
}
type CompletionsTriggerCharacter = "." | '"' | "'" | "`" | "/" | "@" | "<";
/**
* Arguments for completions messages.
*/
@@ -6724,7 +6791,7 @@ declare namespace ts.server.protocol {
* Optional prefix to apply to possible completions.
*/
prefix?: string;
triggerCharacter?: string;
triggerCharacter?: CompletionsTriggerCharacter;
/**
* @deprecated Use UserPreferences.includeCompletionsForModuleExports
*/
@@ -7557,6 +7624,7 @@ declare namespace ts.server.protocol {
project?: string;
reactNamespace?: string;
removeComments?: boolean;
references?: ProjectReference[];
rootDir?: string;
rootDirs?: string[];
skipLibCheck?: boolean;
@@ -7668,7 +7736,7 @@ declare namespace ts.server {
enqueueInstallTypingsRequest(p: Project, typeAcquisition: TypeAcquisition, unresolvedImports: SortedReadonlyArray<string>): void;
attach(projectService: ProjectService): void;
onProjectClosed(p: Project): void;
readonly globalTypingsCacheLocation: string;
readonly globalTypingsCacheLocation: string | undefined;
}
const nullTypingsInstaller: ITypingsInstaller;
}
@@ -7745,7 +7813,7 @@ declare namespace ts.server {
private readonly cancellationToken;
isNonTsProject(): boolean;
isJsOnlyProject(): boolean;
static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {};
static resolveModule(moduleName: string, initialDir: string, host: ServerHost, log: (message: string) => void): {} | undefined;
isKnownTypesPackageName(name: string): boolean;
installPackage(options: InstallPackageOptions): Promise<ApplyCodeActionCommandResult>;
private readonly typingsCache;
@@ -7753,6 +7821,7 @@ declare namespace ts.server {
getCompilerOptions(): CompilerOptions;
getNewLine(): string;
getProjectVersion(): string;
getProjectReferences(): ReadonlyArray<ProjectReference> | undefined;
getScriptFileNames(): string[];
private getOrCreateScriptInfoAndAttachToProject;
getScriptKind(fileName: string): ScriptKind;
@@ -7826,6 +7895,8 @@ declare namespace ts.server {
protected removeRoot(info: ScriptInfo): void;
protected enableGlobalPlugins(): void;
protected enablePlugin(pluginConfigEntry: PluginImport, searchPaths: string[]): void;
/** Starts a new check for diagnostics. Call this if some file has updated that would cause diagnostics to be changed. */
refreshDiagnostics(): void;
private enableProxy;
}
/**
@@ -7852,6 +7923,7 @@ declare namespace ts.server {
*/
class ConfiguredProject extends Project {
compileOnSaveEnabled: boolean;
private projectReferences;
private typeAcquisition;
private directoriesWatchedForWildcards;
readonly canonicalConfigFilePath: NormalizedPath;
@@ -7864,6 +7936,8 @@ declare namespace ts.server {
*/
updateGraph(): boolean;
getConfigFilePath(): NormalizedPath;
getProjectReferences(): ReadonlyArray<ProjectReference> | undefined;
updateReferences(refs: ReadonlyArray<ProjectReference> | undefined): void;
enablePlugins(): void;
/**
* Get the errors that dont have any file name associated
@@ -7899,6 +7973,7 @@ declare namespace ts.server {
const ConfigFileDiagEvent = "configFileDiag";
const ProjectLanguageServiceStateEvent = "projectLanguageServiceState";
const ProjectInfoTelemetryEvent = "projectInfo";
const OpenFileInfoTelemetryEvent = "openFileInfo";
interface ProjectsUpdatedInBackgroundEvent {
eventName: typeof ProjectsUpdatedInBackgroundEvent;
data: {
@@ -7947,6 +8022,18 @@ declare namespace ts.server {
/** TypeScript version used by the server. */
readonly version: string;
}
/**
* Info that we may send about a file that was just opened.
* Info about a file will only be sent once per session, even if the file changes in ways that might affect the info.
* Currently this is only sent for '.js' files.
*/
interface OpenFileInfoTelemetryEvent {
readonly eventName: typeof OpenFileInfoTelemetryEvent;
readonly data: OpenFileInfoTelemetryEventData;
}
interface OpenFileInfoTelemetryEventData {
readonly info: OpenFileInfo;
}
interface ProjectInfoTypeAcquisitionData {
readonly enable: boolean;
readonly include: boolean;
@@ -7959,7 +8046,10 @@ declare namespace ts.server {
readonly tsx: number;
readonly dts: number;
}
type ProjectServiceEvent = ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent;
interface OpenFileInfo {
readonly checkJs: boolean;
}
type ProjectServiceEvent = ProjectsUpdatedInBackgroundEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent | OpenFileInfoTelemetryEvent;
type ProjectServiceEventHandler = (event: ProjectServiceEvent) => void;
interface SafeList {
[name: string]: {
@@ -8010,6 +8100,7 @@ declare namespace ts.server {
* Container of all known scripts
*/
private readonly filenameToScriptInfo;
private readonly allJsFilesForOpenFileTelemetry;
/**
* maps external project file name to list of config files that were the part of this project
*/
@@ -8078,7 +8169,6 @@ declare namespace ts.server {
updateTypingsForProject(response: SetTypings | InvalidateCachedTypings | PackageInstalledResponse): void;
private delayEnsureProjectForOpenFiles;
private delayUpdateProjectGraph;
private sendProjectsUpdatedInBackgroundEvent;
private delayUpdateProjectGraphs;
setCompilerOptionsForInferredProjects(projectCompilerOptions: protocol.ExternalProjectCompilerOptions, projectRootPath?: string): void;
findProject(projectName: string): Project | undefined;
@@ -8215,6 +8305,7 @@ declare namespace ts.server {
openClientFile(fileName: string, fileContent?: string, scriptKind?: ScriptKind, projectRootPath?: string): OpenConfiguredProjectResult;
private findExternalProjectContainingOpenScriptInfo;
openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult;
private telemetryOnOpenFile;
/**
* Close file whose contents is managed by the client
* @param filename is absolute pathname
+114 -49
View File
@@ -337,32 +337,34 @@ declare namespace ts {
EnumMember = 272,
SourceFile = 273,
Bundle = 274,
JSDocTypeExpression = 275,
JSDocAllType = 276,
JSDocUnknownType = 277,
JSDocNullableType = 278,
JSDocNonNullableType = 279,
JSDocOptionalType = 280,
JSDocFunctionType = 281,
JSDocVariadicType = 282,
JSDocComment = 283,
JSDocTypeLiteral = 284,
JSDocTag = 285,
JSDocAugmentsTag = 286,
JSDocClassTag = 287,
JSDocParameterTag = 288,
JSDocReturnTag = 289,
JSDocTypeTag = 290,
JSDocTemplateTag = 291,
JSDocTypedefTag = 292,
JSDocPropertyTag = 293,
SyntaxList = 294,
NotEmittedStatement = 295,
PartiallyEmittedExpression = 296,
CommaListExpression = 297,
MergeDeclarationMarker = 298,
EndOfDeclarationMarker = 299,
Count = 300,
UnparsedSource = 275,
InputFiles = 276,
JSDocTypeExpression = 277,
JSDocAllType = 278,
JSDocUnknownType = 279,
JSDocNullableType = 280,
JSDocNonNullableType = 281,
JSDocOptionalType = 282,
JSDocFunctionType = 283,
JSDocVariadicType = 284,
JSDocComment = 285,
JSDocTypeLiteral = 286,
JSDocTag = 287,
JSDocAugmentsTag = 288,
JSDocClassTag = 289,
JSDocParameterTag = 290,
JSDocReturnTag = 291,
JSDocTypeTag = 292,
JSDocTemplateTag = 293,
JSDocTypedefTag = 294,
JSDocPropertyTag = 295,
SyntaxList = 296,
NotEmittedStatement = 297,
PartiallyEmittedExpression = 298,
CommaListExpression = 299,
MergeDeclarationMarker = 300,
EndOfDeclarationMarker = 301,
Count = 302,
FirstAssignment = 58,
LastAssignment = 70,
FirstCompoundAssignment = 59,
@@ -388,10 +390,10 @@ declare namespace ts {
FirstBinaryOperator = 27,
LastBinaryOperator = 70,
FirstNode = 145,
FirstJSDocNode = 275,
LastJSDocNode = 293,
FirstJSDocTagNode = 285,
LastJSDocTagNode = 293
FirstJSDocNode = 277,
LastJSDocNode = 295,
FirstJSDocTagNode = 287,
LastJSDocTagNode = 295
}
enum NodeFlags {
None = 0,
@@ -1150,7 +1152,7 @@ declare namespace ts {
kind: SyntaxKind.NotEmittedStatement;
}
/**
* A list of comma-seperated expressions. This node is only created by transformations.
* A list of comma-separated expressions. This node is only created by transformations.
*/
interface CommaListExpression extends Expression {
kind: SyntaxKind.CommaListExpression;
@@ -1646,8 +1648,18 @@ declare namespace ts {
}
interface Bundle extends Node {
kind: SyntaxKind.Bundle;
prepends: ReadonlyArray<InputFiles | UnparsedSource>;
sourceFiles: ReadonlyArray<SourceFile>;
}
interface InputFiles extends Node {
kind: SyntaxKind.InputFiles;
javascriptText: string;
declarationText: string;
}
interface UnparsedSource extends Node {
kind: SyntaxKind.UnparsedSource;
text: string;
}
interface JsonSourceFile extends SourceFile {
statements: NodeArray<JsonObjectExpressionStatement>;
}
@@ -1717,12 +1729,19 @@ declare namespace ts {
*/
getTypeChecker(): TypeChecker;
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
getProjectReferences(): (ResolvedProjectReference | undefined)[] | undefined;
}
interface ResolvedProjectReference {
commandLine: ParsedCommandLine;
sourceFile: SourceFile;
}
interface CustomTransformers {
/** Custom transformers to evaluate before built-in transformations. */
/** Custom transformers to evaluate before built-in .js transformations. */
before?: TransformerFactory<SourceFile>[];
/** Custom transformers to evaluate after built-in transformations. */
/** Custom transformers to evaluate after built-in .js transformations. */
after?: TransformerFactory<SourceFile>[];
/** Custom transformers to evaluate after built-in .d.ts transformations. */
afterDeclarations?: TransformerFactory<Bundle | SourceFile>[];
}
interface SourceMapSpan {
/** Line number in the .js file. */
@@ -2336,7 +2355,17 @@ declare namespace ts {
interface PluginImport {
name: string;
}
type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]> | PluginImport[] | null | undefined;
interface ProjectReference {
/** A normalized path on disk */
path: string;
/** The path as the user originally wrote it */
originalPath?: string;
/** True if the output of this reference should be prepended to the output of this project. Only valid for --outFile compilations */
prepend?: boolean;
/** True if it is intended that this reference form a circularity */
circular?: boolean;
}
type CompilerOptionsValue = string | number | boolean | (string | number)[] | string[] | MapLike<string[]> | PluginImport[] | ProjectReference[] | null | undefined;
interface CompilerOptions {
allowJs?: boolean;
allowSyntheticDefaultImports?: boolean;
@@ -2392,6 +2421,7 @@ declare namespace ts {
project?: string;
reactNamespace?: string;
jsxFactory?: string;
composite?: boolean;
removeComments?: boolean;
rootDir?: string;
rootDirs?: string[];
@@ -2467,6 +2497,7 @@ declare namespace ts {
ES2017 = 4,
ES2018 = 5,
ESNext = 6,
JSON = 100,
Latest = 6
}
enum LanguageVariant {
@@ -2478,6 +2509,7 @@ declare namespace ts {
options: CompilerOptions;
typeAcquisition?: TypeAcquisition;
fileNames: string[];
projectReferences?: ReadonlyArray<ProjectReference>;
raw?: any;
errors: Diagnostic[];
wildcardDirectories?: MapLike<WatchDirectoryFlags>;
@@ -2489,8 +2521,17 @@ declare namespace ts {
}
interface ExpandResult {
fileNames: string[];
projectReferences: ReadonlyArray<ProjectReference> | undefined;
wildcardDirectories: MapLike<WatchDirectoryFlags>;
}
interface CreateProgramOptions {
rootNames: ReadonlyArray<string>;
options: CompilerOptions;
projectReferences?: ReadonlyArray<ProjectReference>;
host?: CompilerHost;
oldProgram?: Program;
configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>;
}
interface ModuleResolutionHost {
fileExists(fileName: string): boolean;
readFile(fileName: string): string | undefined;
@@ -2581,6 +2622,7 @@ declare namespace ts {
getCanonicalFileName(fileName: string): string;
useCaseSensitiveFileNames(): boolean;
getNewLine(): string;
readDirectory?(rootDir: string, extensions: ReadonlyArray<string>, excludes: ReadonlyArray<string> | undefined, includes: ReadonlyArray<string>, depth?: number): string[];
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): (ResolvedModule | undefined)[];
/**
* This method is a companion for 'resolveModuleNames' and is used to resolve 'types' references to actual type declaration files
@@ -3747,8 +3789,10 @@ declare namespace ts {
function updatePartiallyEmittedExpression(node: PartiallyEmittedExpression, expression: Expression): PartiallyEmittedExpression;
function createCommaList(elements: ReadonlyArray<Expression>): CommaListExpression;
function updateCommaList(node: CommaListExpression, elements: ReadonlyArray<Expression>): CommaListExpression;
function createBundle(sourceFiles: ReadonlyArray<SourceFile>): Bundle;
function updateBundle(node: Bundle, sourceFiles: ReadonlyArray<SourceFile>): Bundle;
function createBundle(sourceFiles: ReadonlyArray<SourceFile>, prepends?: ReadonlyArray<UnparsedSource | InputFiles>): Bundle;
function createUnparsedSourceFile(text: string): UnparsedSource;
function createInputFiles(javascript: string, declaration: string): InputFiles;
function updateBundle(node: Bundle, sourceFiles: ReadonlyArray<SourceFile>, prepends?: ReadonlyArray<UnparsedSource>): Bundle;
function createImmediatelyInvokedFunctionExpression(statements: ReadonlyArray<Statement>): CallExpression;
function createImmediatelyInvokedFunctionExpression(statements: ReadonlyArray<Statement>, param: ParameterDeclaration, paramValue: Expression): CallExpression;
function createImmediatelyInvokedArrowFunction(statements: ReadonlyArray<Statement>): CallExpression;
@@ -3955,6 +3999,7 @@ declare namespace ts {
* @param configFileParsingDiagnostics - error during config file parsing
* @returns A 'Program' object.
*/
function createProgram(createProgramOptions: CreateProgramOptions): Program;
function createProgram(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): Program;
}
declare namespace ts {
@@ -4094,7 +4139,6 @@ declare namespace ts {
function createAbstractBuilder(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: BuilderProgram, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): BuilderProgram;
}
declare namespace ts {
type DiagnosticReporter = (diagnostic: Diagnostic) => void;
type WatchStatusReporter = (diagnostic: Diagnostic, newLine: string, options: CompilerOptions) => void;
/** Create the program with rootNames and options, if they are undefined, oldProgram and new configFile diagnostics create new program */
type CreateProgram<T extends BuilderProgram> = (rootNames: ReadonlyArray<string> | undefined, options: CompilerOptions | undefined, host?: CompilerHost, oldProgram?: T, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>) => T;
@@ -4157,15 +4201,6 @@ declare namespace ts {
/** Compiler options */
options: CompilerOptions;
}
/**
* Reports config file diagnostics
*/
interface ConfigFileDiagnosticsReporter {
/**
* Reports unrecoverable error when parsing config file
*/
onUnRecoverableConfigFileDiagnostic: DiagnosticReporter;
}
/**
* Host to create watch with config file
*/
@@ -4212,6 +4247,26 @@ declare namespace ts {
}
declare namespace ts {
function parseCommandLine(commandLine: ReadonlyArray<string>, readFile?: (path: string) => string | undefined): ParsedCommandLine;
type DiagnosticReporter = (diagnostic: Diagnostic) => void;
/**
* Reports config file diagnostics
*/
interface ConfigFileDiagnosticsReporter {
/**
* Reports unrecoverable error when parsing config file
*/
onUnRecoverableConfigFileDiagnostic: DiagnosticReporter;
}
/**
* Interface extending ParseConfigHost to support ParseConfigFile that reads config file and reports errors
*/
interface ParseConfigFileHost extends ParseConfigHost, ConfigFileDiagnosticsReporter {
getCurrentDirectory(): string;
}
/**
* Reads the config file, reports errors if any and exits if the config file cannot be found
*/
function getParsedCommandLineOfConfigFile(configFileName: string, optionsToExtend: CompilerOptions, host: ParseConfigFileHost): ParsedCommandLine | undefined;
/**
* Read tsconfig.json file
* @param fileName The path to the config file
@@ -4385,6 +4440,7 @@ declare namespace ts {
getScriptKind?(fileName: string): ScriptKind;
getScriptVersion(fileName: string): string;
getScriptSnapshot(fileName: string): IScriptSnapshot | undefined;
getProjectReferences?(): ReadonlyArray<ProjectReference> | undefined;
getLocalizedDiagnosticMessages?(): any;
getCancellationToken?(): HostCancellationToken;
getCurrentDirectory(): string;
@@ -4462,6 +4518,7 @@ declare namespace ts {
getDocCommentTemplateAtPosition(fileName: string, position: number): TextInsertion;
isValidBraceCompletionAtPosition(fileName: string, position: number, openingBrace: number): boolean;
getSpanOfEnclosingComment(fileName: string, position: number, onlyMultiLine: boolean): TextSpan;
toLineColumnOffset?(fileName: string, position: number): LineAndCharacter;
getCodeFixesAtPosition(fileName: string, start: number, end: number, errorCodes: ReadonlyArray<number>, formatOptions: FormatCodeSettings, preferences: UserPreferences): ReadonlyArray<CodeFixAction>;
getCombinedCodeFix(scope: CombinedCodeFixScope, fixId: {}, formatOptions: FormatCodeSettings, preferences: UserPreferences): CombinedCodeActions;
applyCodeActionCommand(action: CodeActionCommand): Promise<ApplyCodeActionCommandResult>;
@@ -4486,9 +4543,10 @@ declare namespace ts {
fileName: string;
}
type OrganizeImportsScope = CombinedCodeFixScope;
type CompletionsTriggerCharacter = "." | '"' | "'" | "`" | "/" | "@" | "<";
interface GetCompletionsAtPositionOptions extends UserPreferences {
/** If the editor is asking for completions because a certain character was typed, and not because the user explicitly requested them, this should be set. */
triggerCharacter?: string;
triggerCharacter?: CompletionsTriggerCharacter;
/** @deprecated Use includeCompletionsForModuleExports */
includeExternalModuleExports?: boolean;
/** @deprecated Use includeCompletionsWithInsertText */
@@ -4892,9 +4950,14 @@ declare namespace ts {
kind: OutliningSpanKind;
}
enum OutliningSpanKind {
/** Single or multi-line comments */
Comment = "comment",
/** Sections marked by '// #region' and '// #endregion' comments */
Region = "region",
Code = "code"
/** Declarations and expressions */
Code = "code",
/** Contiguous blocks of import declarations */
Imports = "imports"
}
enum OutputFileType {
JavaScript = 0,
@@ -5018,7 +5081,9 @@ declare namespace ts {
/**
* <JsxTagName attribute1 attribute2={0} />
*/
jsxAttribute = "JSX attribute"
jsxAttribute = "JSX attribute",
/** String literal */
string = "string"
}
enum ScriptElementKindModifier {
none = "",
@@ -47,9 +47,10 @@ function foo() {
return __asyncGenerator(this, arguments, function foo_1() {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, "foo"];
case 1: return [4 /*yield*/, __await.apply(void 0, [Promise.resolve().then(function () { return require(_a.sent()); })])];
case 2:
case 0: return [4 /*yield*/, __await("foo")];
case 1: return [4 /*yield*/, _a.sent()];
case 2: return [4 /*yield*/, __await.apply(void 0, [Promise.resolve().then(function () { return require(_a.sent()); })])];
case 3:
Promise.resolve().then(function () { return require((_a.sent())["default"]); });
return [2 /*return*/];
}
@@ -1,2 +1,2 @@
//// [bundle.d.ts.map]
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["tests/cases/compiler/a.ts","tests/cases/compiler/index.ts"],"names":[],"mappings":";IAAA,MAAM;QACF,OAAO,CAAC,CAAC,EAAE;YAAC,CAAC,EAAE,MAAM,CAAA;SAAC;;;QAGtB,MAAM,CAAC,IAAI;KAGd;;;ICPD,OAAO,EAAC,GAAG,EAAC,UAAY;IAExB,MAAM,CAAC,KAAY,CAAC;IAGpB,MAAM,CAAC,IAAI,CAAC;;KAAqB,CAAC;IAClC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC"}
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["tests/cases/compiler/a.ts","tests/cases/compiler/index.ts"],"names":[],"mappings":";IAAA,MAAM;QACF,OAAO,CAAC,GAAG;YAAC,CAAC,EAAE,MAAM,CAAA;SAAC;;;QAGtB,MAAM,CAAC,IAAI;KAGd;;;ICPD,OAAO,EAAC,GAAG,EAAC,UAAY;IAExB,MAAM,CAAC,KAAY,CAAC;IAGpB,MAAM,CAAC,IAAI,CAAC;;KAAqB,CAAC;IAClC,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC"}
@@ -22,20 +22,17 @@ sourceFile:tests/cases/compiler/a.ts
1->^^^^^^^^
2 > ^^^^^^^
3 > ^
4 > ^
5 > ^^
6 > ^^^^->
4 > ^^^
5 > ^^^^->
1-> class Foo {
>
2 > doThing
3 > (
4 > x
5 > :
4 > x:
1->Emitted(3, 9) Source(2, 5) + SourceIndex(0)
2 >Emitted(3, 16) Source(2, 12) + SourceIndex(0)
3 >Emitted(3, 17) Source(2, 13) + SourceIndex(0)
4 >Emitted(3, 18) Source(2, 14) + SourceIndex(0)
5 >Emitted(3, 20) Source(2, 16) + SourceIndex(0)
4 >Emitted(3, 20) Source(2, 16) + SourceIndex(0)
---
>>> a: number;
1->^^^^^^^^^^^^
@@ -1,2 +1,2 @@
//// [bundle.d.ts.map]
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["tests/cases/compiler/a.ts","tests/cases/compiler/index.ts"],"names":[],"mappings":"AAAA;IACI,OAAO,CAAC,CAAC,EAAE;QAAC,CAAC,EAAE,MAAM,CAAA;KAAC;;;IAGtB,MAAM,CAAC,IAAI;CAGd;ACPD,QAAA,MAAM,CAAC,KAAY,CAAC;AAGpB,QAAA,IAAI,CAAC;;CAAqB,CAAC"}
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["tests/cases/compiler/a.ts","tests/cases/compiler/index.ts"],"names":[],"mappings":"AAAA;IACI,OAAO,CAAC,GAAG;QAAC,CAAC,EAAE,MAAM,CAAA;KAAC;;;IAGtB,MAAM,CAAC,IAAI;CAGd;ACPD,QAAA,MAAM,CAAC,KAAY,CAAC;AAGpB,QAAA,IAAI,CAAC;;CAAqB,CAAC"}
@@ -18,20 +18,17 @@ sourceFile:tests/cases/compiler/a.ts
1->^^^^
2 > ^^^^^^^
3 > ^
4 > ^
5 > ^^
6 > ^^^^->
4 > ^^^
5 > ^^^^->
1->class Foo {
>
2 > doThing
3 > (
4 > x
5 > :
4 > x:
1->Emitted(2, 5) Source(2, 5) + SourceIndex(0)
2 >Emitted(2, 12) Source(2, 12) + SourceIndex(0)
3 >Emitted(2, 13) Source(2, 13) + SourceIndex(0)
4 >Emitted(2, 14) Source(2, 14) + SourceIndex(0)
5 >Emitted(2, 16) Source(2, 16) + SourceIndex(0)
4 >Emitted(2, 16) Source(2, 16) + SourceIndex(0)
---
>>> a: number;
1->^^^^^^^^
@@ -1,3 +1,3 @@
//// [bundle.js.map]
{"version":3,"file":"bundle.js","sourceRoot":"","sources":["tests/cases/compiler/a.ts","tests/cases/compiler/index.ts"],"names":[],"mappings":"AAAA;IAAA;IAOA,CAAC;IANG,qBAAO,GAAP,UAAQ,CAAc;QAClB,OAAO,EAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAC,CAAC;IACpB,CAAC;IACM,QAAI,GAAX;QACI,OAAO,IAAI,GAAG,EAAE,CAAC;IACrB,CAAC;IACL,UAAC;AAAD,CAAC,AAPD,IAOC;ACPD,IAAM,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC;AACpB,CAAC,CAAC,OAAO,CAAC,EAAC,CAAC,EAAE,EAAE,EAAC,CAAC,CAAC;AAEnB,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAC,CAAC,EAAE,EAAE,EAAC,CAAC,CAAC"}//// [bundle.d.ts.map]
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["tests/cases/compiler/a.ts","tests/cases/compiler/index.ts"],"names":[],"mappings":"AAAA;IACI,OAAO,CAAC,CAAC,EAAE;QAAC,CAAC,EAAE,MAAM,CAAA;KAAC;;;IAGtB,MAAM,CAAC,IAAI;CAGd;ACPD,QAAA,MAAM,CAAC,KAAY,CAAC;AAGpB,QAAA,IAAI,CAAC;;CAAqB,CAAC"}
{"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["tests/cases/compiler/a.ts","tests/cases/compiler/index.ts"],"names":[],"mappings":"AAAA;IACI,OAAO,CAAC,GAAG;QAAC,CAAC,EAAE,MAAM,CAAA;KAAC;;;IAGtB,MAAM,CAAC,IAAI;CAGd;ACPD,QAAA,MAAM,CAAC,KAAY,CAAC;AAGpB,QAAA,IAAI,CAAC;;CAAqB,CAAC"}
@@ -312,20 +312,17 @@ sourceFile:tests/cases/compiler/a.ts
1->^^^^
2 > ^^^^^^^
3 > ^
4 > ^
5 > ^^
6 > ^^^^->
4 > ^^^
5 > ^^^^->
1->class Foo {
>
2 > doThing
3 > (
4 > x
5 > :
4 > x:
1->Emitted(2, 5) Source(2, 5) + SourceIndex(0)
2 >Emitted(2, 12) Source(2, 12) + SourceIndex(0)
3 >Emitted(2, 13) Source(2, 13) + SourceIndex(0)
4 >Emitted(2, 14) Source(2, 14) + SourceIndex(0)
5 >Emitted(2, 16) Source(2, 16) + SourceIndex(0)
4 >Emitted(2, 16) Source(2, 16) + SourceIndex(0)
---
>>> a: number;
1->^^^^^^^^
@@ -95,7 +95,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
class C2 {
f() {
return __asyncGenerator(this, arguments, function* f_1() {
const x = yield;
const x = yield yield __await(void 0);
});
}
}
@@ -115,7 +115,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
class C3 {
f() {
return __asyncGenerator(this, arguments, function* f_1() {
const x = yield 1;
const x = yield yield __await(1);
});
}
}
@@ -175,7 +175,7 @@ var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
class C5 {
f() {
return __asyncGenerator(this, arguments, function* f_1() {
const x = yield __await(yield* __asyncDelegator(__asyncValues((function () { return __asyncGenerator(this, arguments, function* () { yield 1; }); })())));
const x = yield __await(yield* __asyncDelegator(__asyncValues((function () { return __asyncGenerator(this, arguments, function* () { yield yield __await(1); }); })())));
});
}
}
@@ -160,8 +160,9 @@ var C2 = /** @class */ (function () {
var x;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/];
case 1:
case 0: return [4 /*yield*/, __await(void 0)];
case 1: return [4 /*yield*/, _a.sent()];
case 2:
x = _a.sent();
return [2 /*return*/];
}
@@ -218,8 +219,9 @@ var C3 = /** @class */ (function () {
var x;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, 1];
case 1:
case 0: return [4 /*yield*/, __await(1)];
case 1: return [4 /*yield*/, _a.sent()];
case 2:
x = _a.sent();
return [2 /*return*/];
}
@@ -377,8 +379,9 @@ var C5 = /** @class */ (function () {
switch (_a.label) {
case 0: return [5 /*yield**/, __values(__asyncDelegator(__asyncValues((function () { return __asyncGenerator(this, arguments, function () { return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, 1];
case 1:
case 0: return [4 /*yield*/, __await(1)];
case 1: return [4 /*yield*/, _a.sent()];
case 2:
_a.sent();
return [2 /*return*/];
}
@@ -61,7 +61,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
};
function f2() {
return __asyncGenerator(this, arguments, function* f2_1() {
const x = yield;
const x = yield yield __await(void 0);
});
}
//// [F3.js]
@@ -79,7 +79,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
};
function f3() {
return __asyncGenerator(this, arguments, function* f3_1() {
const x = yield 1;
const x = yield yield __await(1);
});
}
//// [F4.js]
@@ -135,7 +135,7 @@ var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
};
function f5() {
return __asyncGenerator(this, arguments, function* f5_1() {
const x = yield __await(yield* __asyncDelegator(__asyncValues((function () { return __asyncGenerator(this, arguments, function* () { yield 1; }); })())));
const x = yield __await(yield* __asyncDelegator(__asyncValues((function () { return __asyncGenerator(this, arguments, function* () { yield yield __await(1); }); })())));
});
}
//// [F6.js]
@@ -121,8 +121,9 @@ function f2() {
var x;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/];
case 1:
case 0: return [4 /*yield*/, __await(void 0)];
case 1: return [4 /*yield*/, _a.sent()];
case 2:
x = _a.sent();
return [2 /*return*/];
}
@@ -174,8 +175,9 @@ function f3() {
var x;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, 1];
case 1:
case 0: return [4 /*yield*/, __await(1)];
case 1: return [4 /*yield*/, _a.sent()];
case 2:
x = _a.sent();
return [2 /*return*/];
}
@@ -323,8 +325,9 @@ function f5() {
switch (_a.label) {
case 0: return [5 /*yield**/, __values(__asyncDelegator(__asyncValues((function () { return __asyncGenerator(this, arguments, function () { return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, 1];
case 1:
case 0: return [4 /*yield*/, __await(1)];
case 1: return [4 /*yield*/, _a.sent()];
case 2:
_a.sent();
return [2 /*return*/];
}
@@ -61,7 +61,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
};
const f2 = function () {
return __asyncGenerator(this, arguments, function* () {
const x = yield;
const x = yield yield __await(void 0);
});
};
//// [F3.js]
@@ -79,7 +79,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
};
const f3 = function () {
return __asyncGenerator(this, arguments, function* () {
const x = yield 1;
const x = yield yield __await(1);
});
};
//// [F4.js]
@@ -135,7 +135,7 @@ var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
};
const f5 = function () {
return __asyncGenerator(this, arguments, function* () {
const x = yield __await(yield* __asyncDelegator(__asyncValues((function () { return __asyncGenerator(this, arguments, function* () { yield 1; }); })())));
const x = yield __await(yield* __asyncDelegator(__asyncValues((function () { return __asyncGenerator(this, arguments, function* () { yield yield __await(1); }); })())));
});
};
//// [F6.js]
@@ -121,8 +121,9 @@ var f2 = function () {
var x;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/];
case 1:
case 0: return [4 /*yield*/, __await(void 0)];
case 1: return [4 /*yield*/, _a.sent()];
case 2:
x = _a.sent();
return [2 /*return*/];
}
@@ -174,8 +175,9 @@ var f3 = function () {
var x;
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, 1];
case 1:
case 0: return [4 /*yield*/, __await(1)];
case 1: return [4 /*yield*/, _a.sent()];
case 2:
x = _a.sent();
return [2 /*return*/];
}
@@ -323,8 +325,9 @@ var f5 = function () {
switch (_a.label) {
case 0: return [5 /*yield**/, __values(__asyncDelegator(__asyncValues((function () { return __asyncGenerator(this, arguments, function () { return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, 1];
case 1:
case 0: return [4 /*yield*/, __await(1)];
case 1: return [4 /*yield*/, _a.sent()];
case 2:
_a.sent();
return [2 /*return*/];
}
@@ -78,7 +78,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
const o2 = {
f() {
return __asyncGenerator(this, arguments, function* f_1() {
const x = yield;
const x = yield yield __await(void 0);
});
}
};
@@ -98,7 +98,7 @@ var __asyncGenerator = (this && this.__asyncGenerator) || function (thisArg, _ar
const o3 = {
f() {
return __asyncGenerator(this, arguments, function* f_1() {
const x = yield 1;
const x = yield yield __await(1);
});
}
};
@@ -158,7 +158,7 @@ var __asyncDelegator = (this && this.__asyncDelegator) || function (o) {
const o5 = {
f() {
return __asyncGenerator(this, arguments, function* f_1() {
const x = yield __await(yield* __asyncDelegator(__asyncValues((function () { return __asyncGenerator(this, arguments, function* () { yield 1; }); })())));
const x = yield __await(yield* __asyncDelegator(__asyncValues((function () { return __asyncGenerator(this, arguments, function* () { yield yield __await(1); }); })())));
});
}
};

Some files were not shown because too many files have changed in this diff Show More