mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into sourceMapGenerator
This commit is contained in:
+68
-12
@@ -2112,7 +2112,7 @@ namespace ts {
|
||||
// Nothing to do
|
||||
break;
|
||||
default:
|
||||
Debug.fail("Unknown special property assignment kind");
|
||||
Debug.fail("Unknown binary expression special property assignment kind");
|
||||
}
|
||||
return checkStrictModeBinaryExpression(<BinaryExpression>node);
|
||||
case SyntaxKind.CatchClause:
|
||||
@@ -2188,6 +2188,19 @@ namespace ts {
|
||||
return bindFunctionExpression(<FunctionExpression>node);
|
||||
|
||||
case SyntaxKind.CallExpression:
|
||||
const assignmentKind = getAssignmentDeclarationKind(node as CallExpression);
|
||||
switch (assignmentKind) {
|
||||
case AssignmentDeclarationKind.ObjectDefinePropertyValue:
|
||||
return bindObjectDefinePropertyAssignment(node as BindableObjectDefinePropertyCall);
|
||||
case AssignmentDeclarationKind.ObjectDefinePropertyExports:
|
||||
return bindObjectDefinePropertyExport(node as BindableObjectDefinePropertyCall);
|
||||
case AssignmentDeclarationKind.ObjectDefinePrototypeProperty:
|
||||
return bindObjectDefinePrototypeProperty(node as BindableObjectDefinePropertyCall);
|
||||
case AssignmentDeclarationKind.None:
|
||||
break; // Nothing to do
|
||||
default:
|
||||
return Debug.fail("Unknown call expression assignment declaration kind");
|
||||
}
|
||||
if (isInJSFile(node)) {
|
||||
bindCallExpression(<CallExpression>node);
|
||||
}
|
||||
@@ -2351,6 +2364,22 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
function bindObjectDefinePropertyExport(node: BindableObjectDefinePropertyCall) {
|
||||
if (!setCommonJsModuleIndicator(node)) {
|
||||
return;
|
||||
}
|
||||
const symbol = forEachIdentifierInEntityName(node.arguments[0], /*parent*/ undefined, (id, symbol) => {
|
||||
if (symbol) {
|
||||
addDeclarationToSymbol(symbol, id, SymbolFlags.Module | SymbolFlags.Assignment);
|
||||
}
|
||||
return symbol;
|
||||
});
|
||||
if (symbol) {
|
||||
const flags = SymbolFlags.Property | SymbolFlags.ExportValue;
|
||||
declareSymbol(symbol.exports!, symbol, node, flags, SymbolFlags.None);
|
||||
}
|
||||
}
|
||||
|
||||
function bindExportsPropertyAssignment(node: BinaryExpression) {
|
||||
// When we create a property via 'exports.foo = bar', the 'exports.foo' property access
|
||||
// expression is the declaration
|
||||
@@ -2389,7 +2418,7 @@ namespace ts {
|
||||
const flags = exportAssignmentIsAlias(node)
|
||||
? SymbolFlags.Alias // An export= with an EntityNameExpression or a ClassExpression exports all meanings of that identifier or class
|
||||
: SymbolFlags.Property | SymbolFlags.ExportValue | SymbolFlags.ValueModule;
|
||||
declareSymbol(file.symbol.exports!, file.symbol, node, flags, SymbolFlags.None);
|
||||
declareSymbol(file.symbol.exports!, file.symbol, node, flags | SymbolFlags.Assignment, SymbolFlags.None);
|
||||
}
|
||||
|
||||
function bindThisPropertyAssignment(node: BinaryExpression | PropertyAccessExpression) {
|
||||
@@ -2458,6 +2487,11 @@ namespace ts {
|
||||
bindPropertyAssignment(lhs.expression, lhs, /*isPrototypeProperty*/ false);
|
||||
}
|
||||
|
||||
function bindObjectDefinePrototypeProperty(node: BindableObjectDefinePropertyCall) {
|
||||
const namespaceSymbol = lookupSymbolForPropertyAccess((node.arguments[0] as PropertyAccessExpression).expression as EntityNameExpression);
|
||||
bindPotentiallyNewExpandoMemberToNamespace(node, namespaceSymbol, /*isPrototypeProperty*/ true);
|
||||
}
|
||||
|
||||
/**
|
||||
* For `x.prototype.y = z`, declare a member `y` on `x` if `x` is a function or class, or not declared.
|
||||
* Note that jsdoc preceding an ExpressionStatement like `x.prototype.y;` is also treated as a declaration.
|
||||
@@ -2476,6 +2510,12 @@ namespace ts {
|
||||
bindPropertyAssignment(constructorFunction, lhs, /*isPrototypeProperty*/ true);
|
||||
}
|
||||
|
||||
function bindObjectDefinePropertyAssignment(node: BindableObjectDefinePropertyCall) {
|
||||
let namespaceSymbol = lookupSymbolForPropertyAccess(node.arguments[0]);
|
||||
const isToplevel = node.parent.parent.kind === SyntaxKind.SourceFile;
|
||||
namespaceSymbol = bindPotentiallyMissingNamespaces(namespaceSymbol, node.arguments[0], isToplevel, /*isPrototypeProperty*/ false);
|
||||
bindPotentiallyNewExpandoMemberToNamespace(node, namespaceSymbol, /*isPrototypeProperty*/ false);
|
||||
}
|
||||
|
||||
function bindSpecialPropertyAssignment(node: BinaryExpression) {
|
||||
const lhs = node.left as PropertyAccessEntityNameExpression;
|
||||
@@ -2507,16 +2547,12 @@ namespace ts {
|
||||
bindPropertyAssignment(node.expression, node, /*isPrototypeProperty*/ false);
|
||||
}
|
||||
|
||||
function bindPropertyAssignment(name: EntityNameExpression, propertyAccess: PropertyAccessEntityNameExpression, isPrototypeProperty: boolean) {
|
||||
let namespaceSymbol = lookupSymbolForPropertyAccess(name);
|
||||
const isToplevel = isBinaryExpression(propertyAccess.parent)
|
||||
? getParentOfBinaryExpression(propertyAccess.parent).parent.kind === SyntaxKind.SourceFile
|
||||
: propertyAccess.parent.parent.kind === SyntaxKind.SourceFile;
|
||||
function bindPotentiallyMissingNamespaces(namespaceSymbol: Symbol | undefined, entityName: EntityNameExpression, isToplevel: boolean, isPrototypeProperty: boolean) {
|
||||
if (isToplevel && !isPrototypeProperty && (!namespaceSymbol || !(namespaceSymbol.flags & SymbolFlags.Namespace))) {
|
||||
// make symbols or add declarations for intermediate containers
|
||||
const flags = SymbolFlags.Module | SymbolFlags.Assignment;
|
||||
const excludeFlags = SymbolFlags.ValueModuleExcludes & ~SymbolFlags.Assignment;
|
||||
namespaceSymbol = forEachIdentifierInEntityName(propertyAccess.expression, namespaceSymbol, (id, symbol, parent) => {
|
||||
namespaceSymbol = forEachIdentifierInEntityName(entityName, namespaceSymbol, (id, symbol, parent) => {
|
||||
if (symbol) {
|
||||
addDeclarationToSymbol(symbol, id, flags);
|
||||
return symbol;
|
||||
@@ -2528,6 +2564,10 @@ namespace ts {
|
||||
}
|
||||
});
|
||||
}
|
||||
return namespaceSymbol;
|
||||
}
|
||||
|
||||
function bindPotentiallyNewExpandoMemberToNamespace(declaration: PropertyAccessEntityNameExpression | CallExpression, namespaceSymbol: Symbol | undefined, isPrototypeProperty: boolean) {
|
||||
if (!namespaceSymbol || !isExpandoSymbol(namespaceSymbol)) {
|
||||
return;
|
||||
}
|
||||
@@ -2537,10 +2577,19 @@ namespace ts {
|
||||
(namespaceSymbol.members || (namespaceSymbol.members = createSymbolTable())) :
|
||||
(namespaceSymbol.exports || (namespaceSymbol.exports = createSymbolTable()));
|
||||
|
||||
const isMethod = isFunctionLikeDeclaration(getAssignedExpandoInitializer(propertyAccess)!);
|
||||
const isMethod = isFunctionLikeDeclaration(getAssignedExpandoInitializer(declaration)!);
|
||||
const includes = isMethod ? SymbolFlags.Method : SymbolFlags.Property;
|
||||
const excludes = isMethod ? SymbolFlags.MethodExcludes : SymbolFlags.PropertyExcludes;
|
||||
declareSymbol(symbolTable, namespaceSymbol, propertyAccess, includes | SymbolFlags.Assignment, excludes & ~SymbolFlags.Assignment);
|
||||
declareSymbol(symbolTable, namespaceSymbol, declaration, includes | SymbolFlags.Assignment, excludes & ~SymbolFlags.Assignment);
|
||||
}
|
||||
|
||||
function bindPropertyAssignment(name: EntityNameExpression, propertyAccess: PropertyAccessEntityNameExpression, isPrototypeProperty: boolean) {
|
||||
let namespaceSymbol = lookupSymbolForPropertyAccess(name);
|
||||
const isToplevel = isBinaryExpression(propertyAccess.parent)
|
||||
? getParentOfBinaryExpression(propertyAccess.parent).parent.kind === SyntaxKind.SourceFile
|
||||
: propertyAccess.parent.parent.kind === SyntaxKind.SourceFile;
|
||||
namespaceSymbol = bindPotentiallyMissingNamespaces(namespaceSymbol, propertyAccess.expression, isToplevel, isPrototypeProperty);
|
||||
bindPotentiallyNewExpandoMemberToNamespace(propertyAccess, namespaceSymbol, isPrototypeProperty);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2558,6 +2607,9 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
const node = symbol.valueDeclaration;
|
||||
if (isCallExpression(node)) {
|
||||
return !!getAssignedExpandoInitializer(node);
|
||||
}
|
||||
let init = !node ? undefined :
|
||||
isVariableDeclaration(node) ? node.initializer :
|
||||
isBinaryExpression(node) ? node.right :
|
||||
@@ -2869,7 +2921,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isExportsOrModuleExportsOrAlias(sourceFile: SourceFile, node: Expression): boolean {
|
||||
return isExportsIdentifier(node) ||
|
||||
isModuleExportsPropertyAccessExpression(node) ||
|
||||
@@ -3650,6 +3701,10 @@ namespace ts {
|
||||
}
|
||||
break;
|
||||
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
transformFlags |= TransformFlags.AssertESNext;
|
||||
break;
|
||||
|
||||
case SyntaxKind.ForOfStatement:
|
||||
// This node is either ES2015 syntax or ES2017 syntax (if it is a for-await-of).
|
||||
if ((<ForOfStatement>node).awaitModifier) {
|
||||
@@ -3666,6 +3721,7 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.BigIntKeyword:
|
||||
case SyntaxKind.NeverKeyword:
|
||||
case SyntaxKind.ObjectKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
@@ -3841,7 +3897,6 @@ namespace ts {
|
||||
* For performance reasons, `computeTransformFlagsForNode` uses local constant values rather
|
||||
* than calling this function.
|
||||
*/
|
||||
/* @internal */
|
||||
export function getTransformFlagsSubtreeExclusions(kind: SyntaxKind) {
|
||||
if (kind >= SyntaxKind.FirstTypeNode && kind <= SyntaxKind.LastTypeNode) {
|
||||
return TransformFlags.TypeExcludes;
|
||||
@@ -3874,6 +3929,7 @@ namespace ts {
|
||||
return TransformFlags.MethodOrAccessorExcludes;
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.BigIntKeyword:
|
||||
case SyntaxKind.NeverKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
case SyntaxKind.ObjectKeyword:
|
||||
|
||||
+37
-4
@@ -201,12 +201,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
Debug.assert(!!state.currentAffectedFilesExportedModulesMap);
|
||||
const seenFileAndExportsOfFile = createMap<true>();
|
||||
// Go through exported modules from cache first
|
||||
// If exported modules has path, all files referencing file exported from are affected
|
||||
if (forEachEntry(state.currentAffectedFilesExportedModulesMap!, (exportedModules, exportedFromPath) =>
|
||||
exportedModules &&
|
||||
exportedModules.has(affectedFile.path) &&
|
||||
removeSemanticDiagnosticsOfFilesReferencingPath(state, exportedFromPath as Path)
|
||||
removeSemanticDiagnosticsOfFilesReferencingPath(state, exportedFromPath as Path, seenFileAndExportsOfFile)
|
||||
)) {
|
||||
return;
|
||||
}
|
||||
@@ -215,7 +216,7 @@ namespace ts {
|
||||
forEachEntry(state.exportedModulesMap, (exportedModules, exportedFromPath) =>
|
||||
!state.currentAffectedFilesExportedModulesMap!.has(exportedFromPath) && // If we already iterated this through cache, ignore it
|
||||
exportedModules.has(affectedFile.path) &&
|
||||
removeSemanticDiagnosticsOfFilesReferencingPath(state, exportedFromPath as Path)
|
||||
removeSemanticDiagnosticsOfFilesReferencingPath(state, exportedFromPath as Path, seenFileAndExportsOfFile)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -223,9 +224,41 @@ namespace ts {
|
||||
* removes the semantic diagnostics of files referencing referencedPath and
|
||||
* returns true if there are no more semantic diagnostics from old state
|
||||
*/
|
||||
function removeSemanticDiagnosticsOfFilesReferencingPath(state: BuilderProgramState, referencedPath: Path) {
|
||||
function removeSemanticDiagnosticsOfFilesReferencingPath(state: BuilderProgramState, referencedPath: Path, seenFileAndExportsOfFile: Map<true>) {
|
||||
return forEachEntry(state.referencedMap!, (referencesInFile, filePath) =>
|
||||
referencesInFile.has(referencedPath) && removeSemanticDiagnosticsOf(state, filePath as Path)
|
||||
referencesInFile.has(referencedPath) && removeSemanticDiagnosticsOfFileAndExportsOfFile(state, filePath as Path, seenFileAndExportsOfFile)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes semantic diagnostics of file and anything that exports this file
|
||||
*/
|
||||
function removeSemanticDiagnosticsOfFileAndExportsOfFile(state: BuilderProgramState, filePath: Path, seenFileAndExportsOfFile: Map<true>): boolean {
|
||||
if (!addToSeen(seenFileAndExportsOfFile, filePath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (removeSemanticDiagnosticsOf(state, filePath)) {
|
||||
// If there are no more diagnostics from old cache, done
|
||||
return true;
|
||||
}
|
||||
|
||||
Debug.assert(!!state.currentAffectedFilesExportedModulesMap);
|
||||
// Go through exported modules from cache first
|
||||
// If exported modules has path, all files referencing file exported from are affected
|
||||
if (forEachEntry(state.currentAffectedFilesExportedModulesMap!, (exportedModules, exportedFromPath) =>
|
||||
exportedModules &&
|
||||
exportedModules.has(filePath) &&
|
||||
removeSemanticDiagnosticsOfFileAndExportsOfFile(state, exportedFromPath as Path, seenFileAndExportsOfFile)
|
||||
)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If exported from path is not from cache and exported modules has path, all files referencing file exported from are affected
|
||||
return !!forEachEntry(state.exportedModulesMap!, (exportedModules, exportedFromPath) =>
|
||||
!state.currentAffectedFilesExportedModulesMap!.has(exportedFromPath) && // If we already iterated this through cache, ignore it
|
||||
exportedModules.has(filePath) &&
|
||||
removeSemanticDiagnosticsOfFileAndExportsOfFile(state, exportedFromPath as Path, seenFileAndExportsOfFile)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -148,8 +148,39 @@ namespace ts.BuilderState {
|
||||
});
|
||||
}
|
||||
|
||||
// Add module augmentation as references
|
||||
if (sourceFile.moduleAugmentations.length) {
|
||||
const checker = program.getTypeChecker();
|
||||
for (const moduleName of sourceFile.moduleAugmentations) {
|
||||
if (!isStringLiteral(moduleName)) { continue; }
|
||||
const symbol = checker.getSymbolAtLocation(moduleName);
|
||||
if (!symbol) { continue; }
|
||||
|
||||
// Add any file other than our own as reference
|
||||
addReferenceFromAmbientModule(symbol);
|
||||
}
|
||||
}
|
||||
|
||||
// From ambient modules
|
||||
for (const ambientModule of program.getTypeChecker().getAmbientModules()) {
|
||||
if (ambientModule.declarations.length > 1) {
|
||||
addReferenceFromAmbientModule(ambientModule);
|
||||
}
|
||||
}
|
||||
|
||||
return referencedFiles;
|
||||
|
||||
function addReferenceFromAmbientModule(symbol: Symbol) {
|
||||
// Add any file other than our own as reference
|
||||
for (const declaration of symbol.declarations) {
|
||||
const declarationSourceFile = getSourceFileOfNode(declaration);
|
||||
if (declarationSourceFile &&
|
||||
declarationSourceFile !== sourceFile) {
|
||||
addReferencedFile(declarationSourceFile.resolvedPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addReferencedFile(referencedPath: Path) {
|
||||
if (!referencedFiles) {
|
||||
referencedFiles = createMap<true>();
|
||||
@@ -261,6 +292,11 @@ namespace ts.BuilderState {
|
||||
let latestSignature: string;
|
||||
if (sourceFile.isDeclarationFile) {
|
||||
latestSignature = sourceFile.version;
|
||||
if (exportedModulesMapCache && latestSignature !== prevSignature) {
|
||||
// All the references in this file are exported
|
||||
const references = state.referencedMap ? state.referencedMap.get(sourceFile.path) : undefined;
|
||||
exportedModulesMapCache.set(sourceFile.path, references || false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const emitOutput = getFileEmitOutput(programOfThisState, sourceFile, /*emitOnlyDtsFiles*/ true, cancellationToken);
|
||||
|
||||
+1239
-1088
File diff suppressed because it is too large
Load Diff
@@ -44,7 +44,8 @@ namespace ts {
|
||||
["esnext.array", "lib.esnext.array.d.ts"],
|
||||
["esnext.symbol", "lib.esnext.symbol.d.ts"],
|
||||
["esnext.asynciterable", "lib.esnext.asynciterable.d.ts"],
|
||||
["esnext.intl", "lib.esnext.intl.d.ts"]
|
||||
["esnext.intl", "lib.esnext.intl.d.ts"],
|
||||
["esnext.bigint", "lib.esnext.bigint.d.ts"]
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -104,6 +105,13 @@ namespace ts {
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Print_names_of_generated_files_part_of_the_compilation
|
||||
},
|
||||
{
|
||||
name: "pretty",
|
||||
type: "boolean",
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Command_line_Options,
|
||||
description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental
|
||||
},
|
||||
|
||||
{
|
||||
name: "traceResolution",
|
||||
@@ -158,11 +166,11 @@ namespace ts {
|
||||
description: Diagnostics.Build_one_or_more_projects_and_their_dependencies_if_out_of_date
|
||||
},
|
||||
{
|
||||
name: "pretty",
|
||||
name: "showConfig",
|
||||
type: "boolean",
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Command_line_Options,
|
||||
description: Diagnostics.Stylize_errors_and_messages_using_color_and_context_experimental
|
||||
isCommandLineOnly: true,
|
||||
description: Diagnostics.Print_the_final_configuration_instead_of_building
|
||||
},
|
||||
|
||||
// Basic
|
||||
@@ -576,6 +584,12 @@ namespace ts {
|
||||
category: Diagnostics.Experimental_Options,
|
||||
description: Diagnostics.Enables_experimental_support_for_emitting_type_metadata_for_decorators
|
||||
},
|
||||
{
|
||||
name: "experimentalBigInt",
|
||||
type: "boolean",
|
||||
category: Diagnostics.Experimental_Options,
|
||||
description: Diagnostics.Enables_experimental_support_for_ESNext_BigInt_literals
|
||||
},
|
||||
|
||||
// Advanced
|
||||
{
|
||||
@@ -1013,7 +1027,7 @@ namespace ts {
|
||||
i++;
|
||||
break;
|
||||
case "list":
|
||||
const result = parseListTypeOption(<CommandLineOptionOfListType>opt, args[i], errors);
|
||||
const result = parseListTypeOption(opt, args[i], errors);
|
||||
options[opt.name] = result || [];
|
||||
if (result) {
|
||||
i++;
|
||||
@@ -1146,7 +1160,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function printHelp(optionsList: CommandLineOption[], syntaxPrefix = "") {
|
||||
export function printHelp(optionsList: ReadonlyArray<CommandLineOption>, syntaxPrefix = "") {
|
||||
const output: string[] = [];
|
||||
|
||||
// We want to align our "syntax" and "examples" commands to a certain margin.
|
||||
@@ -1293,6 +1307,9 @@ namespace ts {
|
||||
|
||||
const result = parseJsonText(configFileName, configFileText);
|
||||
const cwd = host.getCurrentDirectory();
|
||||
result.path = toPath(configFileName, cwd, createGetCanonicalFileName(host.useCaseSensitiveFileNames));
|
||||
result.resolvedPath = result.path;
|
||||
result.originalFileName = result.fileName;
|
||||
return parseJsonSourceFileConfigFileContent(result, host, getNormalizedAbsolutePath(getDirectoryPath(configFileName), cwd), optionsToExtend, getNormalizedAbsolutePath(configFileName, cwd));
|
||||
}
|
||||
|
||||
@@ -1650,6 +1667,137 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an uncommented, complete tsconfig for use with "--showConfig"
|
||||
* @param configParseResult options to be generated into tsconfig.json
|
||||
* @param configFileName name of the parsed config file - output paths will be generated relative to this
|
||||
* @param host provides current directory and case sensitivity services
|
||||
*/
|
||||
/** @internal */
|
||||
export function convertToTSConfig(configParseResult: ParsedCommandLine, configFileName: string, host: { getCurrentDirectory(): string, useCaseSensitiveFileNames: boolean }): object {
|
||||
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames);
|
||||
const files = map(
|
||||
filter(
|
||||
configParseResult.fileNames,
|
||||
!configParseResult.configFileSpecs ? _ => false : matchesSpecs(
|
||||
configFileName,
|
||||
configParseResult.configFileSpecs.validatedIncludeSpecs,
|
||||
configParseResult.configFileSpecs.validatedExcludeSpecs
|
||||
)
|
||||
),
|
||||
f => getRelativePathFromFile(getNormalizedAbsolutePath(configFileName, host.getCurrentDirectory()), f, getCanonicalFileName)
|
||||
);
|
||||
const optionMap = serializeCompilerOptions(configParseResult.options, { configFilePath: getNormalizedAbsolutePath(configFileName, host.getCurrentDirectory()), useCaseSensitiveFileNames: host.useCaseSensitiveFileNames });
|
||||
const config = {
|
||||
compilerOptions: {
|
||||
...arrayFrom(optionMap.entries()).reduce((prev, cur) => ({ ...prev, [cur[0]]: cur[1] }), {}),
|
||||
showConfig: undefined,
|
||||
configFile: undefined,
|
||||
configFilePath: undefined,
|
||||
help: undefined,
|
||||
init: undefined,
|
||||
listFiles: undefined,
|
||||
listEmittedFiles: undefined,
|
||||
project: undefined,
|
||||
},
|
||||
references: map(configParseResult.projectReferences, r => ({ ...r, path: r.originalPath, originalPath: undefined })),
|
||||
files: length(files) ? files : undefined,
|
||||
...(configParseResult.configFileSpecs ? {
|
||||
include: filterSameAsDefaultInclude(configParseResult.configFileSpecs.validatedIncludeSpecs),
|
||||
exclude: configParseResult.configFileSpecs.validatedExcludeSpecs
|
||||
} : {}),
|
||||
compilerOnSave: !!configParseResult.compileOnSave ? true : undefined
|
||||
};
|
||||
return config;
|
||||
}
|
||||
|
||||
function filterSameAsDefaultInclude(specs: ReadonlyArray<string> | undefined) {
|
||||
if (!length(specs)) return undefined;
|
||||
if (length(specs) !== 1) return specs;
|
||||
if (specs![0] === "**/*") return undefined;
|
||||
return specs;
|
||||
}
|
||||
|
||||
function matchesSpecs(path: string, includeSpecs: ReadonlyArray<string> | undefined, excludeSpecs: ReadonlyArray<string> | undefined): (path: string) => boolean {
|
||||
if (!includeSpecs) return _ => false;
|
||||
const patterns = getFileMatcherPatterns(path, excludeSpecs, includeSpecs, sys.useCaseSensitiveFileNames, sys.getCurrentDirectory());
|
||||
const excludeRe = patterns.excludePattern && getRegexFromPattern(patterns.excludePattern, sys.useCaseSensitiveFileNames);
|
||||
const includeRe = patterns.includeFilePattern && getRegexFromPattern(patterns.includeFilePattern, sys.useCaseSensitiveFileNames);
|
||||
if (includeRe) {
|
||||
if (excludeRe) {
|
||||
return path => includeRe.test(path) && !excludeRe.test(path);
|
||||
}
|
||||
return path => includeRe.test(path);
|
||||
}
|
||||
if (excludeRe) {
|
||||
return path => !excludeRe.test(path);
|
||||
}
|
||||
return _ => false;
|
||||
}
|
||||
|
||||
function getCustomTypeMapOfCommandLineOption(optionDefinition: CommandLineOption): Map<string | number> | undefined {
|
||||
if (optionDefinition.type === "string" || optionDefinition.type === "number" || optionDefinition.type === "boolean") {
|
||||
// this is of a type CommandLineOptionOfPrimitiveType
|
||||
return undefined;
|
||||
}
|
||||
else if (optionDefinition.type === "list") {
|
||||
return getCustomTypeMapOfCommandLineOption(optionDefinition.element);
|
||||
}
|
||||
else {
|
||||
return (<CommandLineOptionOfCustomType>optionDefinition).type;
|
||||
}
|
||||
}
|
||||
|
||||
function getNameOfCompilerOptionValue(value: CompilerOptionsValue, customTypeMap: Map<string | number>): string | undefined {
|
||||
// There is a typeMap associated with this command-line option so use it to map value back to its name
|
||||
return forEachEntry(customTypeMap, (mapValue, key) => {
|
||||
if (mapValue === value) {
|
||||
return key;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function serializeCompilerOptions(options: CompilerOptions, pathOptions?: { configFilePath: string, useCaseSensitiveFileNames: boolean }): Map<CompilerOptionsValue> {
|
||||
const result = createMap<CompilerOptionsValue>();
|
||||
const optionsNameMap = getOptionNameMap().optionNameMap;
|
||||
const getCanonicalFileName = pathOptions && createGetCanonicalFileName(pathOptions.useCaseSensitiveFileNames);
|
||||
|
||||
for (const name in options) {
|
||||
if (hasProperty(options, name)) {
|
||||
// tsconfig only options cannot be specified via command line,
|
||||
// so we can assume that only types that can appear here string | number | boolean
|
||||
if (optionsNameMap.has(name) && optionsNameMap.get(name)!.category === Diagnostics.Command_line_Options) {
|
||||
continue;
|
||||
}
|
||||
const value = <CompilerOptionsValue>options[name];
|
||||
const optionDefinition = optionsNameMap.get(name.toLowerCase());
|
||||
if (optionDefinition) {
|
||||
const customTypeMap = getCustomTypeMapOfCommandLineOption(optionDefinition);
|
||||
if (!customTypeMap) {
|
||||
// There is no map associated with this compiler option then use the value as-is
|
||||
// This is the case if the value is expect to be string, number, boolean or list of string
|
||||
if (pathOptions && optionDefinition.isFilePath) {
|
||||
result.set(name, getRelativePathFromFile(pathOptions.configFilePath, getNormalizedAbsolutePath(value as string, getDirectoryPath(pathOptions.configFilePath)), getCanonicalFileName!));
|
||||
}
|
||||
else {
|
||||
result.set(name, value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (optionDefinition.type === "list") {
|
||||
result.set(name, (value as ReadonlyArray<string | number>).map(element => getNameOfCompilerOptionValue(element, customTypeMap)!)); // TODO: GH#18217
|
||||
}
|
||||
else {
|
||||
// There is a typeMap associated with this command-line option so use it to map value back to its name
|
||||
result.set(name, getNameOfCompilerOptionValue(value, customTypeMap));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate tsconfig configuration when running command line "--init"
|
||||
* @param options commandlineOptions to be generated into tsconfig.json
|
||||
@@ -1661,63 +1809,6 @@ namespace ts {
|
||||
const compilerOptionsMap = serializeCompilerOptions(compilerOptions);
|
||||
return writeConfigurations();
|
||||
|
||||
function getCustomTypeMapOfCommandLineOption(optionDefinition: CommandLineOption): Map<string | number> | undefined {
|
||||
if (optionDefinition.type === "string" || optionDefinition.type === "number" || optionDefinition.type === "boolean") {
|
||||
// this is of a type CommandLineOptionOfPrimitiveType
|
||||
return undefined;
|
||||
}
|
||||
else if (optionDefinition.type === "list") {
|
||||
return getCustomTypeMapOfCommandLineOption((<CommandLineOptionOfListType>optionDefinition).element);
|
||||
}
|
||||
else {
|
||||
return (<CommandLineOptionOfCustomType>optionDefinition).type;
|
||||
}
|
||||
}
|
||||
|
||||
function getNameOfCompilerOptionValue(value: CompilerOptionsValue, customTypeMap: Map<string | number>): string | undefined {
|
||||
// There is a typeMap associated with this command-line option so use it to map value back to its name
|
||||
return forEachEntry(customTypeMap, (mapValue, key) => {
|
||||
if (mapValue === value) {
|
||||
return key;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function serializeCompilerOptions(options: CompilerOptions): Map<CompilerOptionsValue> {
|
||||
const result = createMap<CompilerOptionsValue>();
|
||||
const optionsNameMap = getOptionNameMap().optionNameMap;
|
||||
|
||||
for (const name in options) {
|
||||
if (hasProperty(options, name)) {
|
||||
// tsconfig only options cannot be specified via command line,
|
||||
// so we can assume that only types that can appear here string | number | boolean
|
||||
if (optionsNameMap.has(name) && optionsNameMap.get(name)!.category === Diagnostics.Command_line_Options) {
|
||||
continue;
|
||||
}
|
||||
const value = <CompilerOptionsValue>options[name];
|
||||
const optionDefinition = optionsNameMap.get(name.toLowerCase());
|
||||
if (optionDefinition) {
|
||||
const customTypeMap = getCustomTypeMapOfCommandLineOption(optionDefinition);
|
||||
if (!customTypeMap) {
|
||||
// There is no map associated with this compiler option then use the value as-is
|
||||
// This is the case if the value is expect to be string, number, boolean or list of string
|
||||
result.set(name, value);
|
||||
}
|
||||
else {
|
||||
if (optionDefinition.type === "list") {
|
||||
result.set(name, (value as ReadonlyArray<string | number>).map(element => getNameOfCompilerOptionValue(element, customTypeMap)!)); // TODO: GH#18217
|
||||
}
|
||||
else {
|
||||
// There is a typeMap associated with this command-line option so use it to map value back to its name
|
||||
result.set(name, getNameOfCompilerOptionValue(value, customTypeMap));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getDefaultValueForOption(option: CommandLineOption) {
|
||||
switch (option.type) {
|
||||
case "number":
|
||||
@@ -1731,7 +1822,7 @@ namespace ts {
|
||||
case "object":
|
||||
return {};
|
||||
default:
|
||||
return (option as CommandLineOptionOfCustomType).type.keys().next().value;
|
||||
return option.type.keys().next().value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2188,20 +2279,24 @@ namespace ts {
|
||||
errors: Push<Diagnostic>,
|
||||
createDiagnostic: (message: DiagnosticMessage, arg1?: string) => Diagnostic) {
|
||||
extendedConfig = normalizeSlashes(extendedConfig);
|
||||
// If the path isn't a rooted or relative path, don't try to resolve it (we reserve the right to special case module-id like paths in the future)
|
||||
if (!(isRootedDiskPath(extendedConfig) || startsWith(extendedConfig, "./") || startsWith(extendedConfig, "../"))) {
|
||||
errors.push(createDiagnostic(Diagnostics.A_path_in_an_extends_option_must_be_relative_or_rooted_but_0_is_not, extendedConfig));
|
||||
return undefined;
|
||||
}
|
||||
let extendedConfigPath = getNormalizedAbsolutePath(extendedConfig, basePath);
|
||||
if (!host.fileExists(extendedConfigPath) && !endsWith(extendedConfigPath, Extension.Json)) {
|
||||
extendedConfigPath = `${extendedConfigPath}.json`;
|
||||
if (!host.fileExists(extendedConfigPath)) {
|
||||
errors.push(createDiagnostic(Diagnostics.File_0_does_not_exist, extendedConfig));
|
||||
return undefined;
|
||||
if (isRootedDiskPath(extendedConfig) || startsWith(extendedConfig, "./") || startsWith(extendedConfig, "../")) {
|
||||
let extendedConfigPath = getNormalizedAbsolutePath(extendedConfig, basePath);
|
||||
if (!host.fileExists(extendedConfigPath) && !endsWith(extendedConfigPath, Extension.Json)) {
|
||||
extendedConfigPath = `${extendedConfigPath}.json`;
|
||||
if (!host.fileExists(extendedConfigPath)) {
|
||||
errors.push(createDiagnostic(Diagnostics.File_0_does_not_exist, extendedConfig));
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
return extendedConfigPath;
|
||||
}
|
||||
return extendedConfigPath;
|
||||
// If the path isn't a rooted or relative path, resolve like a module
|
||||
const resolved = nodeModuleNameResolver(extendedConfig, combinePaths(basePath, "tsconfig.json"), { moduleResolution: ModuleResolutionKind.NodeJs }, host, /*cache*/ undefined, /*projectRefs*/ undefined, /*lookupConfig*/ true);
|
||||
if (resolved.resolvedModule) {
|
||||
return resolved.resolvedModule.resolvedFileName;
|
||||
}
|
||||
errors.push(createDiagnostic(Diagnostics.File_0_does_not_exist, extendedConfig));
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function getExtendedConfig(
|
||||
@@ -2338,7 +2433,7 @@ namespace ts {
|
||||
function normalizeOptionValue(option: CommandLineOption, basePath: string, value: any): CompilerOptionsValue {
|
||||
if (isNullOrUndefined(value)) return undefined;
|
||||
if (option.type === "list") {
|
||||
const listOption = <CommandLineOptionOfListType>option;
|
||||
const listOption = option;
|
||||
if (listOption.element.isFilePath || !isString(listOption.element.type)) {
|
||||
return <CompilerOptionsValue>filter(map(value, v => normalizeOptionValue(listOption.element, basePath, v)), v => !!v);
|
||||
}
|
||||
@@ -2509,11 +2604,16 @@ namespace ts {
|
||||
// via wildcard, and to handle extension priority.
|
||||
const wildcardFileMap = createMap<string>();
|
||||
|
||||
// Wildcard paths of json files (provided via the "includes" array in tsconfig.json) are stored in a
|
||||
// file map with a possibly case insensitive key. We use this map to store paths matched
|
||||
// via wildcard of *.json kind
|
||||
const wildCardJsonFileMap = createMap<string>();
|
||||
const { filesSpecs, validatedIncludeSpecs, validatedExcludeSpecs, wildcardDirectories } = spec;
|
||||
|
||||
// Rather than requery this for each file and filespec, we query the supported extensions
|
||||
// once and store it on the expansion context.
|
||||
const supportedExtensions = getSupportedExtensions(options, extraFileExtensions);
|
||||
const supportedExtensionsWithJsonIfResolveJsonModule = getSuppoertedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions);
|
||||
|
||||
// Literal files are always included verbatim. An "include" or "exclude" specification cannot
|
||||
// remove a literal file.
|
||||
@@ -2524,8 +2624,25 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
let jsonOnlyIncludeRegexes: ReadonlyArray<RegExp> | undefined;
|
||||
if (validatedIncludeSpecs && validatedIncludeSpecs.length > 0) {
|
||||
for (const file of host.readDirectory(basePath, supportedExtensions, validatedExcludeSpecs, validatedIncludeSpecs, /*depth*/ undefined)) {
|
||||
for (const file of host.readDirectory(basePath, supportedExtensionsWithJsonIfResolveJsonModule, validatedExcludeSpecs, validatedIncludeSpecs, /*depth*/ undefined)) {
|
||||
if (fileExtensionIs(file, Extension.Json)) {
|
||||
// Valid only if *.json specified
|
||||
if (!jsonOnlyIncludeRegexes) {
|
||||
const includes = validatedIncludeSpecs.filter(s => endsWith(s, Extension.Json));
|
||||
const includeFilePatterns = map(getRegularExpressionsForWildcards(includes, basePath, "files"), pattern => `^${pattern}$`);
|
||||
jsonOnlyIncludeRegexes = includeFilePatterns ? includeFilePatterns.map(pattern => getRegexFromPattern(pattern, host.useCaseSensitiveFileNames)) : emptyArray;
|
||||
}
|
||||
const includeIndex = findIndex(jsonOnlyIncludeRegexes, re => re.test(file));
|
||||
if (includeIndex !== -1) {
|
||||
const key = keyMapper(file);
|
||||
if (!literalFileMap.has(key) && !wildCardJsonFileMap.has(key)) {
|
||||
wildCardJsonFileMap.set(key, file);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// If we have already included a literal or wildcard path with a
|
||||
// higher priority extension, we should skip this file.
|
||||
//
|
||||
@@ -2553,7 +2670,7 @@ namespace ts {
|
||||
const wildcardFiles = arrayFrom(wildcardFileMap.values());
|
||||
|
||||
return {
|
||||
fileNames: literalFiles.concat(wildcardFiles),
|
||||
fileNames: literalFiles.concat(wildcardFiles, arrayFrom(wildCardJsonFileMap.values())),
|
||||
wildcardDirectories,
|
||||
spec
|
||||
};
|
||||
@@ -2723,7 +2840,7 @@ namespace ts {
|
||||
case "boolean":
|
||||
return typeof value === "boolean" ? value : "";
|
||||
case "list":
|
||||
const elementType = (option as CommandLineOptionOfListType).element;
|
||||
const elementType = option.element;
|
||||
return isArray(value) ? value.map(v => getOptionValueWithEmptyStrings(v, elementType)) : "";
|
||||
default:
|
||||
return forEachEntry(option.type, (optionEnumValue, optionStringValue) => {
|
||||
|
||||
+37
-16
@@ -16,6 +16,10 @@ namespace ts {
|
||||
[index: string]: T;
|
||||
}
|
||||
|
||||
export interface SortedReadonlyArray<T> extends ReadonlyArray<T> {
|
||||
" __sortedArrayBrand": any;
|
||||
}
|
||||
|
||||
export interface SortedArray<T> extends Array<T> {
|
||||
" __sortedArrayBrand": any;
|
||||
}
|
||||
@@ -511,12 +515,27 @@ namespace ts {
|
||||
* @param array The array to map.
|
||||
* @param mapfn The callback used to map the result into one or more values.
|
||||
*/
|
||||
export function flatMap<T, U>(array: ReadonlyArray<T>, mapfn: (x: T, i: number) => U | ReadonlyArray<U> | undefined): U[];
|
||||
export function flatMap<T, U>(array: ReadonlyArray<T> | undefined, mapfn: (x: T, i: number) => U | ReadonlyArray<U> | undefined): U[] | undefined;
|
||||
export function flatMap<T, U>(array: ReadonlyArray<T> | undefined, mapfn: (x: T, i: number) => U | ReadonlyArray<U> | undefined): U[] | undefined {
|
||||
export function flatMap<T, U>(array: ReadonlyArray<T> | undefined, mapfn: (x: T, i: number) => U | ReadonlyArray<U> | undefined): ReadonlyArray<U> {
|
||||
let result: U[] | undefined;
|
||||
if (array) {
|
||||
result = [];
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const v = mapfn(array[i], i);
|
||||
if (v) {
|
||||
if (isArray(v)) {
|
||||
result = addRange(result, v);
|
||||
}
|
||||
else {
|
||||
result = append(result, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result || emptyArray;
|
||||
}
|
||||
|
||||
export function flatMapToMutable<T, U>(array: ReadonlyArray<T> | undefined, mapfn: (x: T, i: number) => U | ReadonlyArray<U> | undefined): U[] {
|
||||
const result: U[] = [];
|
||||
if (array) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
const v = mapfn(array[i], i);
|
||||
if (v) {
|
||||
@@ -800,8 +819,8 @@ namespace ts {
|
||||
/**
|
||||
* Deduplicates an array that has already been sorted.
|
||||
*/
|
||||
function deduplicateSorted<T>(array: ReadonlyArray<T>, comparer: EqualityComparer<T> | Comparer<T>): T[] {
|
||||
if (array.length === 0) return [];
|
||||
function deduplicateSorted<T>(array: SortedReadonlyArray<T>, comparer: EqualityComparer<T> | Comparer<T>): SortedReadonlyArray<T> {
|
||||
if (array.length === 0) return emptyArray as any as SortedReadonlyArray<T>;
|
||||
|
||||
let last = array[0];
|
||||
const deduplicated: T[] = [last];
|
||||
@@ -823,7 +842,7 @@ namespace ts {
|
||||
deduplicated.push(last = next);
|
||||
}
|
||||
|
||||
return deduplicated;
|
||||
return deduplicated as any as SortedReadonlyArray<T>;
|
||||
}
|
||||
|
||||
export function insertSorted<T>(array: SortedArray<T>, insert: T, compare: Comparer<T>): void {
|
||||
@@ -838,8 +857,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function sortAndDeduplicate<T>(array: ReadonlyArray<T>, comparer: Comparer<T>, equalityComparer?: EqualityComparer<T>) {
|
||||
return deduplicateSorted(sort(array, comparer), equalityComparer || comparer);
|
||||
export function sortAndDeduplicate<T>(array: ReadonlyArray<string>): SortedReadonlyArray<string>;
|
||||
export function sortAndDeduplicate<T>(array: ReadonlyArray<T>, comparer: Comparer<T>, equalityComparer?: EqualityComparer<T>): SortedReadonlyArray<T>;
|
||||
export function sortAndDeduplicate<T>(array: ReadonlyArray<T>, comparer?: Comparer<T>, equalityComparer?: EqualityComparer<T>): SortedReadonlyArray<T> {
|
||||
return deduplicateSorted(sort(array, comparer), equalityComparer || comparer || compareStringsCaseSensitive as any as Comparer<T>);
|
||||
}
|
||||
|
||||
export function arrayIsEqualTo<T>(array1: ReadonlyArray<T> | undefined, array2: ReadonlyArray<T> | undefined, equalityComparer: (a: T, b: T, index: number) => boolean = equateValues): boolean {
|
||||
@@ -1020,8 +1041,8 @@ namespace ts {
|
||||
/**
|
||||
* Returns a new sorted array.
|
||||
*/
|
||||
export function sort<T>(array: ReadonlyArray<T>, comparer: Comparer<T>): T[] {
|
||||
return array.slice().sort(comparer);
|
||||
export function sort<T>(array: ReadonlyArray<T>, comparer?: Comparer<T>): SortedReadonlyArray<T> {
|
||||
return (array.length === 0 ? array : array.slice().sort(comparer)) as SortedReadonlyArray<T>;
|
||||
}
|
||||
|
||||
export function arrayIterator<T>(array: ReadonlyArray<T>): Iterator<T> {
|
||||
@@ -1615,8 +1636,9 @@ namespace ts {
|
||||
return value;
|
||||
}
|
||||
|
||||
export function assertNever(member: never, message?: string, stackCrawlMark?: AnyFunction): never {
|
||||
return fail(message || `Illegal value: ${member}`, stackCrawlMark || assertNever);
|
||||
export function assertNever(member: never, message = "Illegal value:", stackCrawlMark?: AnyFunction): never {
|
||||
const detail = "kind" in member && "pos" in member ? "SyntaxKind: " + showSyntaxKind(member as Node) : JSON.stringify(member);
|
||||
return fail(`${message} ${detail}`, stackCrawlMark || assertNever);
|
||||
}
|
||||
|
||||
export function getFunctionName(func: AnyFunction) {
|
||||
@@ -2043,7 +2065,6 @@ namespace ts {
|
||||
}
|
||||
|
||||
/** Represents a "prefix*suffix" pattern. */
|
||||
/* @internal */
|
||||
export interface Pattern {
|
||||
prefix: string;
|
||||
suffix: string;
|
||||
@@ -2198,7 +2219,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
private unsafeAdd(value: T, sortedAndUnique: boolean) {
|
||||
if (this.copyOnWrite) {
|
||||
if (this.copyOnWrite || this.unsafeArray === emptyArray) {
|
||||
this.unsafeArray = this.unsafeArray.slice();
|
||||
this.copyOnWrite = false;
|
||||
}
|
||||
@@ -2210,7 +2231,7 @@ namespace ts {
|
||||
|
||||
private ensureSortedAndUnique() {
|
||||
if (!this.sortedAndUnique) {
|
||||
this.unsafeArray = deduplicateSorted(stableSort(this.unsafeArray, this.relationalComparer), this.equalityComparer);
|
||||
this.unsafeArray = deduplicateSorted(stableSort(this.unsafeArray, this.relationalComparer) as any as SortedReadonlyArray<T>, this.equalityComparer) as any as T[];
|
||||
this.unsafeLast = undefined;
|
||||
this.sortedAndUnique = true;
|
||||
}
|
||||
|
||||
@@ -1007,6 +1007,14 @@
|
||||
"category": "Error",
|
||||
"code": 1349
|
||||
},
|
||||
"Print the final configuration instead of building.": {
|
||||
"category": "Message",
|
||||
"code": 1350
|
||||
},
|
||||
"Experimental support for BigInt is a feature that is subject to change in a future release. Set the 'experimentalBigInt' option to remove this warning.": {
|
||||
"category": "Error",
|
||||
"code": 1351
|
||||
},
|
||||
|
||||
"Duplicate identifier '{0}'.": {
|
||||
"category": "Error",
|
||||
@@ -1232,7 +1240,7 @@
|
||||
"category": "Error",
|
||||
"code": 2355
|
||||
},
|
||||
"An arithmetic operand must be of type 'any', 'number' or an enum type.": {
|
||||
"An arithmetic operand must be of type 'any', 'number', 'bigint' or an enum type.": {
|
||||
"category": "Error",
|
||||
"code": 2356
|
||||
},
|
||||
@@ -1256,11 +1264,11 @@
|
||||
"category": "Error",
|
||||
"code": 2361
|
||||
},
|
||||
"The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.": {
|
||||
"The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.": {
|
||||
"category": "Error",
|
||||
"code": 2362
|
||||
},
|
||||
"The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type.": {
|
||||
"The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.": {
|
||||
"category": "Error",
|
||||
"code": 2363
|
||||
},
|
||||
@@ -2088,15 +2096,15 @@
|
||||
"category": "Error",
|
||||
"code": 2577
|
||||
},
|
||||
"Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i @types/node`.": {
|
||||
"Cannot find name '{0}'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.": {
|
||||
"category": "Error",
|
||||
"code": 2580
|
||||
},
|
||||
"Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i @types/jquery`.": {
|
||||
"Cannot find name '{0}'. Do you need to install type definitions for jQuery? Try `npm i @types/jquery` and then add `jquery` to the types field in your tsconfig.": {
|
||||
"category": "Error",
|
||||
"code": 2581
|
||||
},
|
||||
"Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha`.": {
|
||||
"Cannot find name '{0}'. Do you need to install type definitions for a test runner? Try `npm i @types/jest` or `npm i @types/mocha` and then add `jest` or `mocha` to the types field in your tsconfig.": {
|
||||
"category": "Error",
|
||||
"code": 2582
|
||||
},
|
||||
@@ -2485,14 +2493,26 @@
|
||||
"category": "Error",
|
||||
"code": 2732
|
||||
},
|
||||
"Index '{0}' is out-of-bounds in tuple of length {1}.": {
|
||||
"category": "Error",
|
||||
"code": 2733
|
||||
},
|
||||
"It is highly likely that you are missing a semicolon.": {
|
||||
"category": "Error",
|
||||
"code": 2734
|
||||
},
|
||||
"Did you mean for '{0}' to be constrained to type 'new (...args: any[]) => {1}'?": {
|
||||
"category": "Error",
|
||||
"code": 2735
|
||||
},
|
||||
"Operator '{0}' cannot be applied to type '{1}'.": {
|
||||
"category": "Error",
|
||||
"code": 2736
|
||||
},
|
||||
"BigInt literals are not available when targetting lower than ESNext.": {
|
||||
"category": "Error",
|
||||
"code": 2737
|
||||
},
|
||||
"An outer value of 'this' is shadowed by this container.": {
|
||||
"category": "Message",
|
||||
"code": 2738
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
@@ -3767,6 +3787,18 @@
|
||||
"category": "Message",
|
||||
"code": 6214
|
||||
},
|
||||
"Using compiler options of project reference redirect '{0}'.": {
|
||||
"category": "Message",
|
||||
"code": 6215
|
||||
},
|
||||
"Found 1 error.": {
|
||||
"category": "Message",
|
||||
"code": 6216
|
||||
},
|
||||
"Found {0} errors.": {
|
||||
"category": "Message",
|
||||
"code": 6217
|
||||
},
|
||||
|
||||
"Projects to reference": {
|
||||
"category": "Message",
|
||||
@@ -3889,6 +3921,10 @@
|
||||
"category": "Error",
|
||||
"code": 6370
|
||||
},
|
||||
"Enables experimental support for ESNext BigInt literals.": {
|
||||
"category": "Message",
|
||||
"code": 6371
|
||||
},
|
||||
|
||||
"The expected type comes from property '{0}' which is declared here on type '{1}'": {
|
||||
"category": "Message",
|
||||
@@ -4041,6 +4077,39 @@
|
||||
"category": "Error",
|
||||
"code": 7042
|
||||
},
|
||||
"Variable '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage.": {
|
||||
"category": "Suggestion",
|
||||
"code": 7043
|
||||
},
|
||||
"Parameter '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage.": {
|
||||
"category": "Suggestion",
|
||||
"code": 7044
|
||||
},
|
||||
"Member '{0}' implicitly has an '{1}' type, but a better type may be inferred from usage.": {
|
||||
"category": "Suggestion",
|
||||
"code": 7045
|
||||
},
|
||||
"Variable '{0}' implicitly has type '{1}' in some locations, but a better type may be inferred from usage.": {
|
||||
"category": "Suggestion",
|
||||
"code": 7046
|
||||
},
|
||||
"Rest parameter '{0}' implicitly has an 'any[]' type, but a better type may be inferred from usage.": {
|
||||
"category": "Suggestion",
|
||||
"code": 7047
|
||||
},
|
||||
"Property '{0}' implicitly has type 'any', but a better type for its get accessor may be inferred from usage.": {
|
||||
"category": "Suggestion",
|
||||
"code": 7048
|
||||
},
|
||||
"Property '{0}' implicitly has type 'any', but a better type for its set accessor may be inferred from usage.": {
|
||||
"category": "Suggestion",
|
||||
"code": 7049
|
||||
},
|
||||
"'{0}' implicitly has an '{1}' return type, but a better type may be inferred from usage.": {
|
||||
"category": "Suggestion",
|
||||
"code": 7050
|
||||
},
|
||||
|
||||
"You cannot rename this element.": {
|
||||
"category": "Error",
|
||||
"code": 8000
|
||||
|
||||
+220
-22
@@ -42,20 +42,25 @@ namespace ts {
|
||||
export function getOutputPathsFor(sourceFile: SourceFile | Bundle, host: EmitHost, forceDtsPaths: boolean): EmitFileNames {
|
||||
const options = host.getCompilerOptions();
|
||||
if (sourceFile.kind === SyntaxKind.Bundle) {
|
||||
const jsFilePath = options.outFile || options.out!;
|
||||
const sourceMapFilePath = getSourceMapFilePath(jsFilePath, options);
|
||||
const declarationFilePath = (forceDtsPaths || getEmitDeclarations(options)) ? removeFileExtension(jsFilePath) + Extension.Dts : undefined;
|
||||
const declarationMapPath = getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
|
||||
const outPath = options.outFile || options.out!;
|
||||
const jsFilePath = options.emitDeclarationOnly ? undefined : outPath;
|
||||
const sourceMapFilePath = jsFilePath && getSourceMapFilePath(jsFilePath, options);
|
||||
const declarationFilePath = (forceDtsPaths || getEmitDeclarations(options)) ? removeFileExtension(outPath) + Extension.Dts : undefined;
|
||||
const declarationMapPath = declarationFilePath && getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
|
||||
const bundleInfoPath = options.references && jsFilePath ? (removeFileExtension(jsFilePath) + infoExtension) : undefined;
|
||||
return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, bundleInfoPath };
|
||||
}
|
||||
else {
|
||||
const jsFilePath = getOwnEmitOutputFilePath(sourceFile.fileName, host, getOutputExtension(sourceFile, options));
|
||||
const sourceMapFilePath = isJsonSourceFile(sourceFile) ? undefined : getSourceMapFilePath(jsFilePath, options);
|
||||
const ownOutputFilePath = getOwnEmitOutputFilePath(sourceFile.fileName, host, getOutputExtension(sourceFile, options));
|
||||
// If json file emits to the same location skip writing it, if emitDeclarationOnly skip writing it
|
||||
const isJsonEmittedToSameLocation = isJsonSourceFile(sourceFile) &&
|
||||
comparePaths(sourceFile.fileName, ownOutputFilePath, host.getCurrentDirectory(), !host.useCaseSensitiveFileNames()) === Comparison.EqualTo;
|
||||
const jsFilePath = options.emitDeclarationOnly || isJsonEmittedToSameLocation ? undefined : ownOutputFilePath;
|
||||
const sourceMapFilePath = !jsFilePath || isJsonSourceFile(sourceFile) ? undefined : getSourceMapFilePath(jsFilePath, options);
|
||||
// For legacy reasons (ie, we have baselines capturing the behavior), js files don't report a .d.ts output path - this would only matter if `declaration` and `allowJs` were both on, which is currently an error
|
||||
const isJs = isSourceFileJS(sourceFile);
|
||||
const declarationFilePath = ((forceDtsPaths || getEmitDeclarations(options)) && !isJs) ? getDeclarationEmitOutputFilePath(sourceFile.fileName, host) : undefined;
|
||||
const declarationMapPath = getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
|
||||
const declarationMapPath = declarationFilePath && getAreDeclarationMapsEnabled(options) ? declarationFilePath + ".map" : undefined;
|
||||
return { jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath, bundleInfoPath: undefined };
|
||||
}
|
||||
}
|
||||
@@ -128,27 +133,33 @@ namespace ts {
|
||||
|
||||
if (!emitSkipped && emittedFilesList) {
|
||||
if (!emitOnlyDtsFiles) {
|
||||
emittedFilesList.push(jsFilePath);
|
||||
}
|
||||
if (sourceMapFilePath) {
|
||||
emittedFilesList.push(sourceMapFilePath);
|
||||
if (jsFilePath) {
|
||||
emittedFilesList.push(jsFilePath);
|
||||
}
|
||||
if (sourceMapFilePath) {
|
||||
emittedFilesList.push(sourceMapFilePath);
|
||||
}
|
||||
if (bundleInfoPath) {
|
||||
emittedFilesList.push(bundleInfoPath);
|
||||
}
|
||||
}
|
||||
if (declarationFilePath) {
|
||||
emittedFilesList.push(declarationFilePath);
|
||||
}
|
||||
if (bundleInfoPath) {
|
||||
emittedFilesList.push(bundleInfoPath);
|
||||
if (declarationMapPath) {
|
||||
emittedFilesList.push(declarationMapPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function emitJsFileOrBundle(sourceFileOrBundle: SourceFile | Bundle, jsFilePath: string, sourceMapFilePath: string | undefined, 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;
|
||||
function emitJsFileOrBundle(sourceFileOrBundle: SourceFile | Bundle, jsFilePath: string | undefined, sourceMapFilePath: string | undefined, bundleInfoPath: string | undefined) {
|
||||
if (emitOnlyDtsFiles || !jsFilePath) {
|
||||
return;
|
||||
}
|
||||
if (emitOnlyDtsFiles) {
|
||||
|
||||
// Make sure not to write js file and source map file if any of them cannot be written
|
||||
if ((jsFilePath && host.isEmitBlocked(jsFilePath)) || compilerOptions.noEmit) {
|
||||
emitSkipped = true;
|
||||
return;
|
||||
}
|
||||
// Transform the source files
|
||||
@@ -955,7 +966,34 @@ namespace ts {
|
||||
case SyntaxKind.EnumMember:
|
||||
return emitEnumMember(<EnumMember>node);
|
||||
|
||||
// JSDoc nodes (ignored)
|
||||
// JSDoc nodes (only used in codefixes currently)
|
||||
case SyntaxKind.JSDocParameterTag:
|
||||
case SyntaxKind.JSDocPropertyTag:
|
||||
return emitJSDocPropertyLikeTag(node as JSDocPropertyLikeTag);
|
||||
case SyntaxKind.JSDocReturnTag:
|
||||
case SyntaxKind.JSDocTypeTag:
|
||||
case SyntaxKind.JSDocThisTag:
|
||||
case SyntaxKind.JSDocEnumTag:
|
||||
return emitJSDocSimpleTypedTag(node as JSDocTypeTag);
|
||||
case SyntaxKind.JSDocAugmentsTag:
|
||||
return emitJSDocAugmentsTag(node as JSDocAugmentsTag);
|
||||
case SyntaxKind.JSDocTemplateTag:
|
||||
return emitJSDocTemplateTag(node as JSDocTemplateTag);
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
return emitJSDocTypedefTag(node as JSDocTypedefTag);
|
||||
case SyntaxKind.JSDocCallbackTag:
|
||||
return emitJSDocCallbackTag(node as JSDocCallbackTag);
|
||||
case SyntaxKind.JSDocSignature:
|
||||
return emitJSDocSignature(node as JSDocSignature);
|
||||
case SyntaxKind.JSDocTypeLiteral:
|
||||
return emitJSDocTypeLiteral(node as JSDocTypeLiteral);
|
||||
case SyntaxKind.JSDocClassTag:
|
||||
case SyntaxKind.JSDocTag:
|
||||
return emitJSDocSimpleTag(node as JSDocTag);
|
||||
|
||||
case SyntaxKind.JSDocComment:
|
||||
return emitJSDoc(node as JSDoc);
|
||||
|
||||
// Transformation nodes (ignored)
|
||||
}
|
||||
|
||||
@@ -973,7 +1011,8 @@ namespace ts {
|
||||
switch (node.kind) {
|
||||
// Literals
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return emitNumericLiteral(<NumericLiteral>node);
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
return emitNumericOrBigIntLiteral(<NumericLiteral | BigIntLiteral>node);
|
||||
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.RegularExpressionLiteral:
|
||||
@@ -1137,7 +1176,8 @@ namespace ts {
|
||||
//
|
||||
|
||||
// SyntaxKind.NumericLiteral
|
||||
function emitNumericLiteral(node: NumericLiteral) {
|
||||
// SyntaxKind.BigIntLiteral
|
||||
function emitNumericOrBigIntLiteral(node: NumericLiteral | BigIntLiteral) {
|
||||
emitLiteral(node);
|
||||
}
|
||||
|
||||
@@ -2687,6 +2727,154 @@ namespace ts {
|
||||
emitInitializer(node.initializer, node.name.end, node);
|
||||
}
|
||||
|
||||
//
|
||||
// JSDoc
|
||||
//
|
||||
function emitJSDoc(node: JSDoc) {
|
||||
write("/**");
|
||||
if (node.comment) {
|
||||
const lines = node.comment.split(/\r\n?|\n/g);
|
||||
for (const line of lines) {
|
||||
writeLine();
|
||||
writeSpace();
|
||||
writePunctuation("*");
|
||||
writeSpace();
|
||||
write(line);
|
||||
}
|
||||
}
|
||||
if (node.tags) {
|
||||
if (node.tags.length === 1 && node.tags[0].kind === SyntaxKind.JSDocTypeTag && !node.comment) {
|
||||
writeSpace();
|
||||
emit(node.tags[0]);
|
||||
}
|
||||
else {
|
||||
emitList(node, node.tags, ListFormat.JSDocComment);
|
||||
}
|
||||
}
|
||||
writeSpace();
|
||||
write("*/");
|
||||
}
|
||||
|
||||
function emitJSDocSimpleTypedTag(tag: JSDocTypeTag | JSDocThisTag | JSDocEnumTag | JSDocReturnTag) {
|
||||
emitJSDocTagName(tag.tagName);
|
||||
emitJSDocTypeExpression(tag.typeExpression);
|
||||
emitJSDocComment(tag.comment);
|
||||
}
|
||||
|
||||
function emitJSDocAugmentsTag(tag: JSDocAugmentsTag) {
|
||||
emitJSDocTagName(tag.tagName);
|
||||
writeSpace();
|
||||
writePunctuation("{");
|
||||
emit(tag.class);
|
||||
writePunctuation("}");
|
||||
emitJSDocComment(tag.comment);
|
||||
}
|
||||
|
||||
function emitJSDocTemplateTag(tag: JSDocTemplateTag) {
|
||||
emitJSDocTagName(tag.tagName);
|
||||
emitJSDocTypeExpression(tag.constraint);
|
||||
writeSpace();
|
||||
emitList(tag, tag.typeParameters, ListFormat.CommaListElements);
|
||||
emitJSDocComment(tag.comment);
|
||||
}
|
||||
|
||||
function emitJSDocTypedefTag(tag: JSDocTypedefTag) {
|
||||
emitJSDocTagName(tag.tagName);
|
||||
if (tag.typeExpression) {
|
||||
if (tag.typeExpression.kind === SyntaxKind.JSDocTypeExpression) {
|
||||
emitJSDocTypeExpression(tag.typeExpression);
|
||||
}
|
||||
else {
|
||||
writeSpace();
|
||||
writePunctuation("{");
|
||||
write("Object");
|
||||
if (tag.typeExpression.isArrayType) {
|
||||
writePunctuation("[");
|
||||
writePunctuation("]");
|
||||
}
|
||||
writePunctuation("}");
|
||||
}
|
||||
}
|
||||
if (tag.fullName) {
|
||||
writeSpace();
|
||||
emit(tag.fullName);
|
||||
}
|
||||
emitJSDocComment(tag.comment);
|
||||
if (tag.typeExpression && tag.typeExpression.kind === SyntaxKind.JSDocTypeLiteral) {
|
||||
emitJSDocTypeLiteral(tag.typeExpression);
|
||||
}
|
||||
}
|
||||
|
||||
function emitJSDocCallbackTag(tag: JSDocCallbackTag) {
|
||||
emitJSDocTagName(tag.tagName);
|
||||
if (tag.name) {
|
||||
writeSpace();
|
||||
emit(tag.name);
|
||||
}
|
||||
emitJSDocComment(tag.comment);
|
||||
emitJSDocSignature(tag.typeExpression);
|
||||
}
|
||||
|
||||
function emitJSDocSimpleTag(tag: JSDocTag) {
|
||||
emitJSDocTagName(tag.tagName);
|
||||
emitJSDocComment(tag.comment);
|
||||
}
|
||||
|
||||
function emitJSDocTypeLiteral(lit: JSDocTypeLiteral) {
|
||||
emitList(lit, createNodeArray(lit.jsDocPropertyTags), ListFormat.JSDocComment);
|
||||
}
|
||||
|
||||
function emitJSDocSignature(sig: JSDocSignature) {
|
||||
if (sig.typeParameters) {
|
||||
emitList(sig, createNodeArray(sig.typeParameters), ListFormat.JSDocComment);
|
||||
}
|
||||
if (sig.parameters) {
|
||||
emitList(sig, createNodeArray(sig.parameters), ListFormat.JSDocComment);
|
||||
}
|
||||
if (sig.type) {
|
||||
writeLine();
|
||||
writeSpace();
|
||||
writePunctuation("*");
|
||||
writeSpace();
|
||||
emit(sig.type);
|
||||
}
|
||||
}
|
||||
|
||||
function emitJSDocPropertyLikeTag(param: JSDocPropertyLikeTag) {
|
||||
emitJSDocTagName(param.tagName);
|
||||
emitJSDocTypeExpression(param.typeExpression);
|
||||
writeSpace();
|
||||
if (param.isBracketed) {
|
||||
writePunctuation("[");
|
||||
}
|
||||
emit(param.name);
|
||||
if (param.isBracketed) {
|
||||
writePunctuation("]");
|
||||
}
|
||||
emitJSDocComment(param.comment);
|
||||
}
|
||||
|
||||
function emitJSDocTagName(tagName: Identifier) {
|
||||
writePunctuation("@");
|
||||
emit(tagName);
|
||||
}
|
||||
|
||||
function emitJSDocComment(comment: string | undefined) {
|
||||
if (comment) {
|
||||
writeSpace();
|
||||
write(comment);
|
||||
}
|
||||
}
|
||||
|
||||
function emitJSDocTypeExpression(typeExpression: JSDocTypeExpression | undefined) {
|
||||
if (typeExpression) {
|
||||
writeSpace();
|
||||
writePunctuation("{");
|
||||
emit(typeExpression.type);
|
||||
writePunctuation("}");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Top-level nodes
|
||||
//
|
||||
@@ -2984,6 +3172,11 @@ namespace ts {
|
||||
writeSpace();
|
||||
writePunctuation("|");
|
||||
break;
|
||||
case ListFormat.AsteriskDelimited:
|
||||
writeSpace();
|
||||
writePunctuation("*");
|
||||
writeSpace();
|
||||
break;
|
||||
case ListFormat.AmpersandDelimited:
|
||||
writeSpace();
|
||||
writePunctuation("&");
|
||||
@@ -3053,7 +3246,12 @@ namespace ts {
|
||||
const child = children![start + i];
|
||||
|
||||
// Write the delimiter if this is not the first node.
|
||||
if (previousSibling) {
|
||||
if (format & ListFormat.AsteriskDelimited) {
|
||||
// always write JSDoc in the format "\n *"
|
||||
writeLine();
|
||||
writeDelimiter(format);
|
||||
}
|
||||
else if (previousSibling) {
|
||||
// i.e
|
||||
// function commentedParameters(
|
||||
// /* Parameter a */
|
||||
|
||||
+63
-3
@@ -68,13 +68,16 @@ namespace ts {
|
||||
/* @internal */ export function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier, isSingleQuote: boolean): StringLiteral; // tslint:disable-line unified-signatures
|
||||
/** If a node is passed, creates a string literal whose source text is read from a source node during emit. */
|
||||
export function createLiteral(value: string | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier): StringLiteral;
|
||||
export function createLiteral(value: number): NumericLiteral;
|
||||
export function createLiteral(value: number | PseudoBigInt): NumericLiteral;
|
||||
export function createLiteral(value: boolean): BooleanLiteral;
|
||||
export function createLiteral(value: string | number | boolean): PrimaryExpression;
|
||||
export function createLiteral(value: string | number | boolean | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier, isSingleQuote?: boolean): PrimaryExpression {
|
||||
export function createLiteral(value: string | number | PseudoBigInt | boolean): PrimaryExpression;
|
||||
export function createLiteral(value: string | number | PseudoBigInt | boolean | StringLiteral | NoSubstitutionTemplateLiteral | NumericLiteral | Identifier, isSingleQuote?: boolean): PrimaryExpression {
|
||||
if (typeof value === "number") {
|
||||
return createNumericLiteral(value + "");
|
||||
}
|
||||
if (typeof value === "object" && "base10Value" in value) { // PseudoBigInt
|
||||
return createBigIntLiteral(pseudoBigIntToString(value) + "n");
|
||||
}
|
||||
if (typeof value === "boolean") {
|
||||
return value ? createTrue() : createFalse();
|
||||
}
|
||||
@@ -93,6 +96,12 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createBigIntLiteral(value: string): BigIntLiteral {
|
||||
const node = <BigIntLiteral>createSynthesizedNode(SyntaxKind.BigIntLiteral);
|
||||
node.text = value;
|
||||
return node;
|
||||
}
|
||||
|
||||
export function createStringLiteral(text: string): StringLiteral {
|
||||
const node = <StringLiteral>createSynthesizedNode(SyntaxKind.StringLiteral);
|
||||
node.text = text;
|
||||
@@ -2170,6 +2179,56 @@ namespace ts {
|
||||
: node;
|
||||
}
|
||||
|
||||
// JSDoc
|
||||
|
||||
/* @internal */
|
||||
export function createJSDocTypeExpression(type: TypeNode): JSDocTypeExpression {
|
||||
const node = createSynthesizedNode(SyntaxKind.JSDocTypeExpression) as JSDocTypeExpression;
|
||||
node.type = type;
|
||||
return node;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createJSDocTypeTag(typeExpression?: JSDocTypeExpression, comment?: string): JSDocTypeTag {
|
||||
const tag = createJSDocTag<JSDocTypeTag>(SyntaxKind.JSDocTypeTag, "type");
|
||||
tag.typeExpression = typeExpression;
|
||||
tag.comment = comment;
|
||||
return tag;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createJSDocReturnTag(typeExpression?: JSDocTypeExpression, comment?: string): JSDocReturnTag {
|
||||
const tag = createJSDocTag<JSDocReturnTag>(SyntaxKind.JSDocReturnTag, "returns");
|
||||
tag.typeExpression = typeExpression;
|
||||
tag.comment = comment;
|
||||
return tag;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createJSDocParamTag(name: EntityName, isBracketed: boolean, typeExpression?: JSDocTypeExpression, comment?: string): JSDocParameterTag {
|
||||
const tag = createJSDocTag<JSDocParameterTag>(SyntaxKind.JSDocParameterTag, "param");
|
||||
tag.typeExpression = typeExpression;
|
||||
tag.name = name;
|
||||
tag.isBracketed = isBracketed;
|
||||
tag.comment = comment;
|
||||
return tag;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createJSDocComment(comment?: string | undefined, tags?: NodeArray<JSDocTag> | undefined) {
|
||||
const node = createSynthesizedNode(SyntaxKind.JSDocComment) as JSDoc;
|
||||
node.comment = comment;
|
||||
node.tags = tags;
|
||||
return node;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
function createJSDocTag<T extends JSDocTag>(kind: T["kind"], tagName: string): T {
|
||||
const node = createSynthesizedNode(kind) as T;
|
||||
node.tagName = createIdentifier(tagName);
|
||||
return node;
|
||||
}
|
||||
|
||||
// JSX
|
||||
|
||||
export function createJsxElement(openingElement: JsxOpeningElement, children: ReadonlyArray<JsxChild>, closingElement: JsxClosingElement) {
|
||||
@@ -3416,6 +3475,7 @@ namespace ts {
|
||||
return cacheIdentifiers;
|
||||
case SyntaxKind.ThisKeyword:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
return false;
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
|
||||
@@ -62,6 +62,7 @@ namespace ts {
|
||||
TypeScript, /** '.ts', '.tsx', or '.d.ts' */
|
||||
JavaScript, /** '.js' or '.jsx' */
|
||||
Json, /** '.json' */
|
||||
TSConfig, /** '.json' with `tsconfig` used instead of `index` */
|
||||
DtsOnly /** Only '.d.ts' */
|
||||
}
|
||||
|
||||
@@ -98,6 +99,7 @@ namespace ts {
|
||||
types?: string;
|
||||
typesVersions?: MapLike<MapLike<string[]>>;
|
||||
main?: string;
|
||||
tsconfig?: string;
|
||||
}
|
||||
|
||||
interface PackageJson extends PackageJsonPathFields {
|
||||
@@ -126,7 +128,7 @@ namespace ts {
|
||||
return value;
|
||||
}
|
||||
|
||||
function readPackageJsonPathField<K extends "typings" | "types" | "main">(jsonContent: PackageJson, fieldName: K, baseDirectory: string, state: ModuleResolutionState): PackageJson[K] | undefined {
|
||||
function readPackageJsonPathField<K extends "typings" | "types" | "main" | "tsconfig">(jsonContent: PackageJson, fieldName: K, baseDirectory: string, state: ModuleResolutionState): PackageJson[K] | undefined {
|
||||
const fileName = readPackageJsonField(jsonContent, fieldName, "string", state);
|
||||
if (fileName === undefined) return;
|
||||
const path = normalizePath(combinePaths(baseDirectory, fileName));
|
||||
@@ -141,6 +143,10 @@ namespace ts {
|
||||
|| readPackageJsonPathField(jsonContent, "types", baseDirectory, state);
|
||||
}
|
||||
|
||||
function readPackageJsonTSConfigField(jsonContent: PackageJson, baseDirectory: string, state: ModuleResolutionState) {
|
||||
return readPackageJsonPathField(jsonContent, "tsconfig", baseDirectory, state);
|
||||
}
|
||||
|
||||
function readPackageJsonMainField(jsonContent: PackageJson, baseDirectory: string, state: ModuleResolutionState) {
|
||||
return readPackageJsonPathField(jsonContent, "main", baseDirectory, state);
|
||||
}
|
||||
@@ -258,8 +264,11 @@ namespace ts {
|
||||
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
|
||||
* is assumed to be the same as root directory of the project.
|
||||
*/
|
||||
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost): ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
|
||||
export function resolveTypeReferenceDirective(typeReferenceDirectiveName: string, containingFile: string | undefined, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference): ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
|
||||
const traceEnabled = isTraceEnabled(options, host);
|
||||
if (redirectedReference) {
|
||||
options = redirectedReference.commandLine.options;
|
||||
}
|
||||
const failedLookupLocations: string[] = [];
|
||||
const moduleResolutionState: ModuleResolutionState = { compilerOptions: options, host, traceEnabled, failedLookupLocations };
|
||||
|
||||
@@ -281,6 +290,9 @@ namespace ts {
|
||||
trace(host, Diagnostics.Resolving_type_reference_directive_0_containing_file_1_root_directory_2, typeReferenceDirectiveName, containingFile, typeRoots);
|
||||
}
|
||||
}
|
||||
if (redirectedReference) {
|
||||
trace(host, Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirectedReference.sourceFile.fileName);
|
||||
}
|
||||
}
|
||||
|
||||
let resolved = primaryLookup();
|
||||
@@ -292,14 +304,12 @@ namespace ts {
|
||||
|
||||
let resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective | undefined;
|
||||
if (resolved) {
|
||||
if (!options.preserveSymlinks) {
|
||||
resolved = { ...resolved, fileName: realPath(resolved.fileName, host, traceEnabled) };
|
||||
}
|
||||
|
||||
const { fileName, packageId } = resolved;
|
||||
const resolvedFileName = options.preserveSymlinks ? fileName : realPath(fileName, host, traceEnabled);
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolved.fileName, primary);
|
||||
trace(host, Diagnostics.Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2, typeReferenceDirectiveName, resolvedFileName, primary);
|
||||
}
|
||||
resolvedTypeReferenceDirective = { primary, resolvedFileName: resolved.fileName, packageId: resolved.packageId };
|
||||
resolvedTypeReferenceDirective = { primary, resolvedFileName, packageId, isExternalLibraryImport: pathContainsNodeModules(fileName) };
|
||||
}
|
||||
|
||||
return { resolvedTypeReferenceDirective, failedLookupLocations };
|
||||
@@ -310,7 +320,7 @@ namespace ts {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Resolving_with_primary_search_path_0, typeRoots.join(", "));
|
||||
}
|
||||
return forEach(typeRoots, typeRoot => {
|
||||
return firstDefined(typeRoots, typeRoot => {
|
||||
const candidate = combinePaths(typeRoot, typeReferenceDirectiveName);
|
||||
const candidateDirectory = getDirectoryPath(candidate);
|
||||
const directoryExists = directoryProbablyExists(candidateDirectory, host);
|
||||
@@ -337,15 +347,16 @@ namespace ts {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Looking_up_in_node_modules_folder_initial_location_0, initialLocationForSecondaryLookup);
|
||||
}
|
||||
let result: SearchResult<Resolved> | undefined;
|
||||
let result: Resolved | undefined;
|
||||
if (!isExternalModuleNameRelative(typeReferenceDirectiveName)) {
|
||||
result = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined);
|
||||
const searchResult = loadModuleFromNearestNodeModulesDirectory(Extensions.DtsOnly, typeReferenceDirectiveName, initialLocationForSecondaryLookup, moduleResolutionState, /*cache*/ undefined, /*redirectedReference*/ undefined);
|
||||
result = searchResult && searchResult.value;
|
||||
}
|
||||
else {
|
||||
const { path: candidate } = normalizePathAndParts(combinePaths(initialLocationForSecondaryLookup, typeReferenceDirectiveName));
|
||||
result = toSearchResult(nodeLoadModuleByRelativeName(Extensions.DtsOnly, candidate, /*onlyRecordFailures*/ false, moduleResolutionState, /*considerPackageJson*/ true));
|
||||
result = nodeLoadModuleByRelativeName(Extensions.DtsOnly, candidate, /*onlyRecordFailures*/ false, moduleResolutionState, /*considerPackageJson*/ true);
|
||||
}
|
||||
const resolvedFile = resolvedTypeScriptOnly(result && result.value);
|
||||
const resolvedFile = resolvedTypeScriptOnly(result);
|
||||
if (!resolvedFile && traceEnabled) {
|
||||
trace(host, Diagnostics.Type_reference_directive_0_was_not_resolved, typeReferenceDirectiveName);
|
||||
}
|
||||
@@ -409,7 +420,7 @@ namespace ts {
|
||||
* This assumes that any module id will have the same resolution for sibling files located in the same folder.
|
||||
*/
|
||||
export interface ModuleResolutionCache extends NonRelativeModuleNameResolutionCache {
|
||||
getOrCreateCacheForDirectory(directoryName: string): Map<ResolvedModuleWithFailedLookupLocations>;
|
||||
getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference): Map<ResolvedModuleWithFailedLookupLocations>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -417,7 +428,7 @@ namespace ts {
|
||||
* We support only non-relative module names because resolution of relative module names is usually more deterministic and thus less expensive.
|
||||
*/
|
||||
export interface NonRelativeModuleNameResolutionCache {
|
||||
getOrCreateCacheForModuleName(nonRelativeModuleName: string): PerModuleNameCache;
|
||||
getOrCreateCacheForModuleName(nonRelativeModuleName: string, redirectedReference?: ResolvedProjectReference): PerModuleNameCache;
|
||||
}
|
||||
|
||||
export interface PerModuleNameCache {
|
||||
@@ -427,40 +438,78 @@ namespace ts {
|
||||
|
||||
export function createModuleResolutionCache(currentDirectory: string, getCanonicalFileName: (s: string) => string): ModuleResolutionCache {
|
||||
return createModuleResolutionCacheWithMaps(
|
||||
createMap<Map<ResolvedModuleWithFailedLookupLocations>>(),
|
||||
createMap<PerModuleNameCache>(),
|
||||
createCacheWithRedirects(),
|
||||
createCacheWithRedirects(),
|
||||
currentDirectory,
|
||||
getCanonicalFileName
|
||||
);
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export interface CacheWithRedirects<T> {
|
||||
ownMap: Map<T>;
|
||||
redirectsMap: Map<Map<T>>;
|
||||
getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined): Map<T>;
|
||||
clear(): void;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function createCacheWithRedirects<T>(): CacheWithRedirects<T> {
|
||||
const ownMap: Map<T> = createMap();
|
||||
const redirectsMap: Map<Map<T>> = createMap();
|
||||
return {
|
||||
ownMap,
|
||||
redirectsMap,
|
||||
getOrCreateMapOfCacheRedirects,
|
||||
clear
|
||||
};
|
||||
|
||||
function getOrCreateMapOfCacheRedirects(redirectedReference: ResolvedProjectReference | undefined) {
|
||||
if (!redirectedReference) {
|
||||
return ownMap;
|
||||
}
|
||||
const path = redirectedReference.sourceFile.path;
|
||||
let redirects = redirectsMap.get(path);
|
||||
if (!redirects) {
|
||||
redirects = createMap();
|
||||
redirectsMap.set(path, redirects);
|
||||
}
|
||||
return redirects;
|
||||
}
|
||||
|
||||
function clear() {
|
||||
ownMap.clear();
|
||||
redirectsMap.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
export function createModuleResolutionCacheWithMaps(
|
||||
directoryToModuleNameMap: Map<Map<ResolvedModuleWithFailedLookupLocations>>,
|
||||
moduleNameToDirectoryMap: Map<PerModuleNameCache>,
|
||||
directoryToModuleNameMap: CacheWithRedirects<Map<ResolvedModuleWithFailedLookupLocations>>,
|
||||
moduleNameToDirectoryMap: CacheWithRedirects<PerModuleNameCache>,
|
||||
currentDirectory: string,
|
||||
getCanonicalFileName: GetCanonicalFileName): ModuleResolutionCache {
|
||||
|
||||
return { getOrCreateCacheForDirectory, getOrCreateCacheForModuleName };
|
||||
|
||||
function getOrCreateCacheForDirectory(directoryName: string) {
|
||||
function getOrCreateCacheForDirectory(directoryName: string, redirectedReference?: ResolvedProjectReference) {
|
||||
const path = toPath(directoryName, currentDirectory, getCanonicalFileName);
|
||||
let perFolderCache = directoryToModuleNameMap.get(path);
|
||||
if (!perFolderCache) {
|
||||
perFolderCache = createMap<ResolvedModuleWithFailedLookupLocations>();
|
||||
directoryToModuleNameMap.set(path, perFolderCache);
|
||||
}
|
||||
return perFolderCache;
|
||||
return getOrCreateCache<Map<ResolvedModuleWithFailedLookupLocations>>(directoryToModuleNameMap, redirectedReference, path, createMap);
|
||||
}
|
||||
|
||||
function getOrCreateCacheForModuleName(nonRelativeModuleName: string): PerModuleNameCache {
|
||||
function getOrCreateCacheForModuleName(nonRelativeModuleName: string, redirectedReference?: ResolvedProjectReference): PerModuleNameCache {
|
||||
Debug.assert(!isExternalModuleNameRelative(nonRelativeModuleName));
|
||||
let perModuleNameCache = moduleNameToDirectoryMap.get(nonRelativeModuleName);
|
||||
if (!perModuleNameCache) {
|
||||
perModuleNameCache = createPerModuleNameCache();
|
||||
moduleNameToDirectoryMap.set(nonRelativeModuleName, perModuleNameCache);
|
||||
return getOrCreateCache(moduleNameToDirectoryMap, redirectedReference, nonRelativeModuleName, createPerModuleNameCache);
|
||||
}
|
||||
|
||||
function getOrCreateCache<T>(cacheWithRedirects: CacheWithRedirects<T>, redirectedReference: ResolvedProjectReference | undefined, key: string, create: () => T): T {
|
||||
const cache = cacheWithRedirects.getOrCreateMapOfCacheRedirects(redirectedReference);
|
||||
let result = cache.get(key);
|
||||
if (!result) {
|
||||
result = create();
|
||||
cache.set(key, result);
|
||||
}
|
||||
return perModuleNameCache;
|
||||
return result;
|
||||
}
|
||||
|
||||
function createPerModuleNameCache(): PerModuleNameCache {
|
||||
@@ -542,13 +591,19 @@ namespace ts {
|
||||
return perFolderCache && perFolderCache.get(moduleName);
|
||||
}
|
||||
|
||||
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations {
|
||||
export function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations {
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
if (redirectedReference) {
|
||||
compilerOptions = redirectedReference.commandLine.options;
|
||||
}
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Resolving_module_0_from_1, moduleName, containingFile);
|
||||
if (redirectedReference) {
|
||||
trace(host, Diagnostics.Using_compiler_options_of_project_reference_redirect_0, redirectedReference.sourceFile.fileName);
|
||||
}
|
||||
}
|
||||
const containingDirectory = getDirectoryPath(containingFile);
|
||||
const perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory);
|
||||
const perFolderCache = cache && cache.getOrCreateCacheForDirectory(containingDirectory, redirectedReference);
|
||||
let result = perFolderCache && perFolderCache.get(moduleName);
|
||||
|
||||
if (result) {
|
||||
@@ -572,10 +627,10 @@ namespace ts {
|
||||
|
||||
switch (moduleResolution) {
|
||||
case ModuleResolutionKind.NodeJs:
|
||||
result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache);
|
||||
result = nodeModuleNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference);
|
||||
break;
|
||||
case ModuleResolutionKind.Classic:
|
||||
result = classicNameResolver(moduleName, containingFile, compilerOptions, host, cache);
|
||||
result = classicNameResolver(moduleName, containingFile, compilerOptions, host, cache, redirectedReference);
|
||||
break;
|
||||
default:
|
||||
return Debug.fail(`Unexpected moduleResolution: ${moduleResolution}`);
|
||||
@@ -585,7 +640,7 @@ namespace ts {
|
||||
perFolderCache.set(moduleName, result);
|
||||
if (!isExternalModuleNameRelative(moduleName)) {
|
||||
// put result in per-module name cache
|
||||
cache!.getOrCreateCacheForModuleName(moduleName).set(containingDirectory, result);
|
||||
cache!.getOrCreateCacheForModuleName(moduleName, redirectedReference).set(containingDirectory, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -675,6 +730,9 @@ namespace ts {
|
||||
function tryLoadModuleUsingOptionalResolutionSettings(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader,
|
||||
state: ModuleResolutionState): Resolved | undefined {
|
||||
|
||||
const resolved = tryLoadModuleUsingPathsIfEligible(extensions, moduleName, loader, state);
|
||||
if (resolved) return resolved.value;
|
||||
|
||||
if (!isExternalModuleNameRelative(moduleName)) {
|
||||
return tryLoadModuleUsingBaseUrl(extensions, moduleName, loader, state);
|
||||
}
|
||||
@@ -683,6 +741,17 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function tryLoadModuleUsingPathsIfEligible(extensions: Extensions, moduleName: string, loader: ResolutionKindSpecificLoader, state: ModuleResolutionState) {
|
||||
const { baseUrl, paths } = state.compilerOptions;
|
||||
if (baseUrl && paths && !pathIsRelative(moduleName)) {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, baseUrl, moduleName);
|
||||
trace(state.host, Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName);
|
||||
}
|
||||
return tryLoadModuleUsingPaths(extensions, moduleName, baseUrl, paths, loader, /*onlyRecordFailures*/ false, state);
|
||||
}
|
||||
}
|
||||
|
||||
function tryLoadModuleUsingRootDirs(extensions: Extensions, moduleName: string, containingDirectory: string, loader: ResolutionKindSpecificLoader,
|
||||
state: ModuleResolutionState): Resolved | undefined {
|
||||
|
||||
@@ -761,22 +830,13 @@ namespace ts {
|
||||
}
|
||||
|
||||
function tryLoadModuleUsingBaseUrl(extensions: Extensions, moduleName: string, loader: ResolutionKindSpecificLoader, state: ModuleResolutionState): Resolved | undefined {
|
||||
const { baseUrl, paths } = state.compilerOptions;
|
||||
const { baseUrl } = state.compilerOptions;
|
||||
if (!baseUrl) {
|
||||
return undefined;
|
||||
}
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.baseUrl_option_is_set_to_0_using_this_value_to_resolve_non_relative_module_name_1, baseUrl, moduleName);
|
||||
}
|
||||
if (paths) {
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.paths_option_is_specified_looking_for_a_pattern_to_match_module_name_0, moduleName);
|
||||
}
|
||||
const resolved = tryLoadModuleUsingPaths(extensions, moduleName, baseUrl, paths, loader, /*onlyRecordFailures*/ false, state);
|
||||
if (resolved) {
|
||||
return resolved.value;
|
||||
}
|
||||
}
|
||||
const candidate = normalizePath(combinePaths(baseUrl, moduleName));
|
||||
if (state.traceEnabled) {
|
||||
trace(state.host, Diagnostics.Resolving_module_name_0_relative_to_base_url_1_2, moduleName, baseUrl, candidate);
|
||||
@@ -804,25 +864,27 @@ namespace ts {
|
||||
return resolvedModule && resolvedModule.resolvedFileName;
|
||||
}
|
||||
|
||||
const jsOnlyExtensions = [Extensions.JavaScript];
|
||||
const tsExtensions = [Extensions.TypeScript, Extensions.JavaScript];
|
||||
const tsPlusJsonExtensions = [...tsExtensions, Extensions.Json];
|
||||
const tsconfigExtensions = [Extensions.TSConfig];
|
||||
function tryResolveJSModuleWorker(moduleName: string, initialDir: string, host: ModuleResolutionHost): ResolvedModuleWithFailedLookupLocations {
|
||||
return nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, /*jsOnly*/ true);
|
||||
return nodeModuleNameResolverWorker(moduleName, initialDir, { moduleResolution: ModuleResolutionKind.NodeJs, allowJs: true }, host, /*cache*/ undefined, jsOnlyExtensions, /*redirectedReferences*/ undefined);
|
||||
}
|
||||
|
||||
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache): ResolvedModuleWithFailedLookupLocations {
|
||||
return nodeModuleNameResolverWorker(moduleName, getDirectoryPath(containingFile), compilerOptions, host, cache, /*jsOnly*/ false);
|
||||
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations;
|
||||
/* @internal */ export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, lookupConfig?: boolean): ResolvedModuleWithFailedLookupLocations; // tslint:disable-line unified-signatures
|
||||
export function nodeModuleNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: ModuleResolutionCache, redirectedReference?: ResolvedProjectReference, lookupConfig?: boolean): ResolvedModuleWithFailedLookupLocations {
|
||||
return nodeModuleNameResolverWorker(moduleName, getDirectoryPath(containingFile), compilerOptions, host, cache, lookupConfig ? tsconfigExtensions : (compilerOptions.resolveJsonModule ? tsPlusJsonExtensions : tsExtensions), redirectedReference);
|
||||
}
|
||||
|
||||
function nodeModuleNameResolverWorker(moduleName: string, containingDirectory: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache | undefined, jsOnly: boolean): ResolvedModuleWithFailedLookupLocations {
|
||||
function nodeModuleNameResolverWorker(moduleName: string, containingDirectory: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache: ModuleResolutionCache | undefined, extensions: Extensions[], redirectedReference: ResolvedProjectReference | undefined): ResolvedModuleWithFailedLookupLocations {
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
|
||||
const failedLookupLocations: string[] = [];
|
||||
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations };
|
||||
|
||||
const result = jsOnly ?
|
||||
tryResolve(Extensions.JavaScript) :
|
||||
(tryResolve(Extensions.TypeScript) ||
|
||||
tryResolve(Extensions.JavaScript) ||
|
||||
(compilerOptions.resolveJsonModule ? tryResolve(Extensions.Json) : undefined));
|
||||
const result = forEach(extensions, ext => tryResolve(ext));
|
||||
if (result && result.value) {
|
||||
const { resolved, isExternalLibraryImport } = result.value;
|
||||
return createResolvedModuleWithFailedLookupLocations(resolved, isExternalLibraryImport, failedLookupLocations);
|
||||
@@ -833,14 +895,14 @@ namespace ts {
|
||||
const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => nodeLoadModuleByRelativeName(extensions, candidate, onlyRecordFailures, state, /*considerPackageJson*/ true);
|
||||
const resolved = tryLoadModuleUsingOptionalResolutionSettings(extensions, moduleName, containingDirectory, loader, state);
|
||||
if (resolved) {
|
||||
return toSearchResult({ resolved, isExternalLibraryImport: stringContains(resolved.path, nodeModulesPathPart) });
|
||||
return toSearchResult({ resolved, isExternalLibraryImport: pathContainsNodeModules(resolved.path) });
|
||||
}
|
||||
|
||||
if (!isExternalModuleNameRelative(moduleName)) {
|
||||
if (traceEnabled) {
|
||||
trace(host, Diagnostics.Loading_module_0_from_node_modules_folder_target_file_type_1, moduleName, Extensions[extensions]);
|
||||
}
|
||||
const resolved = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache);
|
||||
const resolved = loadModuleFromNearestNodeModulesDirectory(extensions, moduleName, containingDirectory, state, cache, redirectedReference);
|
||||
if (!resolved) return undefined;
|
||||
|
||||
let resolvedValue = resolved.value;
|
||||
@@ -910,6 +972,10 @@ namespace ts {
|
||||
|
||||
/*@internal*/
|
||||
export const nodeModulesPathPart = "/node_modules/";
|
||||
/*@internal*/
|
||||
export function pathContainsNodeModules(path: string): boolean {
|
||||
return stringContains(path, nodeModulesPathPart);
|
||||
}
|
||||
|
||||
/**
|
||||
* This will be called on the successfully resolved path from `loadModuleFromFile`.
|
||||
@@ -966,9 +1032,9 @@ namespace ts {
|
||||
* in cases when we know upfront that all load attempts will fail (because containing folder does not exists) however we still need to record all failed lookup locations.
|
||||
*/
|
||||
function loadModuleFromFile(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState): PathAndExtension | undefined {
|
||||
if (extensions === Extensions.Json) {
|
||||
if (extensions === Extensions.Json || extensions === Extensions.TSConfig) {
|
||||
const extensionLess = tryRemoveExtension(candidate, Extension.Json);
|
||||
return extensionLess === undefined ? undefined : tryAddingExtensions(extensionLess, extensions, onlyRecordFailures, state);
|
||||
return (extensionLess === undefined && extensions === Extensions.Json) ? undefined : tryAddingExtensions(extensionLess || candidate, extensions, onlyRecordFailures, state);
|
||||
}
|
||||
|
||||
// First, try adding an extension. An import of "foo" could be matched by a file "foo.ts", or "foo.js" by "foo.js.ts"
|
||||
@@ -1006,6 +1072,7 @@ namespace ts {
|
||||
return tryExtension(Extension.Ts) || tryExtension(Extension.Tsx) || tryExtension(Extension.Dts);
|
||||
case Extensions.JavaScript:
|
||||
return tryExtension(Extension.Js) || tryExtension(Extension.Jsx);
|
||||
case Extensions.TSConfig:
|
||||
case Extensions.Json:
|
||||
return tryExtension(Extension.Json);
|
||||
}
|
||||
@@ -1103,11 +1170,27 @@ namespace ts {
|
||||
}
|
||||
|
||||
function loadNodeModuleFromDirectoryWorker(extensions: Extensions, candidate: string, onlyRecordFailures: boolean, state: ModuleResolutionState, jsonContent: PackageJsonPathFields | undefined, versionPaths: VersionPaths | undefined): PathAndExtension | undefined {
|
||||
const packageFile = jsonContent && (extensions !== Extensions.JavaScript && extensions !== Extensions.Json
|
||||
? readPackageJsonTypesFields(jsonContent, candidate, state) ||
|
||||
// When resolving typescript modules, try resolving using main field as well
|
||||
(extensions === Extensions.TypeScript ? readPackageJsonMainField(jsonContent, candidate, state) : undefined)
|
||||
: readPackageJsonMainField(jsonContent, candidate, state));
|
||||
let packageFile: string | undefined;
|
||||
if (jsonContent) {
|
||||
switch (extensions) {
|
||||
case Extensions.JavaScript:
|
||||
case Extensions.Json:
|
||||
packageFile = readPackageJsonMainField(jsonContent, candidate, state);
|
||||
break;
|
||||
case Extensions.TypeScript:
|
||||
// When resolving typescript modules, try resolving using main field as well
|
||||
packageFile = readPackageJsonTypesFields(jsonContent, candidate, state) || readPackageJsonMainField(jsonContent, candidate, state);
|
||||
break;
|
||||
case Extensions.DtsOnly:
|
||||
packageFile = readPackageJsonTypesFields(jsonContent, candidate, state);
|
||||
break;
|
||||
case Extensions.TSConfig:
|
||||
packageFile = readPackageJsonTSConfigField(jsonContent, candidate, state);
|
||||
break;
|
||||
default:
|
||||
return Debug.assertNever(extensions);
|
||||
}
|
||||
}
|
||||
|
||||
const loader: ResolutionKindSpecificLoader = (extensions, candidate, onlyRecordFailures, state) => {
|
||||
const fromFile = tryFile(candidate, onlyRecordFailures, state);
|
||||
@@ -1129,7 +1212,7 @@ namespace ts {
|
||||
|
||||
const onlyRecordFailuresForPackageFile = packageFile ? !directoryProbablyExists(getDirectoryPath(packageFile), state.host) : undefined;
|
||||
const onlyRecordFailuresForIndex = onlyRecordFailures || !directoryProbablyExists(candidate, state.host);
|
||||
const indexPath = combinePaths(candidate, "index");
|
||||
const indexPath = combinePaths(candidate, extensions === Extensions.TSConfig ? "tsconfig" : "index");
|
||||
|
||||
if (versionPaths && (!packageFile || containsPath(candidate, packageFile))) {
|
||||
const moduleName = getRelativePathFromDirectory(candidate, packageFile || indexPath, /*ignoreCase*/ false);
|
||||
@@ -1160,6 +1243,7 @@ namespace ts {
|
||||
switch (extensions) {
|
||||
case Extensions.JavaScript:
|
||||
return extension === Extension.Js || extension === Extension.Jsx;
|
||||
case Extensions.TSConfig:
|
||||
case Extensions.Json:
|
||||
return extension === Extension.Json;
|
||||
case Extensions.TypeScript:
|
||||
@@ -1178,17 +1262,17 @@ namespace ts {
|
||||
return idx === -1 ? { packageName: moduleName, rest: "" } : { packageName: moduleName.slice(0, idx), rest: moduleName.slice(idx + 1) };
|
||||
}
|
||||
|
||||
function loadModuleFromNearestNodeModulesDirectory(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache | undefined): SearchResult<Resolved> {
|
||||
return loadModuleFromNearestNodeModulesDirectoryWorker(extensions, moduleName, directory, state, /*typesScopeOnly*/ false, cache);
|
||||
function loadModuleFromNearestNodeModulesDirectory(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult<Resolved> {
|
||||
return loadModuleFromNearestNodeModulesDirectoryWorker(extensions, moduleName, directory, state, /*typesScopeOnly*/ false, cache, redirectedReference);
|
||||
}
|
||||
|
||||
function loadModuleFromNearestNodeModulesDirectoryTypesScope(moduleName: string, directory: string, state: ModuleResolutionState): SearchResult<Resolved> {
|
||||
// Extensions parameter here doesn't actually matter, because typesOnly ensures we're just doing @types lookup, which is always DtsOnly.
|
||||
return loadModuleFromNearestNodeModulesDirectoryWorker(Extensions.DtsOnly, moduleName, directory, state, /*typesScopeOnly*/ true, /*cache*/ undefined);
|
||||
return loadModuleFromNearestNodeModulesDirectoryWorker(Extensions.DtsOnly, moduleName, directory, state, /*typesScopeOnly*/ true, /*cache*/ undefined, /*redirectedReference*/ undefined);
|
||||
}
|
||||
|
||||
function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean, cache: NonRelativeModuleNameResolutionCache | undefined): SearchResult<Resolved> {
|
||||
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName);
|
||||
function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions, moduleName: string, directory: string, state: ModuleResolutionState, typesScopeOnly: boolean, cache: NonRelativeModuleNameResolutionCache | undefined, redirectedReference: ResolvedProjectReference | undefined): SearchResult<Resolved> {
|
||||
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName, redirectedReference);
|
||||
return forEachAncestorDirectory(normalizeSlashes(directory), ancestorDirectory => {
|
||||
if (getBaseFileName(ancestorDirectory) !== "node_modules") {
|
||||
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, ancestorDirectory, state);
|
||||
@@ -1211,7 +1295,7 @@ namespace ts {
|
||||
if (packageResult) {
|
||||
return packageResult;
|
||||
}
|
||||
if (extensions !== Extensions.JavaScript && extensions !== Extensions.Json) {
|
||||
if (extensions === Extensions.TypeScript || extensions === Extensions.DtsOnly) {
|
||||
const nodeModulesAtTypes = combinePaths(nodeModulesFolder, "@types");
|
||||
let nodeModulesAtTypesExists = nodeModulesFolderExists;
|
||||
if (nodeModulesFolderExists && !directoryProbablyExists(nodeModulesAtTypes, state.host)) {
|
||||
@@ -1356,7 +1440,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache): ResolvedModuleWithFailedLookupLocations {
|
||||
export function classicNameResolver(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, cache?: NonRelativeModuleNameResolutionCache, redirectedReference?: ResolvedProjectReference): ResolvedModuleWithFailedLookupLocations {
|
||||
const traceEnabled = isTraceEnabled(compilerOptions, host);
|
||||
const failedLookupLocations: string[] = [];
|
||||
const state: ModuleResolutionState = { compilerOptions, host, traceEnabled, failedLookupLocations };
|
||||
@@ -1373,7 +1457,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (!isExternalModuleNameRelative(moduleName)) {
|
||||
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName);
|
||||
const perModuleNameCache = cache && cache.getOrCreateCacheForModuleName(moduleName, redirectedReference);
|
||||
// Climb up parent directories looking for a module.
|
||||
const resolved = forEachAncestorDirectory(containingDirectory, directory => {
|
||||
const resolutionFromCache = tryFindNonRelativeModuleNameInCache(perModuleNameCache, moduleName, directory, state);
|
||||
|
||||
@@ -260,6 +260,9 @@ namespace ts.moduleSpecifiers {
|
||||
}
|
||||
|
||||
function tryGetModuleNameAsNodeModule(moduleFileName: string, { getCanonicalFileName, sourceDirectory }: Info, host: ModuleSpecifierResolutionHost, options: CompilerOptions): string | undefined {
|
||||
if (!host.fileExists || !host.readFile) {
|
||||
return undefined;
|
||||
}
|
||||
const parts: NodeModulePathParts = getNodeModulePathParts(moduleFileName)!;
|
||||
if (!parts) {
|
||||
return undefined;
|
||||
@@ -267,8 +270,8 @@ namespace ts.moduleSpecifiers {
|
||||
|
||||
const packageRootPath = moduleFileName.substring(0, parts.packageRootIndex);
|
||||
const packageJsonPath = combinePaths(packageRootPath, "package.json");
|
||||
const packageJsonContent = host.fileExists!(packageJsonPath)
|
||||
? JSON.parse(host.readFile!(packageJsonPath)!)
|
||||
const packageJsonContent = host.fileExists(packageJsonPath)
|
||||
? JSON.parse(host.readFile(packageJsonPath)!)
|
||||
: undefined;
|
||||
const versionPaths = packageJsonContent && packageJsonContent.typesVersions
|
||||
? getPackageJsonTypesVersionsPaths(packageJsonContent.typesVersions)
|
||||
@@ -325,11 +328,12 @@ namespace ts.moduleSpecifiers {
|
||||
}
|
||||
|
||||
function tryGetAnyFileFromPath(host: ModuleSpecifierResolutionHost, path: string) {
|
||||
if (!host.fileExists) return;
|
||||
// We check all js, `node` and `json` extensions in addition to TS, since node module resolution would also choose those over the directory
|
||||
const extensions = getSupportedExtensions({ allowJs: true }, [{ extension: "node", isMixedContent: false }, { extension: "json", isMixedContent: false, scriptKind: ScriptKind.JSON }]);
|
||||
for (const e of extensions) {
|
||||
const fullPath = path + e;
|
||||
if (host.fileExists!(fullPath)) { // TODO: GH#18217
|
||||
if (host.fileExists(fullPath)) {
|
||||
return fullPath;
|
||||
}
|
||||
}
|
||||
|
||||
+76
-77
@@ -1482,7 +1482,15 @@ namespace ts {
|
||||
// which would be a candidate for improved error reporting.
|
||||
return token() === SyntaxKind.OpenBracketToken || isLiteralPropertyName();
|
||||
case ParsingContext.ObjectLiteralMembers:
|
||||
return token() === SyntaxKind.OpenBracketToken || token() === SyntaxKind.AsteriskToken || token() === SyntaxKind.DotDotDotToken || isLiteralPropertyName();
|
||||
switch (token()) {
|
||||
case SyntaxKind.OpenBracketToken:
|
||||
case SyntaxKind.AsteriskToken:
|
||||
case SyntaxKind.DotDotDotToken:
|
||||
case SyntaxKind.DotToken: // Not an object literal member, but don't want to close the object (see `tests/cases/fourslash/completionsDotInObjectLiteral.ts`)
|
||||
return true;
|
||||
default:
|
||||
return isLiteralPropertyName();
|
||||
}
|
||||
case ParsingContext.RestProperties:
|
||||
return isLiteralPropertyName();
|
||||
case ParsingContext.ObjectBindingElements:
|
||||
@@ -1510,8 +1518,10 @@ namespace ts {
|
||||
case ParsingContext.TypeParameters:
|
||||
return isIdentifier();
|
||||
case ParsingContext.ArrayLiteralMembers:
|
||||
if (token() === SyntaxKind.CommaToken) {
|
||||
return true;
|
||||
switch (token()) {
|
||||
case SyntaxKind.CommaToken:
|
||||
case SyntaxKind.DotToken: // Not an array literal member, but don't want to close the array (see `tests/cases/fourslash/completionsDotInArrayLiteralInObjectLiteral.ts`)
|
||||
return true;
|
||||
}
|
||||
// falls through
|
||||
case ParsingContext.ArgumentExpressions:
|
||||
@@ -2237,8 +2247,7 @@ namespace ts {
|
||||
|
||||
function parseLiteralLikeNode(kind: SyntaxKind): LiteralExpression | LiteralLikeNode {
|
||||
const node = <LiteralExpression>createNode(kind);
|
||||
const text = scanner.getTokenValue();
|
||||
node.text = text;
|
||||
node.text = scanner.getTokenValue();
|
||||
|
||||
if (scanner.hasExtendedUnicodeEscape()) {
|
||||
node.hasExtendedUnicodeEscape = true;
|
||||
@@ -2882,8 +2891,9 @@ namespace ts {
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
function nextTokenIsNumericLiteral() {
|
||||
return nextToken() === SyntaxKind.NumericLiteral;
|
||||
function nextTokenIsNumericOrBigIntLiteral() {
|
||||
nextToken();
|
||||
return token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.BigIntLiteral;
|
||||
}
|
||||
|
||||
function parseNonArrayType(): TypeNode {
|
||||
@@ -2892,6 +2902,7 @@ namespace ts {
|
||||
case SyntaxKind.UnknownKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.BigIntKeyword:
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
case SyntaxKind.UndefinedKeyword:
|
||||
@@ -2912,11 +2923,12 @@ namespace ts {
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
return parseLiteralTypeNode();
|
||||
case SyntaxKind.MinusToken:
|
||||
return lookAhead(nextTokenIsNumericLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference();
|
||||
return lookAhead(nextTokenIsNumericOrBigIntLiteral) ? parseLiteralTypeNode(/*negative*/ true) : parseTypeReference();
|
||||
case SyntaxKind.VoidKeyword:
|
||||
case SyntaxKind.NullKeyword:
|
||||
return parseTokenNode<TypeNode>();
|
||||
@@ -2950,6 +2962,7 @@ namespace ts {
|
||||
case SyntaxKind.UnknownKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.BigIntKeyword:
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
case SyntaxKind.UniqueKeyword:
|
||||
@@ -2967,6 +2980,7 @@ namespace ts {
|
||||
case SyntaxKind.NewKeyword:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
case SyntaxKind.ObjectKeyword:
|
||||
@@ -2980,7 +2994,7 @@ namespace ts {
|
||||
case SyntaxKind.FunctionKeyword:
|
||||
return !inStartOfParameter;
|
||||
case SyntaxKind.MinusToken:
|
||||
return !inStartOfParameter && lookAhead(nextTokenIsNumericLiteral);
|
||||
return !inStartOfParameter && lookAhead(nextTokenIsNumericOrBigIntLiteral);
|
||||
case SyntaxKind.OpenParenToken:
|
||||
// Only consider '(' the start of a type if followed by ')', '...', an identifier, a modifier,
|
||||
// or something that starts a type. We don't want to consider things like '(1)' a type.
|
||||
@@ -3205,6 +3219,7 @@ namespace ts {
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.TemplateHead:
|
||||
@@ -4614,6 +4629,7 @@ namespace ts {
|
||||
function parsePrimaryExpression(): PrimaryExpression {
|
||||
switch (token()) {
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
return parseLiteralNode();
|
||||
@@ -4728,8 +4744,7 @@ namespace ts {
|
||||
// CoverInitializedName[Yield] :
|
||||
// IdentifierReference[?Yield] Initializer[In, ?Yield]
|
||||
// this is necessary because ObjectLiteral productions are also used to cover grammar for ObjectAssignmentPattern
|
||||
const isShorthandPropertyAssignment =
|
||||
tokenIsIdentifier && (token() === SyntaxKind.CommaToken || token() === SyntaxKind.CloseBraceToken || token() === SyntaxKind.EqualsToken);
|
||||
const isShorthandPropertyAssignment = tokenIsIdentifier && (token() !== SyntaxKind.ColonToken);
|
||||
if (isShorthandPropertyAssignment) {
|
||||
node.kind = SyntaxKind.ShorthandPropertyAssignment;
|
||||
const equalsToken = parseOptionalToken(SyntaxKind.EqualsToken);
|
||||
@@ -5130,7 +5145,7 @@ namespace ts {
|
||||
|
||||
function nextTokenIsIdentifierOrKeywordOrLiteralOnSameLine() {
|
||||
nextToken();
|
||||
return (tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.StringLiteral) && !scanner.hasPrecedingLineBreak();
|
||||
return (tokenIsIdentifierOrKeyword(token()) || token() === SyntaxKind.NumericLiteral || token() === SyntaxKind.BigIntLiteral || token() === SyntaxKind.StringLiteral) && !scanner.hasPrecedingLineBreak();
|
||||
}
|
||||
|
||||
function isDeclaration(): boolean {
|
||||
@@ -6308,7 +6323,7 @@ namespace ts {
|
||||
|
||||
// Parses out a JSDoc type expression.
|
||||
export function parseJSDocTypeExpression(mayOmitBraces?: boolean): JSDocTypeExpression {
|
||||
const result = <JSDocTypeExpression>createNode(SyntaxKind.JSDocTypeExpression, scanner.getTokenPos());
|
||||
const result = <JSDocTypeExpression>createNode(SyntaxKind.JSDocTypeExpression);
|
||||
|
||||
const hasBrace = (mayOmitBraces ? parseOptional : parseExpected)(SyntaxKind.OpenBraceToken);
|
||||
result.type = doInsideOfContext(NodeFlags.JSDoc, parseJSDocType);
|
||||
@@ -6512,7 +6527,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function skipWhitespaceOrAsterisk(next: () => void): void {
|
||||
function skipWhitespaceOrAsterisk(): void {
|
||||
if (token() === SyntaxKind.WhitespaceTrivia || token() === SyntaxKind.NewLineTrivia) {
|
||||
if (lookAhead(isNextNonwhitespaceTokenEndOfFile)) {
|
||||
return; // Don't skip whitespace prior to EoF (or end of comment) - that shouldn't be included in any node's range
|
||||
@@ -6527,58 +6542,56 @@ namespace ts {
|
||||
else if (token() === SyntaxKind.AsteriskToken) {
|
||||
precedingLineBreak = false;
|
||||
}
|
||||
next();
|
||||
nextJSDocToken();
|
||||
}
|
||||
}
|
||||
|
||||
function parseTag(indent: number) {
|
||||
Debug.assert(token() === SyntaxKind.AtToken);
|
||||
const atToken = <AtToken>createNode(SyntaxKind.AtToken, scanner.getTokenPos());
|
||||
atToken.end = scanner.getTextPos();
|
||||
const start = scanner.getTokenPos();
|
||||
nextJSDocToken();
|
||||
|
||||
// Use 'nextToken' instead of 'nextJsDocToken' so we can parse a type like 'number' in `@enum number`
|
||||
const tagName = parseJSDocIdentifierName(/*message*/ undefined, nextToken);
|
||||
skipWhitespaceOrAsterisk(nextToken);
|
||||
const tagName = parseJSDocIdentifierName(/*message*/ undefined);
|
||||
skipWhitespaceOrAsterisk();
|
||||
|
||||
let tag: JSDocTag | undefined;
|
||||
switch (tagName.escapedText) {
|
||||
case "augments":
|
||||
case "extends":
|
||||
tag = parseAugmentsTag(atToken, tagName);
|
||||
tag = parseAugmentsTag(start, tagName);
|
||||
break;
|
||||
case "class":
|
||||
case "constructor":
|
||||
tag = parseClassTag(atToken, tagName);
|
||||
tag = parseClassTag(start, tagName);
|
||||
break;
|
||||
case "this":
|
||||
tag = parseThisTag(atToken, tagName);
|
||||
tag = parseThisTag(start, tagName);
|
||||
break;
|
||||
case "enum":
|
||||
tag = parseEnumTag(atToken, tagName);
|
||||
tag = parseEnumTag(start, tagName);
|
||||
break;
|
||||
case "arg":
|
||||
case "argument":
|
||||
case "param":
|
||||
return parseParameterOrPropertyTag(atToken, tagName, PropertyLikeParse.Parameter, indent);
|
||||
return parseParameterOrPropertyTag(start, tagName, PropertyLikeParse.Parameter, indent);
|
||||
case "return":
|
||||
case "returns":
|
||||
tag = parseReturnTag(atToken, tagName);
|
||||
tag = parseReturnTag(start, tagName);
|
||||
break;
|
||||
case "template":
|
||||
tag = parseTemplateTag(atToken, tagName);
|
||||
tag = parseTemplateTag(start, tagName);
|
||||
break;
|
||||
case "type":
|
||||
tag = parseTypeTag(atToken, tagName);
|
||||
tag = parseTypeTag(start, tagName);
|
||||
break;
|
||||
case "typedef":
|
||||
tag = parseTypedefTag(atToken, tagName, indent);
|
||||
tag = parseTypedefTag(start, tagName, indent);
|
||||
break;
|
||||
case "callback":
|
||||
tag = parseCallbackTag(atToken, tagName, indent);
|
||||
tag = parseCallbackTag(start, tagName, indent);
|
||||
break;
|
||||
default:
|
||||
tag = parseUnknownTag(atToken, tagName);
|
||||
tag = parseUnknownTag(start, tagName);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -6661,9 +6674,8 @@ namespace ts {
|
||||
return comments.length === 0 ? undefined : comments.join("");
|
||||
}
|
||||
|
||||
function parseUnknownTag(atToken: AtToken, tagName: Identifier) {
|
||||
const result = <JSDocTag>createNode(SyntaxKind.JSDocTag, atToken.pos);
|
||||
result.atToken = atToken;
|
||||
function parseUnknownTag(start: number, tagName: Identifier) {
|
||||
const result = <JSDocTag>createNode(SyntaxKind.JSDocTag, start);
|
||||
result.tagName = tagName;
|
||||
return finishNode(result);
|
||||
}
|
||||
@@ -6683,7 +6695,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function tryParseTypeExpression(): JSDocTypeExpression | undefined {
|
||||
skipWhitespaceOrAsterisk(nextJSDocToken);
|
||||
skipWhitespaceOrAsterisk();
|
||||
return token() === SyntaxKind.OpenBraceToken ? parseJSDocTypeExpression() : undefined;
|
||||
}
|
||||
|
||||
@@ -6720,10 +6732,10 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function parseParameterOrPropertyTag(atToken: AtToken, tagName: Identifier, target: PropertyLikeParse, indent: number): JSDocParameterTag | JSDocPropertyTag {
|
||||
function parseParameterOrPropertyTag(start: number, tagName: Identifier, target: PropertyLikeParse, indent: number): JSDocParameterTag | JSDocPropertyTag {
|
||||
let typeExpression = tryParseTypeExpression();
|
||||
let isNameFirst = !typeExpression;
|
||||
skipWhitespaceOrAsterisk(nextJSDocToken);
|
||||
skipWhitespaceOrAsterisk();
|
||||
|
||||
const { name, isBracketed } = parseBracketNameInPropertyAndParamTag();
|
||||
skipWhitespace();
|
||||
@@ -6733,15 +6745,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
const result = target === PropertyLikeParse.Property ?
|
||||
<JSDocPropertyTag>createNode(SyntaxKind.JSDocPropertyTag, atToken.pos) :
|
||||
<JSDocParameterTag>createNode(SyntaxKind.JSDocParameterTag, atToken.pos);
|
||||
const comment = parseTagComments(indent + scanner.getStartPos() - atToken.pos);
|
||||
<JSDocPropertyTag>createNode(SyntaxKind.JSDocPropertyTag, start) :
|
||||
<JSDocParameterTag>createNode(SyntaxKind.JSDocParameterTag, start);
|
||||
const comment = parseTagComments(indent + scanner.getStartPos() - start);
|
||||
const nestedTypeLiteral = target !== PropertyLikeParse.CallbackParameter && parseNestedTypeLiteral(typeExpression, name, target, indent);
|
||||
if (nestedTypeLiteral) {
|
||||
typeExpression = nestedTypeLiteral;
|
||||
isNameFirst = true;
|
||||
}
|
||||
result.atToken = atToken;
|
||||
result.tagName = tagName;
|
||||
result.typeExpression = typeExpression;
|
||||
result.name = name;
|
||||
@@ -6775,33 +6786,30 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function parseReturnTag(atToken: AtToken, tagName: Identifier): JSDocReturnTag {
|
||||
function parseReturnTag(start: number, tagName: Identifier): JSDocReturnTag {
|
||||
if (forEach(tags, t => t.kind === SyntaxKind.JSDocReturnTag)) {
|
||||
parseErrorAt(tagName.pos, scanner.getTokenPos(), Diagnostics._0_tag_already_specified, tagName.escapedText);
|
||||
}
|
||||
|
||||
const result = <JSDocReturnTag>createNode(SyntaxKind.JSDocReturnTag, atToken.pos);
|
||||
result.atToken = atToken;
|
||||
const result = <JSDocReturnTag>createNode(SyntaxKind.JSDocReturnTag, start);
|
||||
result.tagName = tagName;
|
||||
result.typeExpression = tryParseTypeExpression();
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
function parseTypeTag(atToken: AtToken, tagName: Identifier): JSDocTypeTag {
|
||||
function parseTypeTag(start: number, tagName: Identifier): JSDocTypeTag {
|
||||
if (forEach(tags, t => t.kind === SyntaxKind.JSDocTypeTag)) {
|
||||
parseErrorAt(tagName.pos, scanner.getTokenPos(), Diagnostics._0_tag_already_specified, tagName.escapedText);
|
||||
}
|
||||
|
||||
const result = <JSDocTypeTag>createNode(SyntaxKind.JSDocTypeTag, atToken.pos);
|
||||
result.atToken = atToken;
|
||||
const result = <JSDocTypeTag>createNode(SyntaxKind.JSDocTypeTag, start);
|
||||
result.tagName = tagName;
|
||||
result.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true);
|
||||
return finishNode(result);
|
||||
}
|
||||
|
||||
function parseAugmentsTag(atToken: AtToken, tagName: Identifier): JSDocAugmentsTag {
|
||||
const result = <JSDocAugmentsTag>createNode(SyntaxKind.JSDocAugmentsTag, atToken.pos);
|
||||
result.atToken = atToken;
|
||||
function parseAugmentsTag(start: number, tagName: Identifier): JSDocAugmentsTag {
|
||||
const result = <JSDocAugmentsTag>createNode(SyntaxKind.JSDocAugmentsTag, start);
|
||||
result.tagName = tagName;
|
||||
result.class = parseExpressionWithTypeArgumentsForAugments();
|
||||
return finishNode(result);
|
||||
@@ -6830,37 +6838,33 @@ namespace ts {
|
||||
return node;
|
||||
}
|
||||
|
||||
function parseClassTag(atToken: AtToken, tagName: Identifier): JSDocClassTag {
|
||||
const tag = <JSDocClassTag>createNode(SyntaxKind.JSDocClassTag, atToken.pos);
|
||||
tag.atToken = atToken;
|
||||
function parseClassTag(start: number, tagName: Identifier): JSDocClassTag {
|
||||
const tag = <JSDocClassTag>createNode(SyntaxKind.JSDocClassTag, start);
|
||||
tag.tagName = tagName;
|
||||
return finishNode(tag);
|
||||
}
|
||||
|
||||
function parseThisTag(atToken: AtToken, tagName: Identifier): JSDocThisTag {
|
||||
const tag = <JSDocThisTag>createNode(SyntaxKind.JSDocThisTag, atToken.pos);
|
||||
tag.atToken = atToken;
|
||||
function parseThisTag(start: number, tagName: Identifier): JSDocThisTag {
|
||||
const tag = <JSDocThisTag>createNode(SyntaxKind.JSDocThisTag, start);
|
||||
tag.tagName = tagName;
|
||||
tag.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true);
|
||||
skipWhitespace();
|
||||
return finishNode(tag);
|
||||
}
|
||||
|
||||
function parseEnumTag(atToken: AtToken, tagName: Identifier): JSDocEnumTag {
|
||||
const tag = <JSDocEnumTag>createNode(SyntaxKind.JSDocEnumTag, atToken.pos);
|
||||
tag.atToken = atToken;
|
||||
function parseEnumTag(start: number, tagName: Identifier): JSDocEnumTag {
|
||||
const tag = <JSDocEnumTag>createNode(SyntaxKind.JSDocEnumTag, start);
|
||||
tag.tagName = tagName;
|
||||
tag.typeExpression = parseJSDocTypeExpression(/*mayOmitBraces*/ true);
|
||||
skipWhitespace();
|
||||
return finishNode(tag);
|
||||
}
|
||||
|
||||
function parseTypedefTag(atToken: AtToken, tagName: Identifier, indent: number): JSDocTypedefTag {
|
||||
function parseTypedefTag(start: number, tagName: Identifier, indent: number): JSDocTypedefTag {
|
||||
const typeExpression = tryParseTypeExpression();
|
||||
skipWhitespaceOrAsterisk(nextJSDocToken);
|
||||
skipWhitespaceOrAsterisk();
|
||||
|
||||
const typedefTag = <JSDocTypedefTag>createNode(SyntaxKind.JSDocTypedefTag, atToken.pos);
|
||||
typedefTag.atToken = atToken;
|
||||
const typedefTag = <JSDocTypedefTag>createNode(SyntaxKind.JSDocTypedefTag, start);
|
||||
typedefTag.tagName = tagName;
|
||||
typedefTag.fullName = parseJSDocTypeNameWithNamespace();
|
||||
typedefTag.name = getJSDocTypeAliasName(typedefTag.fullName);
|
||||
@@ -6873,7 +6877,6 @@ namespace ts {
|
||||
let child: JSDocTypeTag | JSDocPropertyTag | false;
|
||||
let jsdocTypeLiteral: JSDocTypeLiteral | undefined;
|
||||
let childTypeTag: JSDocTypeTag | undefined;
|
||||
const start = atToken.pos;
|
||||
while (child = tryParse(() => parseChildPropertyTag(indent))) {
|
||||
if (!jsdocTypeLiteral) {
|
||||
jsdocTypeLiteral = <JSDocTypeLiteral>createNode(SyntaxKind.JSDocTypeLiteral, start);
|
||||
@@ -6927,9 +6930,8 @@ namespace ts {
|
||||
return typeNameOrNamespaceName;
|
||||
}
|
||||
|
||||
function parseCallbackTag(atToken: AtToken, tagName: Identifier, indent: number): JSDocCallbackTag {
|
||||
const callbackTag = createNode(SyntaxKind.JSDocCallbackTag, atToken.pos) as JSDocCallbackTag;
|
||||
callbackTag.atToken = atToken;
|
||||
function parseCallbackTag(start: number, tagName: Identifier, indent: number): JSDocCallbackTag {
|
||||
const callbackTag = createNode(SyntaxKind.JSDocCallbackTag, start) as JSDocCallbackTag;
|
||||
callbackTag.tagName = tagName;
|
||||
callbackTag.fullName = parseJSDocTypeNameWithNamespace();
|
||||
callbackTag.name = getJSDocTypeAliasName(callbackTag.fullName);
|
||||
@@ -6937,7 +6939,6 @@ namespace ts {
|
||||
callbackTag.comment = parseTagComments(indent);
|
||||
|
||||
let child: JSDocParameterTag | false;
|
||||
const start = scanner.getStartPos();
|
||||
const jsdocSignature = createNode(SyntaxKind.JSDocSignature, start) as JSDocSignature;
|
||||
jsdocSignature.parameters = [];
|
||||
while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.CallbackParameter, indent) as JSDocParameterTag)) {
|
||||
@@ -7025,8 +7026,7 @@ namespace ts {
|
||||
|
||||
function tryParseChildTag(target: PropertyLikeParse, indent: number): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | false {
|
||||
Debug.assert(token() === SyntaxKind.AtToken);
|
||||
const atToken = <AtToken>createNode(SyntaxKind.AtToken);
|
||||
atToken.end = scanner.getTextPos();
|
||||
const start = scanner.getStartPos();
|
||||
nextJSDocToken();
|
||||
|
||||
const tagName = parseJSDocIdentifierName();
|
||||
@@ -7034,7 +7034,7 @@ namespace ts {
|
||||
let t: PropertyLikeParse;
|
||||
switch (tagName.escapedText) {
|
||||
case "type":
|
||||
return target === PropertyLikeParse.Property && parseTypeTag(atToken, tagName);
|
||||
return target === PropertyLikeParse.Property && parseTypeTag(start, tagName);
|
||||
case "prop":
|
||||
case "property":
|
||||
t = PropertyLikeParse.Property;
|
||||
@@ -7050,10 +7050,10 @@ namespace ts {
|
||||
if (!(target & t)) {
|
||||
return false;
|
||||
}
|
||||
return parseParameterOrPropertyTag(atToken, tagName, target, indent);
|
||||
return parseParameterOrPropertyTag(start, tagName, target, indent);
|
||||
}
|
||||
|
||||
function parseTemplateTag(atToken: AtToken, tagName: Identifier): JSDocTemplateTag {
|
||||
function parseTemplateTag(start: number, tagName: Identifier): JSDocTemplateTag {
|
||||
// the template tag looks like '@template {Constraint} T,U,V'
|
||||
let constraint: JSDocTypeExpression | undefined;
|
||||
if (token() === SyntaxKind.OpenBraceToken) {
|
||||
@@ -7071,8 +7071,7 @@ namespace ts {
|
||||
typeParameters.push(typeParameter);
|
||||
} while (parseOptionalJsdoc(SyntaxKind.CommaToken));
|
||||
|
||||
const result = <JSDocTemplateTag>createNode(SyntaxKind.JSDocTemplateTag, atToken.pos);
|
||||
result.atToken = atToken;
|
||||
const result = <JSDocTemplateTag>createNode(SyntaxKind.JSDocTemplateTag, start);
|
||||
result.tagName = tagName;
|
||||
result.constraint = constraint;
|
||||
result.typeParameters = createNodeArray(typeParameters, typeParametersPos);
|
||||
@@ -7110,7 +7109,7 @@ namespace ts {
|
||||
return entity;
|
||||
}
|
||||
|
||||
function parseJSDocIdentifierName(message?: DiagnosticMessage, next: () => void = nextJSDocToken): Identifier {
|
||||
function parseJSDocIdentifierName(message?: DiagnosticMessage): Identifier {
|
||||
if (!tokenIsIdentifierOrKeyword(token())) {
|
||||
return createMissingNode<Identifier>(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ !message, message || Diagnostics.Identifier_expected);
|
||||
}
|
||||
@@ -7121,7 +7120,7 @@ namespace ts {
|
||||
result.escapedText = escapeLeadingUnderscores(scanner.getTokenText());
|
||||
finishNode(result, end);
|
||||
|
||||
next();
|
||||
nextJSDocToken();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
+326
-201
@@ -198,7 +198,7 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): Diagnostic[] {
|
||||
export function getPreEmitDiagnostics(program: Program, sourceFile?: SourceFile, cancellationToken?: CancellationToken): ReadonlyArray<Diagnostic> {
|
||||
const diagnostics = [
|
||||
...program.getConfigFileParsingDiagnostics(),
|
||||
...program.getOptionsDiagnostics(cancellationToken),
|
||||
@@ -406,7 +406,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function loadWithLocalCache<T>(names: string[], containingFile: string, loader: (name: string, containingFile: string) => T): T[] {
|
||||
function loadWithLocalCache<T>(names: string[], containingFile: string, redirectedReference: ResolvedProjectReference | undefined, loader: (name: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => T): T[] {
|
||||
if (names.length === 0) {
|
||||
return [];
|
||||
}
|
||||
@@ -418,7 +418,7 @@ namespace ts {
|
||||
result = cache.get(name)!;
|
||||
}
|
||||
else {
|
||||
cache.set(name, result = loader(name, containingFile));
|
||||
cache.set(name, result = loader(name, containingFile, redirectedReference));
|
||||
}
|
||||
resolutions.push(result);
|
||||
}
|
||||
@@ -454,6 +454,8 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
let seenResolvedRefs: ResolvedProjectReference[] | undefined;
|
||||
|
||||
// If project references dont match
|
||||
if (!arrayIsEqualTo(program.getProjectReferences(), projectReferences, projectReferenceUptoDate)) {
|
||||
return false;
|
||||
@@ -485,7 +487,7 @@ namespace ts {
|
||||
|
||||
function sourceFileNotUptoDate(sourceFile: SourceFile) {
|
||||
return !sourceFileVersionUptoDate(sourceFile) ||
|
||||
hasInvalidatedResolution(sourceFile.resolvedPath);
|
||||
hasInvalidatedResolution(sourceFile.path);
|
||||
}
|
||||
|
||||
function sourceFileVersionUptoDate(sourceFile: SourceFile) {
|
||||
@@ -496,11 +498,29 @@ namespace ts {
|
||||
if (!projectReferenceIsEqualTo(oldRef, newRef)) {
|
||||
return false;
|
||||
}
|
||||
const oldResolvedRef = program!.getResolvedProjectReferences()![index];
|
||||
return resolvedProjectReferenceUptoDate(program!.getResolvedProjectReferences()![index], oldRef);
|
||||
}
|
||||
|
||||
function resolvedProjectReferenceUptoDate(oldResolvedRef: ResolvedProjectReference | undefined, oldRef: ProjectReference): boolean {
|
||||
if (oldResolvedRef) {
|
||||
if (contains(seenResolvedRefs, oldResolvedRef)) {
|
||||
// Assume true
|
||||
return true;
|
||||
}
|
||||
|
||||
// If sourceFile for the oldResolvedRef existed, check the version for uptodate
|
||||
return sourceFileVersionUptoDate(oldResolvedRef.sourceFile);
|
||||
if (!sourceFileVersionUptoDate(oldResolvedRef.sourceFile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add to seen before checking the referenced paths of this config file
|
||||
(seenResolvedRefs || (seenResolvedRefs = [])).push(oldResolvedRef);
|
||||
|
||||
// If child project references are upto date, this project reference is uptodate
|
||||
return !forEach(oldResolvedRef.references, (childResolvedRef, index) =>
|
||||
!resolvedProjectReferenceUptoDate(childResolvedRef, oldResolvedRef.commandLine.projectReferences![index]));
|
||||
}
|
||||
|
||||
// In old program, not able to resolve project reference path,
|
||||
// so if config file doesnt exist, it is uptodate.
|
||||
return !fileExists(resolveProjectReferencePath(oldRef));
|
||||
@@ -574,12 +594,12 @@ namespace ts {
|
||||
let diagnosticsProducingTypeChecker: TypeChecker;
|
||||
let noDiagnosticsTypeChecker: TypeChecker;
|
||||
let classifiableNames: UnderscoreEscapedMap<true>;
|
||||
let modifiedFilePaths: Path[] | undefined;
|
||||
const ambientModuleNameToUnmodifiedFileName = createMap<string>();
|
||||
|
||||
const cachedSemanticDiagnosticsForFile: DiagnosticCache<Diagnostic> = {};
|
||||
const cachedDeclarationDiagnosticsForFile: DiagnosticCache<DiagnosticWithLocation> = {};
|
||||
|
||||
let resolvedTypeReferenceDirectives = createMap<ResolvedTypeReferenceDirective>();
|
||||
let resolvedTypeReferenceDirectives = createMap<ResolvedTypeReferenceDirective | undefined>();
|
||||
let fileProcessingDiagnostics = createDiagnosticCollection();
|
||||
|
||||
// The below settings are to track if a .js file should be add to the program if loaded via searching under node_modules.
|
||||
@@ -610,18 +630,17 @@ namespace ts {
|
||||
const programDiagnostics = createDiagnosticCollection();
|
||||
const currentDirectory = host.getCurrentDirectory();
|
||||
const supportedExtensions = getSupportedExtensions(options);
|
||||
const supportedExtensionsWithJsonIfResolveJsonModule = options.resolveJsonModule ? [...supportedExtensions, Extension.Json] : undefined;
|
||||
const supportedExtensionsWithJsonIfResolveJsonModule = getSuppoertedExtensionsWithJsonIfResolveJsonModule(options, supportedExtensions);
|
||||
|
||||
// Map storing if there is emit blocking diagnostics for given input
|
||||
const hasEmitBlockingDiagnostics = createMap<boolean>();
|
||||
let _compilerOptionsObjectLiteralSyntax: ObjectLiteralExpression | null | undefined;
|
||||
let _referencesArrayLiteralSyntax: ArrayLiteralExpression | null | undefined;
|
||||
|
||||
let moduleResolutionCache: ModuleResolutionCache | undefined;
|
||||
let resolveModuleNamesWorker: (moduleNames: string[], containingFile: string, reusedNames?: string[]) => ResolvedModuleFull[];
|
||||
let resolveModuleNamesWorker: (moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference) => ResolvedModuleFull[];
|
||||
const hasInvalidatedResolution = host.hasInvalidatedResolution || returnFalse;
|
||||
if (host.resolveModuleNames) {
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile, reusedNames) => host.resolveModuleNames!(Debug.assertEachDefined(moduleNames), containingFile, reusedNames).map(resolved => {
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile, reusedNames, redirectedReference) => host.resolveModuleNames!(Debug.assertEachDefined(moduleNames), containingFile, reusedNames, redirectedReference).map(resolved => {
|
||||
// An older host may have omitted extension, in which case we should infer it from the file extension of resolvedFileName.
|
||||
if (!resolved || (resolved as ResolvedModuleFull).extension !== undefined) {
|
||||
return resolved as ResolvedModuleFull;
|
||||
@@ -633,17 +652,17 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
moduleResolutionCache = createModuleResolutionCache(currentDirectory, x => host.getCanonicalFileName(x));
|
||||
const loader = (moduleName: string, containingFile: string) => resolveModuleName(moduleName, containingFile, options, host, moduleResolutionCache).resolvedModule!; // TODO: GH#18217
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile) => loadWithLocalCache<ResolvedModuleFull>(Debug.assertEachDefined(moduleNames), containingFile, loader);
|
||||
const loader = (moduleName: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => resolveModuleName(moduleName, containingFile, options, host, moduleResolutionCache, redirectedReference).resolvedModule!; // TODO: GH#18217
|
||||
resolveModuleNamesWorker = (moduleNames, containingFile, _reusedNames, redirectedReference) => loadWithLocalCache<ResolvedModuleFull>(Debug.assertEachDefined(moduleNames), containingFile, redirectedReference, loader);
|
||||
}
|
||||
|
||||
let resolveTypeReferenceDirectiveNamesWorker: (typeDirectiveNames: string[], containingFile: string) => ResolvedTypeReferenceDirective[];
|
||||
let resolveTypeReferenceDirectiveNamesWorker: (typeDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference) => (ResolvedTypeReferenceDirective | undefined)[];
|
||||
if (host.resolveTypeReferenceDirectives) {
|
||||
resolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile) => host.resolveTypeReferenceDirectives!(Debug.assertEachDefined(typeDirectiveNames), containingFile);
|
||||
resolveTypeReferenceDirectiveNamesWorker = (typeDirectiveNames, containingFile, redirectedReference) => host.resolveTypeReferenceDirectives!(Debug.assertEachDefined(typeDirectiveNames), containingFile, redirectedReference);
|
||||
}
|
||||
else {
|
||||
const loader = (typesRef: string, containingFile: string) => resolveTypeReferenceDirective(typesRef, containingFile, options, host).resolvedTypeReferenceDirective!; // TODO: GH#18217
|
||||
resolveTypeReferenceDirectiveNamesWorker = (typeReferenceDirectiveNames, containingFile) => loadWithLocalCache<ResolvedTypeReferenceDirective>(Debug.assertEachDefined(typeReferenceDirectiveNames), containingFile, loader);
|
||||
const loader = (typesRef: string, containingFile: string, redirectedReference: ResolvedProjectReference | undefined) => resolveTypeReferenceDirective(typesRef, containingFile, options, host, redirectedReference).resolvedTypeReferenceDirective!; // TODO: GH#18217
|
||||
resolveTypeReferenceDirectiveNamesWorker = (typeReferenceDirectiveNames, containingFile, redirectedReference) => loadWithLocalCache<ResolvedTypeReferenceDirective>(Debug.assertEachDefined(typeReferenceDirectiveNames), containingFile, redirectedReference, loader);
|
||||
}
|
||||
|
||||
// Map from a stringified PackageId to the source file with that id.
|
||||
@@ -662,8 +681,8 @@ namespace ts {
|
||||
const filesByNameIgnoreCase = host.useCaseSensitiveFileNames() ? createMap<SourceFile>() : undefined;
|
||||
|
||||
// A parallel array to projectReferences storing the results of reading in the referenced tsconfig files
|
||||
let resolvedProjectReferences: (ResolvedProjectReference | undefined)[] | undefined = projectReferences ? [] : undefined;
|
||||
let projectReferenceRedirects: ParsedCommandLine[] | undefined;
|
||||
let resolvedProjectReferences: ReadonlyArray<ResolvedProjectReference | undefined> | undefined;
|
||||
let projectReferenceRedirects: Map<ResolvedProjectReference | false> | undefined;
|
||||
|
||||
const shouldCreateNewSourceFile = shouldProgramCreateNewSourceFiles(oldProgram, options);
|
||||
const structuralIsReused = tryReuseStructureFromOldProgram();
|
||||
@@ -672,16 +691,18 @@ namespace ts {
|
||||
processingOtherFiles = [];
|
||||
|
||||
if (projectReferences) {
|
||||
for (const ref of projectReferences) {
|
||||
const parsedRef = parseProjectReferenceConfigFile(ref);
|
||||
resolvedProjectReferences!.push(parsedRef);
|
||||
if (parsedRef) {
|
||||
const out = parsedRef.commandLine.options.outFile || parsedRef.commandLine.options.out;
|
||||
if (out) {
|
||||
const dtsOutfile = changeExtension(out, ".d.ts");
|
||||
processSourceFile(dtsOutfile, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined);
|
||||
if (!resolvedProjectReferences) {
|
||||
resolvedProjectReferences = projectReferences.map(parseProjectReferenceConfigFile);
|
||||
}
|
||||
if (rootNames.length) {
|
||||
for (const parsedRef of resolvedProjectReferences) {
|
||||
if (parsedRef) {
|
||||
const out = parsedRef.commandLine.options.outFile || parsedRef.commandLine.options.out;
|
||||
if (out) {
|
||||
const dtsOutfile = changeExtension(out, ".d.ts");
|
||||
processSourceFile(dtsOutfile, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, /*packageId*/ undefined);
|
||||
}
|
||||
}
|
||||
addProjectReferenceRedirects(parsedRef.commandLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -689,7 +710,7 @@ namespace ts {
|
||||
forEach(rootNames, name => processRootFile(name, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false));
|
||||
|
||||
// load type declarations specified via 'types' argument or implicitly from types/ and node_modules/@types folders
|
||||
const typeReferences: string[] = getAutomaticTypeDirectiveNames(options, host);
|
||||
const typeReferences: string[] = rootNames.length ? getAutomaticTypeDirectiveNames(options, host) : emptyArray;
|
||||
|
||||
if (typeReferences.length) {
|
||||
// This containingFilename needs to match with the one used in managed-side
|
||||
@@ -705,7 +726,7 @@ namespace ts {
|
||||
// - The '--noLib' flag is used.
|
||||
// - A 'no-default-lib' reference comment is encountered in
|
||||
// processing the root files.
|
||||
if (!skipDefaultLib) {
|
||||
if (rootNames.length && !skipDefaultLib) {
|
||||
// If '--lib' is not specified, include default library file according to '--target'
|
||||
// otherwise, using options specified in '--lib' instead of '--target' default library file
|
||||
const defaultLibraryFileName = getDefaultLibraryFileName();
|
||||
@@ -732,10 +753,18 @@ namespace ts {
|
||||
if (oldProgram && host.onReleaseOldSourceFile) {
|
||||
const oldSourceFiles = oldProgram.getSourceFiles();
|
||||
for (const oldSourceFile of oldSourceFiles) {
|
||||
if (!getSourceFile(oldSourceFile.path) || shouldCreateNewSourceFile) {
|
||||
host.onReleaseOldSourceFile(oldSourceFile, oldProgram.getCompilerOptions());
|
||||
const newFile = getSourceFileByPath(oldSourceFile.resolvedPath);
|
||||
if (shouldCreateNewSourceFile || !newFile ||
|
||||
// old file wasnt redirect but new file is
|
||||
(oldSourceFile.resolvedPath === oldSourceFile.path && newFile.resolvedPath !== oldSourceFile.path)) {
|
||||
host.onReleaseOldSourceFile(oldSourceFile, oldProgram.getCompilerOptions(), !!getSourceFileByPath(oldSourceFile.path));
|
||||
}
|
||||
}
|
||||
oldProgram.forEachResolvedProjectReference((resolvedProjectReference, resolvedProjectReferencePath) => {
|
||||
if (resolvedProjectReference && !getResolvedProjectReferenceByPath(resolvedProjectReferencePath)) {
|
||||
host.onReleaseOldSourceFile!(resolvedProjectReference.sourceFile, oldProgram!.getCompilerOptions(), /*hasSourceFileByPath*/ false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// unconditionally set oldProgram to undefined to prevent it from being captured in closure
|
||||
@@ -778,7 +807,10 @@ namespace ts {
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache,
|
||||
getProjectReferences,
|
||||
getResolvedProjectReferences,
|
||||
getProjectReferenceRedirect
|
||||
getProjectReferenceRedirect,
|
||||
getResolvedProjectReferenceToRedirect,
|
||||
getResolvedProjectReferenceByPath,
|
||||
forEachResolvedProjectReference
|
||||
};
|
||||
|
||||
verifyCompilerOptions();
|
||||
@@ -850,21 +882,14 @@ namespace ts {
|
||||
return classifiableNames;
|
||||
}
|
||||
|
||||
interface OldProgramState {
|
||||
program: Program | undefined;
|
||||
oldSourceFile: SourceFile | undefined;
|
||||
/** The collection of paths modified *since* the old program. */
|
||||
modifiedFilePaths: Path[] | undefined;
|
||||
}
|
||||
|
||||
function resolveModuleNamesReusingOldState(moduleNames: string[], containingFile: string, file: SourceFile, oldProgramState: OldProgramState) {
|
||||
function resolveModuleNamesReusingOldState(moduleNames: string[], containingFile: string, file: SourceFile) {
|
||||
if (structuralIsReused === StructureIsReused.Not && !file.ambientModuleNames.length) {
|
||||
// If the old program state does not permit reusing resolutions and `file` does not contain locally defined ambient modules,
|
||||
// the best we can do is fallback to the default logic.
|
||||
return resolveModuleNamesWorker(moduleNames, containingFile);
|
||||
return resolveModuleNamesWorker(moduleNames, containingFile, /*reusedNames*/ undefined, getResolvedProjectReferenceToRedirect(file.originalFileName));
|
||||
}
|
||||
|
||||
const oldSourceFile = oldProgramState.program && oldProgramState.program.getSourceFile(containingFile);
|
||||
const oldSourceFile = oldProgram && oldProgram.getSourceFile(containingFile);
|
||||
if (oldSourceFile !== file && file.resolvedModules) {
|
||||
// `file` was created for the new program.
|
||||
//
|
||||
@@ -928,7 +953,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else {
|
||||
resolvesToAmbientModuleInNonModifiedFile = moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName, oldProgramState);
|
||||
resolvesToAmbientModuleInNonModifiedFile = moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName);
|
||||
}
|
||||
|
||||
if (resolvesToAmbientModuleInNonModifiedFile) {
|
||||
@@ -941,7 +966,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
const resolutions = unknownModuleNames && unknownModuleNames.length
|
||||
? resolveModuleNamesWorker(unknownModuleNames, containingFile, reusedNames)
|
||||
? resolveModuleNamesWorker(unknownModuleNames, containingFile, reusedNames, getResolvedProjectReferenceToRedirect(file.originalFileName))
|
||||
: emptyArray;
|
||||
|
||||
// Combine results of resolutions and predicted results
|
||||
@@ -971,12 +996,9 @@ namespace ts {
|
||||
|
||||
// If we change our policy of rechecking failed lookups on each program create,
|
||||
// we should adjust the value returned here.
|
||||
function moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName: string, oldProgramState: OldProgramState): boolean {
|
||||
if (!oldProgramState.program) {
|
||||
return false;
|
||||
}
|
||||
const resolutionToFile = getResolvedModule(oldProgramState.oldSourceFile!, moduleName); // TODO: GH#18217
|
||||
const resolvedFile = resolutionToFile && oldProgramState.program.getSourceFile(resolutionToFile.resolvedFileName);
|
||||
function moduleNameResolvesToAmbientModuleInNonModifiedFile(moduleName: string): boolean {
|
||||
const resolutionToFile = getResolvedModule(oldSourceFile!, moduleName);
|
||||
const resolvedFile = resolutionToFile && oldProgram!.getSourceFile(resolutionToFile.resolvedFileName);
|
||||
if (resolutionToFile && resolvedFile && !resolvedFile.externalModuleIndicator) {
|
||||
// In the old program, we resolved to an ambient module that was in the same
|
||||
// place as we expected to find an actual module file.
|
||||
@@ -986,21 +1008,43 @@ namespace ts {
|
||||
}
|
||||
|
||||
// at least one of declarations should come from non-modified source file
|
||||
const firstUnmodifiedFile = oldProgramState.program.getSourceFiles().find(
|
||||
f => !contains(oldProgramState.modifiedFilePaths, f.path) && contains(f.ambientModuleNames, moduleName)
|
||||
);
|
||||
const unmodifiedFile = ambientModuleNameToUnmodifiedFileName.get(moduleName);
|
||||
|
||||
if (!firstUnmodifiedFile) {
|
||||
if (!unmodifiedFile) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isTraceEnabled(options, host)) {
|
||||
trace(host, Diagnostics.Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified, moduleName, firstUnmodifiedFile.fileName);
|
||||
trace(host, Diagnostics.Module_0_was_resolved_as_ambient_module_declared_in_1_since_this_file_was_not_modified, moduleName, unmodifiedFile);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function canReuseProjectReferences(): boolean {
|
||||
return !forEachProjectReference(
|
||||
oldProgram!.getProjectReferences(),
|
||||
oldProgram!.getResolvedProjectReferences(),
|
||||
(oldResolvedRef, index, parent) => {
|
||||
const newRef = (parent ? parent.commandLine.projectReferences : projectReferences)![index];
|
||||
const newResolvedRef = parseProjectReferenceConfigFile(newRef);
|
||||
if (oldResolvedRef) {
|
||||
// Resolved project reference has gone missing or changed
|
||||
return !newResolvedRef || newResolvedRef.sourceFile !== oldResolvedRef.sourceFile;
|
||||
}
|
||||
else {
|
||||
// A previously-unresolved reference may be resolved now
|
||||
return newResolvedRef !== undefined;
|
||||
}
|
||||
},
|
||||
(oldProjectReferences, parent) => {
|
||||
// If array of references is changed, we cant resue old program
|
||||
const newReferences = parent ? getResolvedProjectReferenceByPath(parent.sourceFile.path)!.commandLine.projectReferences : projectReferences;
|
||||
return !arrayIsEqualTo(oldProjectReferences, newReferences, projectReferenceIsEqualTo);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function tryReuseStructureFromOldProgram(): StructureIsReused {
|
||||
if (!oldProgram) {
|
||||
return StructureIsReused.Not;
|
||||
@@ -1026,43 +1070,15 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Check if any referenced project tsconfig files are different
|
||||
|
||||
// If array of references is changed, we cant resue old program
|
||||
const oldProjectReferences = oldProgram.getProjectReferences();
|
||||
if (!arrayIsEqualTo(oldProjectReferences!, projectReferences, projectReferenceIsEqualTo)) {
|
||||
if (!canReuseProjectReferences()) {
|
||||
return oldProgram.structureIsReused = StructureIsReused.Not;
|
||||
}
|
||||
|
||||
// Check the json files for the project references
|
||||
const oldRefs = oldProgram.getResolvedProjectReferences();
|
||||
if (projectReferences) {
|
||||
// Resolved project referenced should be array if projectReferences provided are array
|
||||
Debug.assert(!!oldRefs);
|
||||
for (let i = 0; i < projectReferences.length; i++) {
|
||||
const oldRef = oldRefs![i];
|
||||
const newRef = parseProjectReferenceConfigFile(projectReferences[i]);
|
||||
if (oldRef) {
|
||||
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 (newRef !== undefined) {
|
||||
return oldProgram.structureIsReused = StructureIsReused.Not;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Resolved project referenced should be undefined if projectReferences is undefined
|
||||
Debug.assert(!oldRefs);
|
||||
resolvedProjectReferences = projectReferences.map(parseProjectReferenceConfigFile);
|
||||
}
|
||||
|
||||
// check if program source files has changed in the way that can affect structure of the program
|
||||
const newSourceFiles: SourceFile[] = [];
|
||||
const filePaths: Path[] = [];
|
||||
const modifiedSourceFiles: { oldFile: SourceFile, newFile: SourceFile }[] = [];
|
||||
oldProgram.structureIsReused = StructureIsReused.Completely;
|
||||
|
||||
@@ -1115,7 +1131,6 @@ namespace ts {
|
||||
newSourceFile.originalFileName = oldSourceFile.originalFileName;
|
||||
newSourceFile.resolvedPath = oldSourceFile.resolvedPath;
|
||||
newSourceFile.fileName = oldSourceFile.fileName;
|
||||
filePaths.push(newSourceFile.path);
|
||||
|
||||
const packageName = oldProgram.sourceFileToPackageName.get(oldSourceFile.path);
|
||||
if (packageName !== undefined) {
|
||||
@@ -1188,14 +1203,20 @@ namespace ts {
|
||||
return oldProgram.structureIsReused;
|
||||
}
|
||||
|
||||
modifiedFilePaths = modifiedSourceFiles.map(f => f.newFile.path);
|
||||
const modifiedFiles = modifiedSourceFiles.map(f => f.oldFile);
|
||||
for (const oldFile of oldSourceFiles) {
|
||||
if (!contains(modifiedFiles, oldFile)) {
|
||||
for (const moduleName of oldFile.ambientModuleNames) {
|
||||
ambientModuleNameToUnmodifiedFileName.set(moduleName, oldFile.fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
// try to verify results of module resolution
|
||||
for (const { oldFile: oldSourceFile, newFile: newSourceFile } of modifiedSourceFiles) {
|
||||
const newSourceFilePath = getNormalizedAbsolutePath(newSourceFile.originalFileName, currentDirectory);
|
||||
if (resolveModuleNamesWorker) {
|
||||
const moduleNames = getModuleNames(newSourceFile);
|
||||
const oldProgramState: OldProgramState = { program: oldProgram, oldSourceFile, modifiedFilePaths };
|
||||
const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFilePath, newSourceFile, oldProgramState);
|
||||
const resolutions = resolveModuleNamesReusingOldState(moduleNames, newSourceFilePath, newSourceFile);
|
||||
// ensure that module resolution results are still correct
|
||||
const resolutionsChanged = hasChangesInResolutions(moduleNames, resolutions, oldSourceFile.resolvedModules, moduleResolutionIsEqualTo);
|
||||
if (resolutionsChanged) {
|
||||
@@ -1209,7 +1230,7 @@ namespace ts {
|
||||
if (resolveTypeReferenceDirectiveNamesWorker) {
|
||||
// We lower-case all type references because npm automatically lowercases all packages. See GH#9824.
|
||||
const typesReferenceDirectives = map(newSourceFile.typeReferenceDirectives, ref => ref.fileName.toLocaleLowerCase());
|
||||
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFilePath);
|
||||
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typesReferenceDirectives, newSourceFilePath, getResolvedProjectReferenceToRedirect(newSourceFile.originalFileName));
|
||||
// ensure that types resolutions are still correct
|
||||
const resolutionsChanged = hasChangesInResolutions(typesReferenceDirectives, resolutions, oldSourceFile.resolvedTypeReferenceDirectiveNames, typeDirectiveIsEqualTo);
|
||||
if (resolutionsChanged) {
|
||||
@@ -1233,11 +1254,12 @@ namespace ts {
|
||||
missingFilePaths = oldProgram.getMissingFilePaths();
|
||||
|
||||
// update fileName -> file mapping
|
||||
for (let i = 0; i < newSourceFiles.length; i++) {
|
||||
filesByName.set(filePaths[i], newSourceFiles[i]);
|
||||
for (const newSourceFile of newSourceFiles) {
|
||||
const filePath = newSourceFile.path;
|
||||
addFileToFilesByName(newSourceFile, filePath, newSourceFile.resolvedPath);
|
||||
// Set the file as found during node modules search if it was found that way in old progra,
|
||||
if (oldProgram.isSourceFileFromExternalLibrary(oldProgram.getSourceFileByPath(filePaths[i])!)) {
|
||||
sourceFilesFoundSearchingNodeModules.set(filePaths[i], true);
|
||||
if (oldProgram.isSourceFileFromExternalLibrary(oldProgram.getSourceFileByPath(filePath)!)) {
|
||||
sourceFilesFoundSearchingNodeModules.set(filePath, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1248,14 +1270,6 @@ namespace ts {
|
||||
fileProcessingDiagnostics.reattachFileDiagnostics(modifiedFile.newFile);
|
||||
}
|
||||
resolvedTypeReferenceDirectives = oldProgram.getResolvedTypeReferenceDirectives();
|
||||
resolvedProjectReferences = oldProgram.getResolvedProjectReferences();
|
||||
if (resolvedProjectReferences) {
|
||||
resolvedProjectReferences.forEach(ref => {
|
||||
if (ref) {
|
||||
addProjectReferenceRedirects(ref.commandLine);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
sourceFileToPackageName = oldProgram.sourceFileToPackageName;
|
||||
redirectTargetsMap = oldProgram.redirectTargetsMap;
|
||||
@@ -1805,18 +1819,29 @@ namespace ts {
|
||||
return sourceFile.isDeclarationFile ? [] : getDeclarationDiagnosticsWorker(sourceFile, cancellationToken);
|
||||
}
|
||||
|
||||
function getOptionsDiagnostics(): Diagnostic[] {
|
||||
function getOptionsDiagnostics(): SortedReadonlyArray<Diagnostic> {
|
||||
return sortAndDeduplicateDiagnostics(concatenate(
|
||||
fileProcessingDiagnostics.getGlobalDiagnostics(),
|
||||
concatenate(
|
||||
programDiagnostics.getGlobalDiagnostics(),
|
||||
options.configFile ? programDiagnostics.getDiagnostics(options.configFile.fileName) : []
|
||||
getOptionsDiagnosticsOfConfigFile()
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
function getGlobalDiagnostics(): Diagnostic[] {
|
||||
return sortAndDeduplicateDiagnostics(getDiagnosticsProducingTypeChecker().getGlobalDiagnostics().slice());
|
||||
function getOptionsDiagnosticsOfConfigFile() {
|
||||
if (!options.configFile) { return emptyArray; }
|
||||
let diagnostics = programDiagnostics.getDiagnostics(options.configFile.fileName);
|
||||
forEachResolvedProjectReference(resolvedRef => {
|
||||
if (resolvedRef) {
|
||||
diagnostics = concatenate(diagnostics, programDiagnostics.getDiagnostics(resolvedRef.sourceFile.fileName));
|
||||
}
|
||||
});
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
function getGlobalDiagnostics(): SortedReadonlyArray<Diagnostic> {
|
||||
return rootNames.length ? sortAndDeduplicateDiagnostics(getDiagnosticsProducingTypeChecker().getGlobalDiagnostics().slice()) : emptyArray as any as SortedReadonlyArray<Diagnostic>;
|
||||
}
|
||||
|
||||
function getConfigFileParsingDiagnostics(): ReadonlyArray<Diagnostic> {
|
||||
@@ -1866,12 +1891,9 @@ namespace ts {
|
||||
|
||||
for (const node of file.statements) {
|
||||
collectModuleReferences(node, /*inAmbientModule*/ false);
|
||||
if ((file.flags & NodeFlags.PossiblyContainsDynamicImport) || isJavaScriptFile) {
|
||||
collectDynamicImportOrRequireCalls(node);
|
||||
}
|
||||
}
|
||||
if ((file.flags & NodeFlags.PossiblyContainsDynamicImport) || isJavaScriptFile) {
|
||||
collectDynamicImportOrRequireCalls(file.endOfFileToken);
|
||||
collectDynamicImportOrRequireCalls(file);
|
||||
}
|
||||
|
||||
file.imports = imports || emptyArray;
|
||||
@@ -1923,25 +1945,38 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function collectDynamicImportOrRequireCalls(node: Node): void {
|
||||
if (isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true)) {
|
||||
imports = append(imports, node.arguments[0]);
|
||||
}
|
||||
// we have to check the argument list has length of 1. We will still have to process these even though we have parsing error.
|
||||
else if (isImportCall(node) && node.arguments.length === 1 && isStringLiteralLike(node.arguments[0])) {
|
||||
imports = append(imports, node.arguments[0] as StringLiteralLike);
|
||||
}
|
||||
else if (isLiteralImportTypeNode(node)) {
|
||||
imports = append(imports, node.argument.literal);
|
||||
}
|
||||
collectDynamicImportOrRequireCallsForEachChild(node);
|
||||
if (hasJSDocNodes(node)) {
|
||||
forEach(node.jsDoc, collectDynamicImportOrRequireCallsForEachChild);
|
||||
function collectDynamicImportOrRequireCalls(file: SourceFile) {
|
||||
const r = /import|require/g;
|
||||
while (r.exec(file.text) !== null) {
|
||||
const node = getNodeAtPosition(file, r.lastIndex);
|
||||
if (isRequireCall(node, /*checkArgumentIsStringLiteralLike*/ true)) {
|
||||
imports = append(imports, node.arguments[0]);
|
||||
}
|
||||
// we have to check the argument list has length of 1. We will still have to process these even though we have parsing error.
|
||||
else if (isImportCall(node) && node.arguments.length === 1 && isStringLiteralLike(node.arguments[0])) {
|
||||
imports = append(imports, node.arguments[0] as StringLiteralLike);
|
||||
}
|
||||
else if (isLiteralImportTypeNode(node)) {
|
||||
imports = append(imports, node.argument.literal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function collectDynamicImportOrRequireCallsForEachChild(node: Node) {
|
||||
forEachChild(node, collectDynamicImportOrRequireCalls);
|
||||
/** Returns a token if position is in [start-of-leading-trivia, end), includes JSDoc only in JS files */
|
||||
function getNodeAtPosition(sourceFile: SourceFile, position: number): Node {
|
||||
let current: Node = sourceFile;
|
||||
const getContainingChild = (child: Node) => {
|
||||
if (child.pos <= position && (position < child.end || (position === child.end && (child.kind === SyntaxKind.EndOfFileToken)))) {
|
||||
return child;
|
||||
}
|
||||
};
|
||||
while (true) {
|
||||
const child = isJavaScriptFile && hasJSDocNodes(current) && forEach(current.jsDoc, getContainingChild) || forEachChild(current, getContainingChild);
|
||||
if (!child) {
|
||||
return current;
|
||||
}
|
||||
current = child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1965,7 +2000,7 @@ namespace ts {
|
||||
refFile?: SourceFile): SourceFile | undefined {
|
||||
|
||||
if (hasExtension(fileName)) {
|
||||
if (!options.allowNonTsExtensions && !forEach(supportedExtensionsWithJsonIfResolveJsonModule || supportedExtensions, extension => fileExtensionIs(host.getCanonicalFileName(fileName), extension))) {
|
||||
if (!options.allowNonTsExtensions && !forEach(supportedExtensionsWithJsonIfResolveJsonModule, extension => fileExtensionIs(host.getCanonicalFileName(fileName), extension))) {
|
||||
if (fail) fail(Diagnostics.File_0_has_unsupported_extension_The_only_supported_extensions_are_1, fileName, "'" + supportedExtensions.join("', '") + "'");
|
||||
return undefined;
|
||||
}
|
||||
@@ -2031,6 +2066,7 @@ namespace ts {
|
||||
redirect.resolvedPath = resolvedPath;
|
||||
redirect.originalFileName = originalFileName;
|
||||
redirect.redirectInfo = { redirectTarget, unredirected };
|
||||
sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0);
|
||||
Object.defineProperties(redirect, {
|
||||
id: {
|
||||
get(this: SourceFile) { return this.redirectInfo!.redirectTarget.id; },
|
||||
@@ -2088,7 +2124,7 @@ namespace ts {
|
||||
return file;
|
||||
}
|
||||
|
||||
let redirectedPath: string | undefined;
|
||||
let redirectedPath: Path | undefined;
|
||||
if (refFile) {
|
||||
const redirect = getProjectReferenceRedirect(fileName);
|
||||
if (redirect) {
|
||||
@@ -2122,7 +2158,7 @@ namespace ts {
|
||||
// Instead of creating a duplicate, just redirect to the existing one.
|
||||
const dupFile = createRedirectSourceFile(fileFromPackageId, file!, fileName, path, toPath(fileName), originalFileName); // TODO: GH#18217
|
||||
redirectTargetsMap.add(fileFromPackageId.path, fileName);
|
||||
filesByName.set(path, dupFile);
|
||||
addFileToFilesByName(dupFile, path, redirectedPath);
|
||||
sourceFileToPackageName.set(path, packageId.name);
|
||||
processingOtherFiles!.push(dupFile);
|
||||
return dupFile;
|
||||
@@ -2133,11 +2169,7 @@ namespace ts {
|
||||
sourceFileToPackageName.set(path, packageId.name);
|
||||
}
|
||||
}
|
||||
|
||||
filesByName.set(path, file);
|
||||
if (redirectedPath) {
|
||||
filesByName.set(redirectedPath, file);
|
||||
}
|
||||
addFileToFilesByName(file, path, redirectedPath);
|
||||
|
||||
if (file) {
|
||||
sourceFilesFoundSearchingNodeModules.set(path, currentNodeModulesDepth > 0);
|
||||
@@ -2180,27 +2212,109 @@ namespace ts {
|
||||
return file;
|
||||
}
|
||||
|
||||
function addFileToFilesByName(file: SourceFile | undefined, path: Path, redirectedPath: Path | undefined) {
|
||||
filesByName.set(path, file);
|
||||
if (redirectedPath) {
|
||||
filesByName.set(redirectedPath, file);
|
||||
}
|
||||
}
|
||||
|
||||
function getProjectReferenceRedirect(fileName: string): string | undefined {
|
||||
// Ignore dts or any of the non ts files
|
||||
if (!projectReferenceRedirects || fileExtensionIs(fileName, Extension.Dts) || !fileExtensionIsOneOf(fileName, supportedTSExtensions)) {
|
||||
if (!resolvedProjectReferences || !resolvedProjectReferences.length || fileExtensionIs(fileName, Extension.Dts) || !fileExtensionIsOneOf(fileName, supportedTSExtensions)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// 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
|
||||
return forEach(projectReferenceRedirects, referencedProject => {
|
||||
const referencedProject = getResolvedProjectReferenceToRedirect(fileName);
|
||||
if (!referencedProject) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const out = referencedProject.commandLine.options.outFile || referencedProject.commandLine.options.out;
|
||||
return out ?
|
||||
changeExtension(out, Extension.Dts) :
|
||||
getOutputDeclarationFileName(fileName, referencedProject.commandLine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the referenced project if the file is input file from that reference project
|
||||
*/
|
||||
function getResolvedProjectReferenceToRedirect(fileName: string) {
|
||||
return forEachResolvedProjectReference((referencedProject, referenceProjectPath) => {
|
||||
// not input file from the referenced project, ignore
|
||||
if (!contains(referencedProject.fileNames, fileName, isSameFile)) {
|
||||
if (!referencedProject ||
|
||||
toPath(options.configFilePath!) === referenceProjectPath ||
|
||||
!contains(referencedProject.commandLine.fileNames, fileName, isSameFile)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const out = referencedProject.options.outFile || referencedProject.options.out;
|
||||
return out ?
|
||||
changeExtension(out, Extension.Dts) :
|
||||
getOutputDeclarationFileName(fileName, referencedProject);
|
||||
return referencedProject;
|
||||
});
|
||||
}
|
||||
|
||||
function forEachResolvedProjectReference<T>(
|
||||
cb: (resolvedProjectReference: ResolvedProjectReference | undefined, resolvedProjectReferencePath: Path) => T | undefined
|
||||
): T | undefined {
|
||||
return forEachProjectReference(projectReferences, resolvedProjectReferences, (resolvedRef, index, parent) => {
|
||||
const ref = (parent ? parent.commandLine.projectReferences : projectReferences)![index];
|
||||
const resolvedRefPath = toPath(resolveProjectReferencePath(ref));
|
||||
return cb(resolvedRef, resolvedRefPath);
|
||||
});
|
||||
}
|
||||
|
||||
function forEachProjectReference<T>(
|
||||
projectReferences: ReadonlyArray<ProjectReference> | undefined,
|
||||
resolvedProjectReferences: ReadonlyArray<ResolvedProjectReference | undefined> | undefined,
|
||||
cbResolvedRef: (resolvedRef: ResolvedProjectReference | undefined, index: number, parent: ResolvedProjectReference | undefined) => T | undefined,
|
||||
cbRef?: (projectReferences: ReadonlyArray<ProjectReference> | undefined, parent: ResolvedProjectReference | undefined) => T | undefined
|
||||
): T | undefined {
|
||||
let seenResolvedRefs: ResolvedProjectReference[] | undefined;
|
||||
|
||||
return worker(projectReferences, resolvedProjectReferences, /*parent*/ undefined, cbResolvedRef, cbRef);
|
||||
|
||||
function worker(
|
||||
projectReferences: ReadonlyArray<ProjectReference> | undefined,
|
||||
resolvedProjectReferences: ReadonlyArray<ResolvedProjectReference | undefined> | undefined,
|
||||
parent: ResolvedProjectReference | undefined,
|
||||
cbResolvedRef: (resolvedRef: ResolvedProjectReference | undefined, index: number, parent: ResolvedProjectReference | undefined) => T | undefined,
|
||||
cbRef?: (projectReferences: ReadonlyArray<ProjectReference> | undefined, parent: ResolvedProjectReference | undefined) => T | undefined,
|
||||
): T | undefined {
|
||||
|
||||
// Visit project references first
|
||||
if (cbRef) {
|
||||
const result = cbRef(projectReferences, parent);
|
||||
if (result) { return result; }
|
||||
}
|
||||
|
||||
return forEach(resolvedProjectReferences, (resolvedRef, index) => {
|
||||
if (contains(seenResolvedRefs, resolvedRef)) {
|
||||
// ignore recursives
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const result = cbResolvedRef(resolvedRef, index, parent);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!resolvedRef) return undefined;
|
||||
|
||||
(seenResolvedRefs || (seenResolvedRefs = [])).push(resolvedRef);
|
||||
return worker(resolvedRef.commandLine.projectReferences, resolvedRef.references, resolvedRef, cbResolvedRef, cbRef);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getResolvedProjectReferenceByPath(projectReferencePath: Path): ResolvedProjectReference | undefined {
|
||||
if (!projectReferenceRedirects) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return projectReferenceRedirects.get(projectReferencePath) || undefined;
|
||||
}
|
||||
|
||||
function processReferencedFiles(file: SourceFile, isDefaultLib: boolean) {
|
||||
forEach(file.referencedFiles, ref => {
|
||||
const referencedFileName = resolveTripleslashReference(ref.fileName, file.originalFileName);
|
||||
@@ -2215,7 +2329,7 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
|
||||
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeDirectives, file.originalFileName);
|
||||
const resolutions = resolveTypeReferenceDirectiveNamesWorker(typeDirectives, file.originalFileName, getResolvedProjectReferenceToRedirect(file.originalFileName));
|
||||
|
||||
for (let i = 0; i < typeDirectives.length; i++) {
|
||||
const ref = file.typeReferenceDirectives[i];
|
||||
@@ -2227,7 +2341,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function processTypeReferenceDirective(typeReferenceDirective: string, resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective,
|
||||
function processTypeReferenceDirective(typeReferenceDirective: string, resolvedTypeReferenceDirective?: ResolvedTypeReferenceDirective,
|
||||
refFile?: SourceFile, refPos?: number, refEnd?: number): void {
|
||||
|
||||
// If we already found this library as a primary reference - nothing to do
|
||||
@@ -2237,6 +2351,8 @@ namespace ts {
|
||||
}
|
||||
let saveResolution = true;
|
||||
if (resolvedTypeReferenceDirective) {
|
||||
if (resolvedTypeReferenceDirective.isExternalLibraryImport) currentNodeModulesDepth++;
|
||||
|
||||
if (resolvedTypeReferenceDirective.primary) {
|
||||
// resolved from the primary path
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName!, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd); // TODO: GH#18217
|
||||
@@ -2265,6 +2381,8 @@ namespace ts {
|
||||
processSourceFile(resolvedTypeReferenceDirective.resolvedFileName!, /*isDefaultLib*/ false, /*ignoreNoDefaultLib*/ false, resolvedTypeReferenceDirective.packageId, refFile, refPos, refEnd);
|
||||
}
|
||||
}
|
||||
|
||||
if (resolvedTypeReferenceDirective.isExternalLibraryImport) currentNodeModulesDepth--;
|
||||
}
|
||||
else {
|
||||
fileProcessingDiagnostics.add(createDiagnostic(refFile!, refPos!, refEnd!, Diagnostics.Cannot_find_type_definition_file_for_0, typeReferenceDirective)); // TODO: GH#18217
|
||||
@@ -2310,8 +2428,7 @@ namespace ts {
|
||||
if (file.imports.length || file.moduleAugmentations.length) {
|
||||
// Because global augmentation doesn't have string literal name, we can check for global augmentation as such.
|
||||
const moduleNames = getModuleNames(file);
|
||||
const oldProgramState: OldProgramState = { program: oldProgram, oldSourceFile: oldProgram && oldProgram.getSourceFile(file.fileName), modifiedFilePaths };
|
||||
const resolutions = resolveModuleNamesReusingOldState(moduleNames, getNormalizedAbsolutePath(file.originalFileName, currentDirectory), file, oldProgramState);
|
||||
const resolutions = resolveModuleNamesReusingOldState(moduleNames, getNormalizedAbsolutePath(file.originalFileName, currentDirectory), file);
|
||||
Debug.assert(resolutions.length === moduleNames.length);
|
||||
for (let i = 0; i < moduleNames.length; i++) {
|
||||
const resolution = resolutions[i];
|
||||
@@ -2388,22 +2505,37 @@ namespace ts {
|
||||
return allFilesBelongToPath;
|
||||
}
|
||||
|
||||
function parseProjectReferenceConfigFile(ref: ProjectReference): { commandLine: ParsedCommandLine, sourceFile: SourceFile } | undefined {
|
||||
function parseProjectReferenceConfigFile(ref: ProjectReference): ResolvedProjectReference | undefined {
|
||||
if (!projectReferenceRedirects) {
|
||||
projectReferenceRedirects = createMap<ResolvedProjectReference | false>();
|
||||
}
|
||||
|
||||
// The actual filename (i.e. add "/tsconfig.json" if necessary)
|
||||
const refPath = resolveProjectReferencePath(ref);
|
||||
const sourceFilePath = toPath(refPath);
|
||||
const fromCache = projectReferenceRedirects.get(sourceFilePath);
|
||||
if (fromCache !== undefined) {
|
||||
return fromCache || undefined;
|
||||
}
|
||||
|
||||
// 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 | undefined;
|
||||
addFileToFilesByName(sourceFile, sourceFilePath, /*redirectedPath*/ undefined);
|
||||
if (sourceFile === undefined) {
|
||||
projectReferenceRedirects.set(sourceFilePath, false);
|
||||
return undefined;
|
||||
}
|
||||
sourceFile.path = toPath(refPath);
|
||||
sourceFile.path = sourceFilePath;
|
||||
sourceFile.resolvedPath = sourceFilePath;
|
||||
sourceFile.originalFileName = refPath;
|
||||
const commandLine = parseJsonSourceFileConfigFileContent(sourceFile, configParsingHost, basePath, /*existingOptions*/ undefined, refPath);
|
||||
return { commandLine, sourceFile };
|
||||
}
|
||||
|
||||
function addProjectReferenceRedirects(referencedProject: ParsedCommandLine) {
|
||||
(projectReferenceRedirects || (projectReferenceRedirects = [])).push(referencedProject);
|
||||
const resolvedRef: ResolvedProjectReference = { commandLine, sourceFile };
|
||||
projectReferenceRedirects.set(sourceFilePath, resolvedRef);
|
||||
if (commandLine.projectReferences) {
|
||||
resolvedRef.references = commandLine.projectReferences.map(parseProjectReferenceConfigFile);
|
||||
}
|
||||
return resolvedRef;
|
||||
}
|
||||
|
||||
function verifyCompilerOptions() {
|
||||
@@ -2448,30 +2580,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
const out = resolvedRefOpts.outFile || resolvedRefOpts.out;
|
||||
if (out) {
|
||||
if (!host.fileExists(out)) {
|
||||
createDiagnosticForReference(i, Diagnostics.Output_file_0_from_project_1_does_not_exist, out, ref.path);
|
||||
}
|
||||
}
|
||||
else {
|
||||
createDiagnosticForReference(i, Diagnostics.Cannot_prepend_project_0_because_it_does_not_have_outFile_set, ref.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
verifyProjectReferences();
|
||||
|
||||
// List of collected files is complete; validate exhautiveness if this is a project with a file list
|
||||
if (options.composite) {
|
||||
@@ -2560,13 +2669,13 @@ namespace ts {
|
||||
const languageVersion = options.target || ScriptTarget.ES3;
|
||||
const outFile = options.outFile || options.out;
|
||||
|
||||
const firstNonAmbientExternalModuleSourceFile = forEach(files, f => isExternalModule(f) && !f.isDeclarationFile ? f : undefined);
|
||||
const firstNonAmbientExternalModuleSourceFile = find(files, f => isExternalModule(f) && !f.isDeclarationFile);
|
||||
if (options.isolatedModules) {
|
||||
if (options.module === ModuleKind.None && languageVersion < ScriptTarget.ES2015) {
|
||||
createDiagnosticForOptionName(Diagnostics.Option_isolatedModules_can_only_be_used_when_either_option_module_is_provided_or_option_target_is_ES2015_or_higher, "isolatedModules", "target");
|
||||
}
|
||||
|
||||
const firstNonExternalModuleSourceFile = forEach(files, f => !isExternalModule(f) && !f.isDeclarationFile ? f : undefined);
|
||||
const firstNonExternalModuleSourceFile = find(files, f => !isExternalModule(f) && !f.isDeclarationFile && f.scriptKind !== ScriptKind.JSON);
|
||||
if (firstNonExternalModuleSourceFile) {
|
||||
const span = getErrorSpanForNode(firstNonExternalModuleSourceFile, firstNonExternalModuleSourceFile);
|
||||
programDiagnostics.add(createFileDiagnostic(firstNonExternalModuleSourceFile, span.start, span.length, Diagnostics.Cannot_compile_namespaces_when_the_isolatedModules_flag_is_provided));
|
||||
@@ -2609,7 +2718,7 @@ namespace ts {
|
||||
const dir = getCommonSourceDirectory();
|
||||
|
||||
// If we failed to find a good common directory, but outDir is specified and at least one of our files is on a windows drive/URL/other resource, add a failure
|
||||
if (options.outDir && dir === "" && forEach(files, file => getRootLength(file.fileName) > 1)) {
|
||||
if (options.outDir && dir === "" && files.some(file => getRootLength(file.fileName) > 1)) {
|
||||
createDiagnosticForOptionName(Diagnostics.Cannot_find_the_common_subdirectory_path_for_the_input_files, "outDir");
|
||||
}
|
||||
}
|
||||
@@ -2689,6 +2798,36 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function verifyProjectReferences() {
|
||||
forEachProjectReference(projectReferences, resolvedProjectReferences, (resolvedRef, index, parent) => {
|
||||
const ref = (parent ? parent.commandLine.projectReferences : projectReferences)![index];
|
||||
const parentFile = parent && parent.sourceFile as JsonSourceFile;
|
||||
if (!resolvedRef) {
|
||||
createDiagnosticForReference(parentFile, index, Diagnostics.File_0_not_found, ref.path);
|
||||
return;
|
||||
}
|
||||
const options = resolvedRef.commandLine.options;
|
||||
if (!options.composite) {
|
||||
// ok to not have composite if the current program is container only
|
||||
const inputs = parent ? parent.commandLine.fileNames : rootNames;
|
||||
if (inputs.length) {
|
||||
createDiagnosticForReference(parentFile, index, Diagnostics.Referenced_project_0_must_have_setting_composite_Colon_true, ref.path);
|
||||
}
|
||||
}
|
||||
if (ref.prepend) {
|
||||
const out = options.outFile || options.out;
|
||||
if (out) {
|
||||
if (!host.fileExists(out)) {
|
||||
createDiagnosticForReference(parentFile, index, Diagnostics.Output_file_0_from_project_1_does_not_exist, out, ref.path);
|
||||
}
|
||||
}
|
||||
else {
|
||||
createDiagnosticForReference(parentFile, index, Diagnostics.Cannot_prepend_project_0_because_it_does_not_have_outFile_set, ref.path);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createDiagnosticForOptionPathKeyValue(key: string, valueIndex: number, message: DiagnosticMessage, arg0: string | number, arg1: string | number, arg2?: string | number) {
|
||||
let needCompilerDiagnostic = true;
|
||||
const pathsSyntax = getOptionPathsSyntax();
|
||||
@@ -2745,10 +2884,11 @@ 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();
|
||||
function createDiagnosticForReference(sourceFile: JsonSourceFile | undefined, index: number, message: DiagnosticMessage, arg0?: string | number, arg1?: string | number) {
|
||||
const referencesSyntax = firstDefined(getTsConfigPropArray(sourceFile || options.configFile, "references"),
|
||||
property => isArrayLiteralExpression(property.initializer) ? property.initializer : undefined);
|
||||
if (referencesSyntax && referencesSyntax.elements.length > index) {
|
||||
programDiagnostics.add(createDiagnosticForNodeInSourceFile(options.configFile!, referencesSyntax.elements[index], message, arg0, arg1));
|
||||
programDiagnostics.add(createDiagnosticForNodeInSourceFile(sourceFile || options.configFile!, referencesSyntax.elements[index], message, arg0, arg1));
|
||||
}
|
||||
else {
|
||||
programDiagnostics.add(createCompilerDiagnostic(message, arg0, arg1));
|
||||
@@ -2765,22 +2905,6 @@ 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)!; // TODO: GH#18217
|
||||
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
|
||||
@@ -2862,7 +2986,8 @@ namespace ts {
|
||||
readFile: f => host.readFile(f),
|
||||
useCaseSensitiveFileNames: host.useCaseSensitiveFileNames(),
|
||||
getCurrentDirectory: () => host.getCurrentDirectory(),
|
||||
onUnRecoverableConfigFileDiagnostic: () => undefined
|
||||
onUnRecoverableConfigFileDiagnostic: () => undefined,
|
||||
trace: host.trace ? (s) => host.trace!(s) : undefined
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -5,12 +5,13 @@ namespace ts {
|
||||
startRecordingFilesWithChangedResolutions(): void;
|
||||
finishRecordingFilesWithChangedResolutions(): Path[] | undefined;
|
||||
|
||||
resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined): ResolvedModuleFull[];
|
||||
resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference?: ResolvedProjectReference): (ResolvedModuleFull | undefined)[];
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): CachedResolvedModuleWithFailedLookupLocations | undefined;
|
||||
resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): (ResolvedTypeReferenceDirective | undefined)[];
|
||||
|
||||
invalidateResolutionOfFile(filePath: Path): void;
|
||||
removeResolutionsOfFile(filePath: Path): void;
|
||||
removeResolutionsFromProjectReferenceRedirects(filePath: Path): void;
|
||||
setFilesWithInvalidatedNonRelativeUnresolvedImports(filesWithUnresolvedImports: Map<ReadonlyArray<string>>): void;
|
||||
createHasInvalidatedResolution(forceAllFilesAsInvalidated?: boolean): HasInvalidatedResolution;
|
||||
|
||||
@@ -68,7 +69,10 @@ namespace ts {
|
||||
dir: string;
|
||||
dirPath: Path;
|
||||
nonRecursive?: boolean;
|
||||
ignore?: true;
|
||||
}
|
||||
|
||||
export function isPathInNodeModulesStartingWithDot(path: Path) {
|
||||
return stringContains(path, "/node_modules/.");
|
||||
}
|
||||
|
||||
export const maxNumberOfFilesToIterateForInvalidation = 256;
|
||||
@@ -79,7 +83,7 @@ namespace ts {
|
||||
export function createResolutionCache(resolutionHost: ResolutionCacheHost, rootDirForResolution: string | undefined, logChangesWhenResolvingModule: boolean): ResolutionCache {
|
||||
let filesWithChangedSetOfUnresolvedImports: Path[] | undefined;
|
||||
let filesWithInvalidatedResolutions: Map<true> | undefined;
|
||||
let filesWithInvalidatedNonRelativeUnresolvedImports: Map<ReadonlyArray<string>> | undefined;
|
||||
let filesWithInvalidatedNonRelativeUnresolvedImports: ReadonlyMap<ReadonlyArray<string>> | undefined;
|
||||
let allFilesHaveInvalidatedResolution = false;
|
||||
const nonRelativeExternalModuleResolutions = createMultiMap<ResolutionWithFailedLookupLocations>();
|
||||
|
||||
@@ -90,17 +94,17 @@ namespace ts {
|
||||
// The key in the map is source file's path.
|
||||
// The values are Map of resolutions with key being name lookedup.
|
||||
const resolvedModuleNames = createMap<Map<CachedResolvedModuleWithFailedLookupLocations>>();
|
||||
const perDirectoryResolvedModuleNames = createMap<Map<CachedResolvedModuleWithFailedLookupLocations>>();
|
||||
const nonRelaticeModuleNameCache = createMap<PerModuleNameCache>();
|
||||
const perDirectoryResolvedModuleNames: CacheWithRedirects<Map<CachedResolvedModuleWithFailedLookupLocations>> = createCacheWithRedirects();
|
||||
const nonRelativeModuleNameCache: CacheWithRedirects<PerModuleNameCache> = createCacheWithRedirects();
|
||||
const moduleResolutionCache = createModuleResolutionCacheWithMaps(
|
||||
perDirectoryResolvedModuleNames,
|
||||
nonRelaticeModuleNameCache,
|
||||
nonRelativeModuleNameCache,
|
||||
getCurrentDirectory(),
|
||||
resolutionHost.getCanonicalFileName
|
||||
);
|
||||
|
||||
const resolvedTypeReferenceDirectives = createMap<Map<CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations>>();
|
||||
const perDirectoryResolvedTypeReferenceDirectives = createMap<Map<CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations>>();
|
||||
const perDirectoryResolvedTypeReferenceDirectives: CacheWithRedirects<Map<CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations>> = createCacheWithRedirects();
|
||||
|
||||
/**
|
||||
* These are the extensions that failed lookup files will have by default,
|
||||
@@ -128,6 +132,7 @@ namespace ts {
|
||||
resolveModuleNames,
|
||||
getResolvedModuleWithFailedLookupLocationsFromCache,
|
||||
resolveTypeReferenceDirectives,
|
||||
removeResolutionsFromProjectReferenceRedirects,
|
||||
removeResolutionsOfFile,
|
||||
invalidateResolutionOfFile,
|
||||
setFilesWithInvalidatedNonRelativeUnresolvedImports,
|
||||
@@ -199,7 +204,7 @@ namespace ts {
|
||||
|
||||
function clearPerDirectoryResolutions() {
|
||||
perDirectoryResolvedModuleNames.clear();
|
||||
nonRelaticeModuleNameCache.clear();
|
||||
nonRelativeModuleNameCache.clear();
|
||||
perDirectoryResolvedTypeReferenceDirectives.clear();
|
||||
nonRelativeExternalModuleResolutions.forEach(watchFailedLookupLocationOfNonRelativeModuleResolutions);
|
||||
nonRelativeExternalModuleResolutions.clear();
|
||||
@@ -217,8 +222,8 @@ namespace ts {
|
||||
});
|
||||
}
|
||||
|
||||
function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost): CachedResolvedModuleWithFailedLookupLocations {
|
||||
const primaryResult = ts.resolveModuleName(moduleName, containingFile, compilerOptions, host, moduleResolutionCache);
|
||||
function resolveModuleName(moduleName: string, containingFile: string, compilerOptions: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference): CachedResolvedModuleWithFailedLookupLocations {
|
||||
const primaryResult = ts.resolveModuleName(moduleName, containingFile, compilerOptions, host, moduleResolutionCache, redirectedReference);
|
||||
// return result immediately only if global cache support is not enabled or if it is .ts, .tsx or .d.ts
|
||||
if (!resolutionHost.getGlobalCache) {
|
||||
return primaryResult;
|
||||
@@ -240,41 +245,52 @@ namespace ts {
|
||||
}
|
||||
|
||||
function resolveNamesWithLocalCache<T extends ResolutionWithFailedLookupLocations, R extends ResolutionWithResolvedFileName>(
|
||||
names: string[],
|
||||
names: ReadonlyArray<string>,
|
||||
containingFile: string,
|
||||
redirectedReference: ResolvedProjectReference | undefined,
|
||||
cache: Map<Map<T>>,
|
||||
perDirectoryCache: Map<Map<T>>,
|
||||
loader: (name: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost) => T,
|
||||
perDirectoryCacheWithRedirects: CacheWithRedirects<Map<T>>,
|
||||
loader: (name: string, containingFile: string, options: CompilerOptions, host: ModuleResolutionHost, redirectedReference?: ResolvedProjectReference) => T,
|
||||
getResolutionWithResolvedFileName: GetResolutionWithResolvedFileName<T, R>,
|
||||
reusedNames: string[] | undefined,
|
||||
logChanges: boolean): R[] {
|
||||
shouldRetryResolution: (t: T) => boolean,
|
||||
reusedNames: ReadonlyArray<string> | undefined,
|
||||
logChanges: boolean): (R | undefined)[] {
|
||||
|
||||
const path = resolutionHost.toPath(containingFile);
|
||||
const resolutionsInFile = cache.get(path) || cache.set(path, createMap()).get(path)!;
|
||||
const dirPath = getDirectoryPath(path);
|
||||
const perDirectoryCache = perDirectoryCacheWithRedirects.getOrCreateMapOfCacheRedirects(redirectedReference);
|
||||
let perDirectoryResolution = perDirectoryCache.get(dirPath);
|
||||
if (!perDirectoryResolution) {
|
||||
perDirectoryResolution = createMap();
|
||||
perDirectoryCache.set(dirPath, perDirectoryResolution);
|
||||
}
|
||||
const resolvedModules: R[] = [];
|
||||
const resolvedModules: (R | undefined)[] = [];
|
||||
const compilerOptions = resolutionHost.getCompilationSettings();
|
||||
const hasInvalidatedNonRelativeUnresolvedImport = logChanges && isFileWithInvalidatedNonRelativeUnresolvedImports(path);
|
||||
|
||||
// All the resolutions in this file are invalidated if this file wasnt resolved using same redirect
|
||||
const program = resolutionHost.getCurrentProgram();
|
||||
const oldRedirect = program && program.getResolvedProjectReferenceToRedirect(containingFile);
|
||||
const unmatchedRedirects = oldRedirect ?
|
||||
!redirectedReference || redirectedReference.sourceFile.path !== oldRedirect.sourceFile.path :
|
||||
!!redirectedReference;
|
||||
|
||||
const seenNamesInFile = createMap<true>();
|
||||
for (const name of names) {
|
||||
let resolution = resolutionsInFile.get(name);
|
||||
// Resolution is valid if it is present and not invalidated
|
||||
if (!seenNamesInFile.has(name) &&
|
||||
allFilesHaveInvalidatedResolution || !resolution || resolution.isInvalidated ||
|
||||
allFilesHaveInvalidatedResolution || unmatchedRedirects || !resolution || resolution.isInvalidated ||
|
||||
// If the name is unresolved import that was invalidated, recalculate
|
||||
(hasInvalidatedNonRelativeUnresolvedImport && !isExternalModuleNameRelative(name) && !getResolutionWithResolvedFileName(resolution))) {
|
||||
(hasInvalidatedNonRelativeUnresolvedImport && !isExternalModuleNameRelative(name) && shouldRetryResolution(resolution))) {
|
||||
const existingResolution = resolution;
|
||||
const resolutionInDirectory = perDirectoryResolution.get(name);
|
||||
if (resolutionInDirectory) {
|
||||
resolution = resolutionInDirectory;
|
||||
}
|
||||
else {
|
||||
resolution = loader(name, containingFile, compilerOptions, resolutionHost);
|
||||
resolution = loader(name, containingFile, compilerOptions, resolutionHost, redirectedReference);
|
||||
perDirectoryResolution.set(name, resolution);
|
||||
}
|
||||
resolutionsInFile.set(name, resolution);
|
||||
@@ -291,7 +307,7 @@ namespace ts {
|
||||
}
|
||||
Debug.assert(resolution !== undefined && !resolution.isInvalidated);
|
||||
seenNamesInFile.set(name, true);
|
||||
resolvedModules.push(getResolutionWithResolvedFileName(resolution)!); // TODO: GH#18217
|
||||
resolvedModules.push(getResolutionWithResolvedFileName(resolution));
|
||||
}
|
||||
|
||||
// Stop watching and remove the unused name
|
||||
@@ -323,20 +339,22 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[] {
|
||||
function resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): (ResolvedTypeReferenceDirective | undefined)[] {
|
||||
return resolveNamesWithLocalCache<CachedResolvedTypeReferenceDirectiveWithFailedLookupLocations, ResolvedTypeReferenceDirective>(
|
||||
typeDirectiveNames, containingFile,
|
||||
typeDirectiveNames, containingFile, redirectedReference,
|
||||
resolvedTypeReferenceDirectives, perDirectoryResolvedTypeReferenceDirectives,
|
||||
resolveTypeReferenceDirective, getResolvedTypeReferenceDirective,
|
||||
/*shouldRetryResolution*/ resolution => resolution.resolvedTypeReferenceDirective === undefined,
|
||||
/*reusedNames*/ undefined, /*logChanges*/ false
|
||||
);
|
||||
}
|
||||
|
||||
function resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined): ResolvedModuleFull[] {
|
||||
function resolveModuleNames(moduleNames: string[], containingFile: string, reusedNames: string[] | undefined, redirectedReference?: ResolvedProjectReference): (ResolvedModuleFull | undefined)[] {
|
||||
return resolveNamesWithLocalCache<CachedResolvedModuleWithFailedLookupLocations, ResolvedModuleFull>(
|
||||
moduleNames, containingFile,
|
||||
moduleNames, containingFile, redirectedReference,
|
||||
resolvedModuleNames, perDirectoryResolvedModuleNames,
|
||||
resolveModuleName, getResolvedModule,
|
||||
/*shouldRetryResolution*/ resolution => !resolution.resolvedModule || !resolutionExtensionIsTSOrJson(resolution.resolvedModule.extension),
|
||||
reusedNames, logChangesWhenResolvingModule
|
||||
);
|
||||
}
|
||||
@@ -389,14 +407,7 @@ namespace ts {
|
||||
return true;
|
||||
}
|
||||
|
||||
function filterFSRootDirectoriesToWatch(watchPath: DirectoryOfFailedLookupWatch, dirPath: Path): DirectoryOfFailedLookupWatch {
|
||||
if (!canWatchDirectory(dirPath)) {
|
||||
watchPath.ignore = true;
|
||||
}
|
||||
return watchPath;
|
||||
}
|
||||
|
||||
function getDirectoryToWatchFailedLookupLocation(failedLookupLocation: string, failedLookupLocationPath: Path): DirectoryOfFailedLookupWatch {
|
||||
function getDirectoryToWatchFailedLookupLocation(failedLookupLocation: string, failedLookupLocationPath: Path): DirectoryOfFailedLookupWatch | undefined {
|
||||
if (isInDirectoryPath(rootPath, failedLookupLocationPath)) {
|
||||
// Ensure failed look up is normalized path
|
||||
failedLookupLocation = isRootedDiskPath(failedLookupLocation) ? normalizePath(failedLookupLocation) : getNormalizedAbsolutePath(failedLookupLocation, getCurrentDirectory());
|
||||
@@ -418,16 +429,16 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
function getDirectoryToWatchFromFailedLookupLocationDirectory(dir: string, dirPath: Path) {
|
||||
function getDirectoryToWatchFromFailedLookupLocationDirectory(dir: string, dirPath: Path): DirectoryOfFailedLookupWatch | undefined {
|
||||
// If directory path contains node module, get the most parent node_modules directory for watching
|
||||
while (stringContains(dirPath, nodeModulesPathPart)) {
|
||||
while (pathContainsNodeModules(dirPath)) {
|
||||
dir = getDirectoryPath(dir);
|
||||
dirPath = getDirectoryPath(dirPath);
|
||||
}
|
||||
|
||||
// If the directory is node_modules use it to watch, always watch it recursively
|
||||
if (isNodeModulesDirectory(dirPath)) {
|
||||
return filterFSRootDirectoriesToWatch({ dir, dirPath }, getDirectoryPath(dirPath));
|
||||
return canWatchDirectory(getDirectoryPath(dirPath)) ? { dir, dirPath } : undefined;
|
||||
}
|
||||
|
||||
let nonRecursive = true;
|
||||
@@ -447,7 +458,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
return filterFSRootDirectoriesToWatch({ dir: subDirectory || dir, dirPath: subDirectoryPath || dirPath, nonRecursive }, dirPath);
|
||||
return canWatchDirectory(dirPath) ? { dir: subDirectory || dir, dirPath: subDirectoryPath || dirPath, nonRecursive } : undefined;
|
||||
}
|
||||
|
||||
function isPathWithDefaultFailedLookupExtension(path: Path) {
|
||||
@@ -479,8 +490,9 @@ namespace ts {
|
||||
let setAtRoot = false;
|
||||
for (const failedLookupLocation of failedLookupLocations) {
|
||||
const failedLookupLocationPath = resolutionHost.toPath(failedLookupLocation);
|
||||
const { dir, dirPath, nonRecursive, ignore } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
|
||||
if (!ignore) {
|
||||
const toWatch = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
|
||||
if (toWatch) {
|
||||
const { dir, dirPath, nonRecursive } = toWatch;
|
||||
// If the failed lookup location path is not one of the supported extensions,
|
||||
// store it in the custom path
|
||||
if (!isPathWithDefaultFailedLookupExtension(failedLookupLocationPath)) {
|
||||
@@ -539,8 +551,9 @@ namespace ts {
|
||||
let removeAtRoot = false;
|
||||
for (const failedLookupLocation of failedLookupLocations) {
|
||||
const failedLookupLocationPath = resolutionHost.toPath(failedLookupLocation);
|
||||
const { dirPath, ignore } = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
|
||||
if (!ignore) {
|
||||
const toWatch = getDirectoryToWatchFailedLookupLocation(failedLookupLocation, failedLookupLocationPath);
|
||||
if (toWatch) {
|
||||
const { dirPath } = toWatch;
|
||||
const refCount = customFailedLookupPaths.get(failedLookupLocationPath);
|
||||
if (refCount) {
|
||||
if (refCount === 1) {
|
||||
@@ -594,6 +607,20 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function removeResolutionsFromProjectReferenceRedirects(filePath: Path) {
|
||||
if (!fileExtensionIs(filePath, Extension.Json)) { return; }
|
||||
|
||||
const program = resolutionHost.getCurrentProgram();
|
||||
if (!program) { return; }
|
||||
|
||||
// If this file is input file for the referenced project, get it
|
||||
const resolvedProjectReference = program.getResolvedProjectReferenceByPath(filePath);
|
||||
if (!resolvedProjectReference) { return; }
|
||||
|
||||
// filePath is for the projectReference and the containing file is from this project reference, invalidate the resolution
|
||||
resolvedProjectReference.commandLine.fileNames.forEach(f => removeResolutionsOfFile(resolutionHost.toPath(f)));
|
||||
}
|
||||
|
||||
function removeResolutionsOfFile(filePath: Path) {
|
||||
removeResolutionsOfFileFromCache(resolvedModuleNames, filePath);
|
||||
removeResolutionsOfFileFromCache(resolvedTypeReferenceDirectives, filePath);
|
||||
@@ -655,7 +682,7 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
function setFilesWithInvalidatedNonRelativeUnresolvedImports(filesMap: Map<ReadonlyArray<string>>) {
|
||||
function setFilesWithInvalidatedNonRelativeUnresolvedImports(filesMap: ReadonlyMap<ReadonlyArray<string>>) {
|
||||
Debug.assert(filesWithInvalidatedNonRelativeUnresolvedImports === filesMap || filesWithInvalidatedNonRelativeUnresolvedImports === undefined);
|
||||
filesWithInvalidatedNonRelativeUnresolvedImports = filesMap;
|
||||
}
|
||||
@@ -668,6 +695,9 @@ namespace ts {
|
||||
isChangedFailedLookupLocation = location => isInDirectoryPath(fileOrDirectoryPath, resolutionHost.toPath(location));
|
||||
}
|
||||
else {
|
||||
// If something to do with folder/file starting with "." in node_modules folder, skip it
|
||||
if (isPathInNodeModulesStartingWithDot(fileOrDirectoryPath)) return false;
|
||||
|
||||
// Some file or directory in the watching directory is created
|
||||
// Return early if it does not have any of the watching extension or not the custom failed lookup path
|
||||
const dirOfFileOrDirectory = getDirectoryPath(fileOrDirectoryPath);
|
||||
@@ -712,8 +742,8 @@ namespace ts {
|
||||
if (isInDirectoryPath(rootPath, typeRootPath)) {
|
||||
return rootPath;
|
||||
}
|
||||
const { dirPath, ignore } = getDirectoryToWatchFromFailedLookupLocationDirectory(typeRoot, typeRootPath);
|
||||
return !ignore && directoryWatchesOfFailedLookups.has(dirPath) ? dirPath : undefined;
|
||||
const toWatch = getDirectoryToWatchFromFailedLookupLocationDirectory(typeRoot, typeRootPath);
|
||||
return toWatch && directoryWatchesOfFailedLookups.has(toWatch.dirPath) ? toWatch.dirPath : undefined;
|
||||
}
|
||||
|
||||
function createTypeRootsWatch(typeRootPath: Path, typeRoot: string): FileWatcher {
|
||||
|
||||
+165
-138
@@ -60,81 +60,88 @@ namespace ts {
|
||||
tryScan<T>(callback: () => T): T;
|
||||
}
|
||||
|
||||
const textToToken = createMapFromTemplate({
|
||||
"abstract": SyntaxKind.AbstractKeyword,
|
||||
"any": SyntaxKind.AnyKeyword,
|
||||
"as": SyntaxKind.AsKeyword,
|
||||
"boolean": SyntaxKind.BooleanKeyword,
|
||||
"break": SyntaxKind.BreakKeyword,
|
||||
"case": SyntaxKind.CaseKeyword,
|
||||
"catch": SyntaxKind.CatchKeyword,
|
||||
"class": SyntaxKind.ClassKeyword,
|
||||
"continue": SyntaxKind.ContinueKeyword,
|
||||
"const": SyntaxKind.ConstKeyword,
|
||||
"constructor": SyntaxKind.ConstructorKeyword,
|
||||
"debugger": SyntaxKind.DebuggerKeyword,
|
||||
"declare": SyntaxKind.DeclareKeyword,
|
||||
"default": SyntaxKind.DefaultKeyword,
|
||||
"delete": SyntaxKind.DeleteKeyword,
|
||||
"do": SyntaxKind.DoKeyword,
|
||||
"else": SyntaxKind.ElseKeyword,
|
||||
"enum": SyntaxKind.EnumKeyword,
|
||||
"export": SyntaxKind.ExportKeyword,
|
||||
"extends": SyntaxKind.ExtendsKeyword,
|
||||
"false": SyntaxKind.FalseKeyword,
|
||||
"finally": SyntaxKind.FinallyKeyword,
|
||||
"for": SyntaxKind.ForKeyword,
|
||||
"from": SyntaxKind.FromKeyword,
|
||||
"function": SyntaxKind.FunctionKeyword,
|
||||
"get": SyntaxKind.GetKeyword,
|
||||
"if": SyntaxKind.IfKeyword,
|
||||
"implements": SyntaxKind.ImplementsKeyword,
|
||||
"import": SyntaxKind.ImportKeyword,
|
||||
"in": SyntaxKind.InKeyword,
|
||||
"infer": SyntaxKind.InferKeyword,
|
||||
"instanceof": SyntaxKind.InstanceOfKeyword,
|
||||
"interface": SyntaxKind.InterfaceKeyword,
|
||||
"is": SyntaxKind.IsKeyword,
|
||||
"keyof": SyntaxKind.KeyOfKeyword,
|
||||
"let": SyntaxKind.LetKeyword,
|
||||
"module": SyntaxKind.ModuleKeyword,
|
||||
"namespace": SyntaxKind.NamespaceKeyword,
|
||||
"never": SyntaxKind.NeverKeyword,
|
||||
"new": SyntaxKind.NewKeyword,
|
||||
"null": SyntaxKind.NullKeyword,
|
||||
"number": SyntaxKind.NumberKeyword,
|
||||
"object": SyntaxKind.ObjectKeyword,
|
||||
"package": SyntaxKind.PackageKeyword,
|
||||
"private": SyntaxKind.PrivateKeyword,
|
||||
"protected": SyntaxKind.ProtectedKeyword,
|
||||
"public": SyntaxKind.PublicKeyword,
|
||||
"readonly": SyntaxKind.ReadonlyKeyword,
|
||||
"require": SyntaxKind.RequireKeyword,
|
||||
"global": SyntaxKind.GlobalKeyword,
|
||||
"return": SyntaxKind.ReturnKeyword,
|
||||
"set": SyntaxKind.SetKeyword,
|
||||
"static": SyntaxKind.StaticKeyword,
|
||||
"string": SyntaxKind.StringKeyword,
|
||||
"super": SyntaxKind.SuperKeyword,
|
||||
"switch": SyntaxKind.SwitchKeyword,
|
||||
"symbol": SyntaxKind.SymbolKeyword,
|
||||
"this": SyntaxKind.ThisKeyword,
|
||||
"throw": SyntaxKind.ThrowKeyword,
|
||||
"true": SyntaxKind.TrueKeyword,
|
||||
"try": SyntaxKind.TryKeyword,
|
||||
"type": SyntaxKind.TypeKeyword,
|
||||
"typeof": SyntaxKind.TypeOfKeyword,
|
||||
"undefined": SyntaxKind.UndefinedKeyword,
|
||||
"unique": SyntaxKind.UniqueKeyword,
|
||||
"unknown": SyntaxKind.UnknownKeyword,
|
||||
"var": SyntaxKind.VarKeyword,
|
||||
"void": SyntaxKind.VoidKeyword,
|
||||
"while": SyntaxKind.WhileKeyword,
|
||||
"with": SyntaxKind.WithKeyword,
|
||||
"yield": SyntaxKind.YieldKeyword,
|
||||
"async": SyntaxKind.AsyncKeyword,
|
||||
"await": SyntaxKind.AwaitKeyword,
|
||||
"of": SyntaxKind.OfKeyword,
|
||||
const textToKeywordObj: MapLike<KeywordSyntaxKind> = {
|
||||
abstract: SyntaxKind.AbstractKeyword,
|
||||
any: SyntaxKind.AnyKeyword,
|
||||
as: SyntaxKind.AsKeyword,
|
||||
bigint: SyntaxKind.BigIntKeyword,
|
||||
boolean: SyntaxKind.BooleanKeyword,
|
||||
break: SyntaxKind.BreakKeyword,
|
||||
case: SyntaxKind.CaseKeyword,
|
||||
catch: SyntaxKind.CatchKeyword,
|
||||
class: SyntaxKind.ClassKeyword,
|
||||
continue: SyntaxKind.ContinueKeyword,
|
||||
const: SyntaxKind.ConstKeyword,
|
||||
["" + "constructor"]: SyntaxKind.ConstructorKeyword,
|
||||
debugger: SyntaxKind.DebuggerKeyword,
|
||||
declare: SyntaxKind.DeclareKeyword,
|
||||
default: SyntaxKind.DefaultKeyword,
|
||||
delete: SyntaxKind.DeleteKeyword,
|
||||
do: SyntaxKind.DoKeyword,
|
||||
else: SyntaxKind.ElseKeyword,
|
||||
enum: SyntaxKind.EnumKeyword,
|
||||
export: SyntaxKind.ExportKeyword,
|
||||
extends: SyntaxKind.ExtendsKeyword,
|
||||
false: SyntaxKind.FalseKeyword,
|
||||
finally: SyntaxKind.FinallyKeyword,
|
||||
for: SyntaxKind.ForKeyword,
|
||||
from: SyntaxKind.FromKeyword,
|
||||
function: SyntaxKind.FunctionKeyword,
|
||||
get: SyntaxKind.GetKeyword,
|
||||
if: SyntaxKind.IfKeyword,
|
||||
implements: SyntaxKind.ImplementsKeyword,
|
||||
import: SyntaxKind.ImportKeyword,
|
||||
in: SyntaxKind.InKeyword,
|
||||
infer: SyntaxKind.InferKeyword,
|
||||
instanceof: SyntaxKind.InstanceOfKeyword,
|
||||
interface: SyntaxKind.InterfaceKeyword,
|
||||
is: SyntaxKind.IsKeyword,
|
||||
keyof: SyntaxKind.KeyOfKeyword,
|
||||
let: SyntaxKind.LetKeyword,
|
||||
module: SyntaxKind.ModuleKeyword,
|
||||
namespace: SyntaxKind.NamespaceKeyword,
|
||||
never: SyntaxKind.NeverKeyword,
|
||||
new: SyntaxKind.NewKeyword,
|
||||
null: SyntaxKind.NullKeyword,
|
||||
number: SyntaxKind.NumberKeyword,
|
||||
object: SyntaxKind.ObjectKeyword,
|
||||
package: SyntaxKind.PackageKeyword,
|
||||
private: SyntaxKind.PrivateKeyword,
|
||||
protected: SyntaxKind.ProtectedKeyword,
|
||||
public: SyntaxKind.PublicKeyword,
|
||||
readonly: SyntaxKind.ReadonlyKeyword,
|
||||
require: SyntaxKind.RequireKeyword,
|
||||
global: SyntaxKind.GlobalKeyword,
|
||||
return: SyntaxKind.ReturnKeyword,
|
||||
set: SyntaxKind.SetKeyword,
|
||||
static: SyntaxKind.StaticKeyword,
|
||||
string: SyntaxKind.StringKeyword,
|
||||
super: SyntaxKind.SuperKeyword,
|
||||
switch: SyntaxKind.SwitchKeyword,
|
||||
symbol: SyntaxKind.SymbolKeyword,
|
||||
this: SyntaxKind.ThisKeyword,
|
||||
throw: SyntaxKind.ThrowKeyword,
|
||||
true: SyntaxKind.TrueKeyword,
|
||||
try: SyntaxKind.TryKeyword,
|
||||
type: SyntaxKind.TypeKeyword,
|
||||
typeof: SyntaxKind.TypeOfKeyword,
|
||||
undefined: SyntaxKind.UndefinedKeyword,
|
||||
unique: SyntaxKind.UniqueKeyword,
|
||||
unknown: SyntaxKind.UnknownKeyword,
|
||||
var: SyntaxKind.VarKeyword,
|
||||
void: SyntaxKind.VoidKeyword,
|
||||
while: SyntaxKind.WhileKeyword,
|
||||
with: SyntaxKind.WithKeyword,
|
||||
yield: SyntaxKind.YieldKeyword,
|
||||
async: SyntaxKind.AsyncKeyword,
|
||||
await: SyntaxKind.AwaitKeyword,
|
||||
of: SyntaxKind.OfKeyword,
|
||||
};
|
||||
|
||||
const textToKeyword = createMapFromTemplate(textToKeywordObj);
|
||||
|
||||
const textToToken = createMapFromTemplate<SyntaxKind>({
|
||||
...textToKeywordObj,
|
||||
"{": SyntaxKind.OpenBraceToken,
|
||||
"}": SyntaxKind.CloseBraceToken,
|
||||
"(": SyntaxKind.OpenParenToken,
|
||||
@@ -913,7 +920,7 @@ namespace ts {
|
||||
return result + text.substring(start, pos);
|
||||
}
|
||||
|
||||
function scanNumber(): string {
|
||||
function scanNumber(): {type: SyntaxKind, value: string} {
|
||||
const start = pos;
|
||||
const mainFragment = scanNumberFragment();
|
||||
let decimalFragment: string | undefined;
|
||||
@@ -937,18 +944,29 @@ namespace ts {
|
||||
end = pos;
|
||||
}
|
||||
}
|
||||
let result: string;
|
||||
if (tokenFlags & TokenFlags.ContainsSeparator) {
|
||||
let result = mainFragment;
|
||||
result = mainFragment;
|
||||
if (decimalFragment) {
|
||||
result += "." + decimalFragment;
|
||||
}
|
||||
if (scientificFragment) {
|
||||
result += scientificFragment;
|
||||
}
|
||||
return "" + +result;
|
||||
}
|
||||
else {
|
||||
return "" + +(text.substring(start, end)); // No need to use all the fragments; no _ removal needed
|
||||
result = text.substring(start, end); // No need to use all the fragments; no _ removal needed
|
||||
}
|
||||
if (decimalFragment !== undefined || tokenFlags & TokenFlags.Scientific) {
|
||||
return {
|
||||
type: SyntaxKind.NumericLiteral,
|
||||
value: "" + +result // if value is not an integer, it can be safely coerced to a number
|
||||
};
|
||||
}
|
||||
else {
|
||||
tokenValue = result;
|
||||
const type = checkBigIntSuffix(); // if value is an integer, check whether it is a bigint
|
||||
return { type, value: tokenValue };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -965,24 +983,24 @@ namespace ts {
|
||||
* returning -1 if the given number is unavailable.
|
||||
*/
|
||||
function scanExactNumberOfHexDigits(count: number, canHaveSeparators: boolean): number {
|
||||
return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ false, canHaveSeparators);
|
||||
const valueString = scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ false, canHaveSeparators);
|
||||
return valueString ? parseInt(valueString, 16) : -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans as many hexadecimal digits as are available in the text,
|
||||
* returning -1 if the given number of digits was unavailable.
|
||||
* returning "" if the given number of digits was unavailable.
|
||||
*/
|
||||
function scanMinimumNumberOfHexDigits(count: number, canHaveSeparators: boolean): number {
|
||||
function scanMinimumNumberOfHexDigits(count: number, canHaveSeparators: boolean): string {
|
||||
return scanHexDigits(/*minCount*/ count, /*scanAsManyAsPossible*/ true, canHaveSeparators);
|
||||
}
|
||||
|
||||
function scanHexDigits(minCount: number, scanAsManyAsPossible: boolean, canHaveSeparators: boolean): number {
|
||||
let digits = 0;
|
||||
let value = 0;
|
||||
function scanHexDigits(minCount: number, scanAsManyAsPossible: boolean, canHaveSeparators: boolean): string {
|
||||
let valueChars: number[] = [];
|
||||
let allowSeparator = false;
|
||||
let isPreviousTokenSeparator = false;
|
||||
while (digits < minCount || scanAsManyAsPossible) {
|
||||
const ch = text.charCodeAt(pos);
|
||||
while (valueChars.length < minCount || scanAsManyAsPossible) {
|
||||
let ch = text.charCodeAt(pos);
|
||||
if (canHaveSeparators && ch === CharacterCodes._) {
|
||||
tokenFlags |= TokenFlags.ContainsSeparator;
|
||||
if (allowSeparator) {
|
||||
@@ -999,29 +1017,25 @@ namespace ts {
|
||||
continue;
|
||||
}
|
||||
allowSeparator = canHaveSeparators;
|
||||
if (ch >= CharacterCodes._0 && ch <= CharacterCodes._9) {
|
||||
value = value * 16 + ch - CharacterCodes._0;
|
||||
if (ch >= CharacterCodes.A && ch <= CharacterCodes.F) {
|
||||
ch += CharacterCodes.a - CharacterCodes.A; // standardize hex literals to lowercase
|
||||
}
|
||||
else if (ch >= CharacterCodes.A && ch <= CharacterCodes.F) {
|
||||
value = value * 16 + ch - CharacterCodes.A + 10;
|
||||
}
|
||||
else if (ch >= CharacterCodes.a && ch <= CharacterCodes.f) {
|
||||
value = value * 16 + ch - CharacterCodes.a + 10;
|
||||
}
|
||||
else {
|
||||
else if (!((ch >= CharacterCodes._0 && ch <= CharacterCodes._9) ||
|
||||
(ch >= CharacterCodes.a && ch <= CharacterCodes.f)
|
||||
)) {
|
||||
break;
|
||||
}
|
||||
valueChars.push(ch);
|
||||
pos++;
|
||||
digits++;
|
||||
isPreviousTokenSeparator = false;
|
||||
}
|
||||
if (digits < minCount) {
|
||||
value = -1;
|
||||
if (valueChars.length < minCount) {
|
||||
valueChars = [];
|
||||
}
|
||||
if (text.charCodeAt(pos - 1) === CharacterCodes._) {
|
||||
error(Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1);
|
||||
}
|
||||
return value;
|
||||
return String.fromCharCode(...valueChars);
|
||||
}
|
||||
|
||||
function scanString(jsxAttributeString = false): string {
|
||||
@@ -1201,7 +1215,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
function scanExtendedUnicodeEscape(): string {
|
||||
const escapedValue = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ false);
|
||||
const escapedValueString = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ false);
|
||||
const escapedValue = escapedValueString ? parseInt(escapedValueString, 16) : -1;
|
||||
let isInvalidExtendedEscape = false;
|
||||
|
||||
// Validate the value of the digit
|
||||
@@ -1288,28 +1303,25 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function getIdentifierToken(): SyntaxKind {
|
||||
function getIdentifierToken(): SyntaxKind.Identifier | KeywordSyntaxKind {
|
||||
// Reserved words are between 2 and 11 characters long and start with a lowercase letter
|
||||
const len = tokenValue.length;
|
||||
if (len >= 2 && len <= 11) {
|
||||
const ch = tokenValue.charCodeAt(0);
|
||||
if (ch >= CharacterCodes.a && ch <= CharacterCodes.z) {
|
||||
token = textToToken.get(tokenValue)!;
|
||||
if (token !== undefined) {
|
||||
return token;
|
||||
const keyword = textToKeyword.get(tokenValue);
|
||||
if (keyword !== undefined) {
|
||||
return token = keyword;
|
||||
}
|
||||
}
|
||||
}
|
||||
return token = SyntaxKind.Identifier;
|
||||
}
|
||||
|
||||
function scanBinaryOrOctalDigits(base: number): number {
|
||||
Debug.assert(base === 2 || base === 8, "Expected either base 2 or base 8");
|
||||
|
||||
let value = 0;
|
||||
function scanBinaryOrOctalDigits(base: 2 | 8): string {
|
||||
let value = "";
|
||||
// For counting number of digits; Valid binaryIntegerLiteral must have at least one binary digit following B or b.
|
||||
// Similarly valid octalIntegerLiteral must have at least one octal digit following o or O.
|
||||
let numberOfDigits = 0;
|
||||
let separatorAllowed = false;
|
||||
let isPreviousTokenSeparator = false;
|
||||
while (true) {
|
||||
@@ -1331,27 +1343,42 @@ namespace ts {
|
||||
continue;
|
||||
}
|
||||
separatorAllowed = true;
|
||||
const valueOfCh = ch - CharacterCodes._0;
|
||||
if (!isDigit(ch) || valueOfCh >= base) {
|
||||
if (!isDigit(ch) || ch - CharacterCodes._0 >= base) {
|
||||
break;
|
||||
}
|
||||
value = value * base + valueOfCh;
|
||||
value += text[pos];
|
||||
pos++;
|
||||
numberOfDigits++;
|
||||
isPreviousTokenSeparator = false;
|
||||
}
|
||||
// Invalid binaryIntegerLiteral or octalIntegerLiteral
|
||||
if (numberOfDigits === 0) {
|
||||
return -1;
|
||||
}
|
||||
if (text.charCodeAt(pos - 1) === CharacterCodes._) {
|
||||
// Literal ends with underscore - not allowed
|
||||
error(Diagnostics.Numeric_separators_are_not_allowed_here, pos - 1, 1);
|
||||
return value;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function checkBigIntSuffix(): SyntaxKind {
|
||||
if (text.charCodeAt(pos) === CharacterCodes.n) {
|
||||
tokenValue += "n";
|
||||
// Use base 10 instead of base 2 or base 8 for shorter literals
|
||||
if (tokenFlags & TokenFlags.BinaryOrOctalSpecifier) {
|
||||
tokenValue = parsePseudoBigInt(tokenValue) + "n";
|
||||
}
|
||||
pos++;
|
||||
return SyntaxKind.BigIntLiteral;
|
||||
}
|
||||
else { // not a bigint, so can convert to number in simplified form
|
||||
// Number() may not support 0b or 0o, so use parseInt() instead
|
||||
const numericValue = tokenFlags & TokenFlags.BinarySpecifier
|
||||
? parseInt(tokenValue.slice(2), 2) // skip "0b"
|
||||
: tokenFlags & TokenFlags.OctalSpecifier
|
||||
? parseInt(tokenValue.slice(2), 8) // skip "0o"
|
||||
: +tokenValue;
|
||||
tokenValue = "" + numericValue;
|
||||
return SyntaxKind.NumericLiteral;
|
||||
}
|
||||
}
|
||||
|
||||
function scan(): SyntaxKind {
|
||||
startPos = pos;
|
||||
tokenFlags = 0;
|
||||
@@ -1500,7 +1527,7 @@ namespace ts {
|
||||
return token = SyntaxKind.MinusToken;
|
||||
case CharacterCodes.dot:
|
||||
if (isDigit(text.charCodeAt(pos + 1))) {
|
||||
tokenValue = scanNumber();
|
||||
tokenValue = scanNumber().value;
|
||||
return token = SyntaxKind.NumericLiteral;
|
||||
}
|
||||
if (text.charCodeAt(pos + 1) === CharacterCodes.dot && text.charCodeAt(pos + 2) === CharacterCodes.dot) {
|
||||
@@ -1576,36 +1603,36 @@ namespace ts {
|
||||
case CharacterCodes._0:
|
||||
if (pos + 2 < end && (text.charCodeAt(pos + 1) === CharacterCodes.X || text.charCodeAt(pos + 1) === CharacterCodes.x)) {
|
||||
pos += 2;
|
||||
let value = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ true);
|
||||
if (value < 0) {
|
||||
tokenValue = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ true);
|
||||
if (!tokenValue) {
|
||||
error(Diagnostics.Hexadecimal_digit_expected);
|
||||
value = 0;
|
||||
tokenValue = "0";
|
||||
}
|
||||
tokenValue = "" + value;
|
||||
tokenValue = "0x" + tokenValue;
|
||||
tokenFlags |= TokenFlags.HexSpecifier;
|
||||
return token = SyntaxKind.NumericLiteral;
|
||||
return token = checkBigIntSuffix();
|
||||
}
|
||||
else if (pos + 2 < end && (text.charCodeAt(pos + 1) === CharacterCodes.B || text.charCodeAt(pos + 1) === CharacterCodes.b)) {
|
||||
pos += 2;
|
||||
let value = scanBinaryOrOctalDigits(/* base */ 2);
|
||||
if (value < 0) {
|
||||
tokenValue = scanBinaryOrOctalDigits(/* base */ 2);
|
||||
if (!tokenValue) {
|
||||
error(Diagnostics.Binary_digit_expected);
|
||||
value = 0;
|
||||
tokenValue = "0";
|
||||
}
|
||||
tokenValue = "" + value;
|
||||
tokenValue = "0b" + tokenValue;
|
||||
tokenFlags |= TokenFlags.BinarySpecifier;
|
||||
return token = SyntaxKind.NumericLiteral;
|
||||
return token = checkBigIntSuffix();
|
||||
}
|
||||
else if (pos + 2 < end && (text.charCodeAt(pos + 1) === CharacterCodes.O || text.charCodeAt(pos + 1) === CharacterCodes.o)) {
|
||||
pos += 2;
|
||||
let value = scanBinaryOrOctalDigits(/* base */ 8);
|
||||
if (value < 0) {
|
||||
tokenValue = scanBinaryOrOctalDigits(/* base */ 8);
|
||||
if (!tokenValue) {
|
||||
error(Diagnostics.Octal_digit_expected);
|
||||
value = 0;
|
||||
tokenValue = "0";
|
||||
}
|
||||
tokenValue = "" + value;
|
||||
tokenValue = "0o" + tokenValue;
|
||||
tokenFlags |= TokenFlags.OctalSpecifier;
|
||||
return token = SyntaxKind.NumericLiteral;
|
||||
return token = checkBigIntSuffix();
|
||||
}
|
||||
// Try to parse as an octal
|
||||
if (pos + 1 < end && isOctalDigit(text.charCodeAt(pos + 1))) {
|
||||
@@ -1626,8 +1653,8 @@ namespace ts {
|
||||
case CharacterCodes._7:
|
||||
case CharacterCodes._8:
|
||||
case CharacterCodes._9:
|
||||
tokenValue = scanNumber();
|
||||
return token = SyntaxKind.NumericLiteral;
|
||||
({ type: token, value: tokenValue } = scanNumber());
|
||||
return token;
|
||||
case CharacterCodes.colon:
|
||||
pos++;
|
||||
return token = SyntaxKind.ColonToken;
|
||||
@@ -2016,7 +2043,7 @@ namespace ts {
|
||||
pos++;
|
||||
}
|
||||
tokenValue = text.substring(tokenPos, pos);
|
||||
return token = SyntaxKind.Identifier;
|
||||
return token = getIdentifierToken();
|
||||
}
|
||||
else {
|
||||
return token = SyntaxKind.Unknown;
|
||||
|
||||
+12
-10
@@ -591,10 +591,12 @@ namespace ts {
|
||||
export function createDocumentPositionMapper(host: DocumentPositionMapperHost, map: RawSourceMap, mapPath: string): DocumentPositionMapper {
|
||||
const mapDirectory = getDirectoryPath(mapPath);
|
||||
const sourceRoot = map.sourceRoot ? getNormalizedAbsolutePath(map.sourceRoot, mapDirectory) : mapDirectory;
|
||||
const generatedFilePath = toPath(map.file, mapDirectory, host.getCanonicalFileName);
|
||||
const generatedFile = host.getSourceFileLike(generatedFilePath);
|
||||
const sourceFilePaths = map.sources.map(source => toPath(source, sourceRoot, host.getCanonicalFileName));
|
||||
const sourceToSourceIndexMap = createMapFromEntries(sourceFilePaths.map((source, i) => [source, i] as [string, number]));
|
||||
const generatedAbsoluteFilePath = getNormalizedAbsolutePath(map.file, mapDirectory);
|
||||
const generatedCanonicalFilePath = host.getCanonicalFileName(generatedAbsoluteFilePath) as Path;
|
||||
const generatedFile = host.getSourceFileLike(generatedCanonicalFilePath);
|
||||
const sourceFileAbsolutePaths = map.sources.map(source => getNormalizedAbsolutePath(source, sourceRoot));
|
||||
const sourceFileCanonicalPaths = sourceFileAbsolutePaths.map(source => host.getCanonicalFileName(source) as Path);
|
||||
const sourceToSourceIndexMap = createMapFromEntries(sourceFileCanonicalPaths.map((source, i) => [source, i] as [string, number]));
|
||||
let decodedMappings: ReadonlyArray<MappedPosition> | undefined;
|
||||
let generatedMappings: ReadonlyArray<MappedPosition> | undefined;
|
||||
let sourceMappings: ReadonlyArray<ReadonlyArray<SourceMappedPosition>> | undefined;
|
||||
@@ -611,7 +613,7 @@ namespace ts {
|
||||
let source: string | undefined;
|
||||
let sourcePosition: number | undefined;
|
||||
if (isSourceMapping(mapping)) {
|
||||
const sourceFilePath = sourceFilePaths[mapping.sourceIndex];
|
||||
const sourceFilePath = sourceFileCanonicalPaths[mapping.sourceIndex];
|
||||
const sourceFile = host.getSourceFileLike(sourceFilePath);
|
||||
source = map.sources[mapping.sourceIndex];
|
||||
sourcePosition = sourceFile !== undefined
|
||||
@@ -670,7 +672,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function getGeneratedPosition(loc: DocumentPosition): DocumentPosition {
|
||||
const sourceIndex = sourceToSourceIndexMap.get(loc.fileName);
|
||||
const sourceIndex = sourceToSourceIndexMap.get(host.getCanonicalFileName(loc.fileName));
|
||||
if (sourceIndex === undefined) return loc;
|
||||
|
||||
const sourceMappings = getSourceMappings(sourceIndex);
|
||||
@@ -678,7 +680,7 @@ namespace ts {
|
||||
|
||||
let targetIndex = binarySearchKey(sourceMappings, loc.pos, getSourcePositionOfMapping, compareValues);
|
||||
if (targetIndex < 0) {
|
||||
// if no exact match, closest is 2's compliment of result
|
||||
// if no exact match, closest is 2's complement of result
|
||||
targetIndex = ~targetIndex;
|
||||
}
|
||||
|
||||
@@ -687,7 +689,7 @@ namespace ts {
|
||||
return loc;
|
||||
}
|
||||
|
||||
return { fileName: generatedFilePath, pos: mapping.generatedPosition }; // Closest pos
|
||||
return { fileName: generatedAbsoluteFilePath, pos: mapping.generatedPosition }; // Closest pos
|
||||
}
|
||||
|
||||
function getSourcePosition(loc: DocumentPosition): DocumentPosition {
|
||||
@@ -696,7 +698,7 @@ namespace ts {
|
||||
|
||||
let targetIndex = binarySearchKey(generatedMappings, loc.pos, getGeneratedPositionOfMapping, compareValues);
|
||||
if (targetIndex < 0) {
|
||||
// if no exact match, closest is 2's compliment of result
|
||||
// if no exact match, closest is 2's complement of result
|
||||
targetIndex = ~targetIndex;
|
||||
}
|
||||
|
||||
@@ -705,7 +707,7 @@ namespace ts {
|
||||
return loc;
|
||||
}
|
||||
|
||||
return { fileName: sourceFilePaths[mapping.sourceIndex], pos: mapping.sourcePosition }; // Closest pos
|
||||
return { fileName: sourceFileAbsolutePaths[mapping.sourceIndex], pos: mapping.sourcePosition }; // Closest pos
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-22
@@ -36,23 +36,6 @@ namespace ts {
|
||||
Low = 250
|
||||
}
|
||||
|
||||
function getPriorityValues(highPriorityValue: number): [number, number, number] {
|
||||
const mediumPriorityValue = highPriorityValue * 2;
|
||||
const lowPriorityValue = mediumPriorityValue * 4;
|
||||
return [highPriorityValue, mediumPriorityValue, lowPriorityValue];
|
||||
}
|
||||
|
||||
function pollingInterval(watchPriority: PollingInterval): number {
|
||||
return pollingIntervalsForPriority[watchPriority];
|
||||
}
|
||||
|
||||
const pollingIntervalsForPriority = getPriorityValues(250);
|
||||
|
||||
/* @internal */
|
||||
export function watchFileUsingPriorityPollingInterval(host: System, fileName: string, callback: FileWatcherCallback, watchPriority: PollingInterval): FileWatcher {
|
||||
return host.watchFile!(fileName, callback, pollingInterval(watchPriority));
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export type HostWatchFile = (fileName: string, callback: FileWatcherCallback, pollingInterval: PollingInterval | undefined) => FileWatcher;
|
||||
/* @internal */
|
||||
@@ -796,11 +779,10 @@ namespace ts {
|
||||
dirName,
|
||||
(_eventName: string, relativeFileName) => {
|
||||
// When files are deleted from disk, the triggered "rename" event would have a relativefileName of "undefined"
|
||||
const fileName = !isString(relativeFileName)
|
||||
? undefined! // TODO: GH#18217
|
||||
: getNormalizedAbsolutePath(relativeFileName, dirName);
|
||||
if (!isString(relativeFileName)) { return; }
|
||||
const fileName = getNormalizedAbsolutePath(relativeFileName, dirName);
|
||||
// Some applications save a working file via rename operations
|
||||
const callbacks = fileWatcherCallbacks.get(toCanonicalName(fileName));
|
||||
const callbacks = fileName && fileWatcherCallbacks.get(toCanonicalName(fileName));
|
||||
if (callbacks) {
|
||||
for (const fileCallback of callbacks) {
|
||||
fileCallback(fileName, FileWatcherEventKind.Changed);
|
||||
@@ -847,7 +829,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
type FsWatchCallback = (eventName: "rename" | "change", relativeFileName: string) => void;
|
||||
type FsWatchCallback = (eventName: "rename" | "change", relativeFileName: string | undefined) => void;
|
||||
|
||||
function createFileWatcherCallback(callback: FsWatchCallback): FileWatcherCallback {
|
||||
return (_fileName, eventKind) => callback(eventKind === FileWatcherEventKind.Changed ? "change" : "rename", "");
|
||||
|
||||
@@ -275,7 +275,7 @@ namespace ts {
|
||||
else {
|
||||
if (isBundledEmit && contains((node as Bundle).sourceFiles, file)) return; // Omit references to files which are being merged
|
||||
const paths = getOutputPathsFor(file, host, /*forceDtsPaths*/ true);
|
||||
declFileName = paths.declarationFilePath || paths.jsFilePath;
|
||||
declFileName = paths.declarationFilePath || paths.jsFilePath || file.fileName;
|
||||
}
|
||||
|
||||
if (declFileName) {
|
||||
@@ -373,7 +373,7 @@ namespace ts {
|
||||
|
||||
function ensureNoInitializer(node: CanHaveLiteralInitializer) {
|
||||
if (shouldPrintWithInitializer(node)) {
|
||||
return resolver.createLiteralConstValue(getParseTreeNode(node) as CanHaveLiteralInitializer); // TODO: Make safe
|
||||
return resolver.createLiteralConstValue(getParseTreeNode(node) as CanHaveLiteralInitializer, symbolTracker); // TODO: Make safe
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@@ -1043,7 +1043,7 @@ namespace ts {
|
||||
const modifiers = createNodeArray(ensureModifiers(input, isPrivate));
|
||||
const typeParameters = ensureTypeParams(input, input.typeParameters);
|
||||
const ctor = getFirstConstructorWithBody(input);
|
||||
let parameterProperties: PropertyDeclaration[] | undefined;
|
||||
let parameterProperties: ReadonlyArray<PropertyDeclaration> | undefined;
|
||||
if (ctor) {
|
||||
const oldDiag = getSymbolAccessibilityDiagnostic;
|
||||
parameterProperties = compact(flatMap(ctor.parameters, param => {
|
||||
|
||||
@@ -466,4 +466,4 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1901,6 +1901,9 @@ namespace ts {
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return createIdentifier("Number");
|
||||
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
return getGlobalBigIntNameWithFallback();
|
||||
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
return createIdentifier("Boolean");
|
||||
@@ -1912,6 +1915,9 @@ namespace ts {
|
||||
case SyntaxKind.NumberKeyword:
|
||||
return createIdentifier("Number");
|
||||
|
||||
case SyntaxKind.BigIntKeyword:
|
||||
return getGlobalBigIntNameWithFallback();
|
||||
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
return languageVersion < ScriptTarget.ES2015
|
||||
? getGlobalSymbolNameWithFallback()
|
||||
@@ -2006,6 +2012,9 @@ namespace ts {
|
||||
case TypeReferenceSerializationKind.VoidNullableOrNeverType:
|
||||
return createVoidZero();
|
||||
|
||||
case TypeReferenceSerializationKind.BigIntLikeType:
|
||||
return getGlobalBigIntNameWithFallback();
|
||||
|
||||
case TypeReferenceSerializationKind.BooleanType:
|
||||
return createIdentifier("Boolean");
|
||||
|
||||
@@ -2115,6 +2124,20 @@ namespace ts {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an expression that points to the global "BigInt" constructor at runtime if it is
|
||||
* available.
|
||||
*/
|
||||
function getGlobalBigIntNameWithFallback(): SerializedTypeNode {
|
||||
return languageVersion < ScriptTarget.ESNext
|
||||
? createConditional(
|
||||
createTypeCheck(createIdentifier("BigInt"), "function"),
|
||||
createIdentifier("BigInt"),
|
||||
createIdentifier("Object")
|
||||
)
|
||||
: createIdentifier("BigInt");
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple inlinable expression is an expression which can be copied into multiple locations
|
||||
* without risk of repeating any sideeffects and whose value could not possibly change between
|
||||
|
||||
+37
-17
@@ -29,6 +29,9 @@ namespace ts {
|
||||
preserveWatchOutput?: boolean;
|
||||
listEmittedFiles?: boolean;
|
||||
listFiles?: boolean;
|
||||
pretty?: boolean;
|
||||
|
||||
traceResolution?: boolean;
|
||||
}
|
||||
|
||||
enum BuildResultFlags {
|
||||
@@ -316,7 +319,7 @@ namespace ts {
|
||||
return fileExtensionIs(fileName, Extension.Dts);
|
||||
}
|
||||
|
||||
export interface SolutionBuilderHost extends CompilerHost {
|
||||
export interface SolutionBuilderHostBase extends CompilerHost {
|
||||
getModifiedTime(fileName: string): Date | undefined;
|
||||
setModifiedTime(fileName: string, date: Date): void;
|
||||
deleteFile(fileName: string): void;
|
||||
@@ -325,13 +328,18 @@ namespace ts {
|
||||
reportSolutionBuilderStatus: DiagnosticReporter;
|
||||
}
|
||||
|
||||
export interface SolutionBuilderWithWatchHost extends SolutionBuilderHost, WatchHost {
|
||||
export interface SolutionBuilderHost extends SolutionBuilderHostBase {
|
||||
reportErrorSummary?: ReportEmitErrorSummary;
|
||||
}
|
||||
|
||||
export interface SolutionBuilderWithWatchHost extends SolutionBuilderHostBase, WatchHost {
|
||||
}
|
||||
|
||||
export interface SolutionBuilder {
|
||||
buildAllProjects(): ExitStatus;
|
||||
cleanAllProjects(): ExitStatus;
|
||||
|
||||
// TODO:: All the below ones should technically only be in watch mode. but thats for later time
|
||||
/*@internal*/ resolveProjectName(name: string): ResolvedConfigFileName;
|
||||
/*@internal*/ getUpToDateStatusOfFile(configFileName: ResolvedConfigFileName): UpToDateStatus;
|
||||
/*@internal*/ getBuildGraph(configFileNames: ReadonlyArray<string>): DependencyGraph;
|
||||
@@ -340,7 +348,9 @@ namespace ts {
|
||||
/*@internal*/ buildInvalidatedProject(): void;
|
||||
|
||||
/*@internal*/ resetBuildContext(opts?: BuildOptions): void;
|
||||
}
|
||||
|
||||
export interface SolutionBuilderWithWatch extends SolutionBuilder {
|
||||
/*@internal*/ startWatching(): void;
|
||||
}
|
||||
|
||||
@@ -355,8 +365,8 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
export function createSolutionBuilderHost(system = sys, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter) {
|
||||
const host = createCompilerHostWorker({}, /*setParentNodes*/ undefined, system) as SolutionBuilderHost;
|
||||
function createSolutionBuilderHostBase(system = sys, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter) {
|
||||
const host = createCompilerHostWorker({}, /*setParentNodes*/ undefined, system) as SolutionBuilderHostBase;
|
||||
host.getModifiedTime = system.getModifiedTime ? path => system.getModifiedTime!(path) : () => undefined;
|
||||
host.setModifiedTime = system.setModifiedTime ? (path, date) => system.setModifiedTime!(path, date) : noop;
|
||||
host.deleteFile = system.deleteFile ? path => system.deleteFile!(path) : noop;
|
||||
@@ -365,8 +375,14 @@ namespace ts {
|
||||
return host;
|
||||
}
|
||||
|
||||
export function createSolutionBuilderWithWatchHost(system = sys, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter) {
|
||||
const host = createSolutionBuilderHost(system, reportDiagnostic, reportSolutionBuilderStatus) as SolutionBuilderWithWatchHost;
|
||||
export function createSolutionBuilderHost(system = sys, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter, reportErrorSummary?: ReportEmitErrorSummary) {
|
||||
const host = createSolutionBuilderHostBase(system, reportDiagnostic, reportSolutionBuilderStatus) as SolutionBuilderHost;
|
||||
host.reportErrorSummary = reportErrorSummary;
|
||||
return host;
|
||||
}
|
||||
|
||||
export function createSolutionBuilderWithWatchHost(system?: System, reportDiagnostic?: DiagnosticReporter, reportSolutionBuilderStatus?: DiagnosticReporter, reportWatchStatus?: WatchStatusReporter) {
|
||||
const host = createSolutionBuilderHostBase(system, reportDiagnostic, reportSolutionBuilderStatus) as SolutionBuilderWithWatchHost;
|
||||
const watchHost = createWatchHost(system, reportWatchStatus);
|
||||
host.onWatchStatusChange = watchHost.onWatchStatusChange;
|
||||
host.watchFile = watchHost.watchFile;
|
||||
@@ -390,7 +406,9 @@ namespace ts {
|
||||
* TODO: use SolutionBuilderWithWatchHost => watchedSolution
|
||||
* use SolutionBuilderHost => Solution
|
||||
*/
|
||||
export function createSolutionBuilder(host: SolutionBuilderHost, rootNames: ReadonlyArray<string>, defaultOptions: BuildOptions): SolutionBuilder {
|
||||
export function createSolutionBuilder(host: SolutionBuilderHost, rootNames: ReadonlyArray<string>, defaultOptions: BuildOptions): SolutionBuilder;
|
||||
export function createSolutionBuilder(host: SolutionBuilderWithWatchHost, rootNames: ReadonlyArray<string>, defaultOptions: BuildOptions): SolutionBuilderWithWatch;
|
||||
export function createSolutionBuilder(host: SolutionBuilderHost | SolutionBuilderWithWatchHost, rootNames: ReadonlyArray<string>, defaultOptions: BuildOptions): SolutionBuilderWithWatch {
|
||||
const hostWithWatch = host as SolutionBuilderWithWatchHost;
|
||||
const currentDirectory = host.getCurrentDirectory();
|
||||
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames());
|
||||
@@ -803,9 +821,7 @@ namespace ts {
|
||||
globalDependencyGraph = undefined;
|
||||
}
|
||||
projectStatus.removeKey(resolved);
|
||||
if (options.watch) {
|
||||
diagnostics.removeKey(resolved);
|
||||
}
|
||||
diagnostics.removeKey(resolved);
|
||||
|
||||
addProjToQueue(resolved, reloadLevel);
|
||||
}
|
||||
@@ -874,7 +890,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function reportErrorSummary() {
|
||||
if (options.watch) {
|
||||
if (options.watch || (host as SolutionBuilderHost).reportErrorSummary) {
|
||||
// Report errors from the other projects
|
||||
getGlobalDependencyGraph().buildQueue.forEach(project => {
|
||||
if (!projectErrorsReported.hasKey(project)) {
|
||||
@@ -882,8 +898,13 @@ namespace ts {
|
||||
}
|
||||
});
|
||||
let totalErrors = 0;
|
||||
diagnostics.forEach(singleProjectErrors => totalErrors += singleProjectErrors.filter(diagnostic => diagnostic.category === DiagnosticCategory.Error).length);
|
||||
reportWatchStatus(totalErrors === 1 ? Diagnostics.Found_1_error_Watching_for_file_changes : Diagnostics.Found_0_errors_Watching_for_file_changes, totalErrors);
|
||||
diagnostics.forEach(singleProjectErrors => totalErrors += getErrorCountForSummary(singleProjectErrors));
|
||||
if (options.watch) {
|
||||
reportWatchStatus(getWatchErrorSummaryDiagnosticMessage(totalErrors), totalErrors);
|
||||
}
|
||||
else {
|
||||
(host as SolutionBuilderHost).reportErrorSummary!(totalErrors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1066,6 +1087,7 @@ namespace ts {
|
||||
type: UpToDateStatusType.UpToDate,
|
||||
newestDeclarationFileContentChangedTime: anyDtsChanged ? maximumDate : newestDeclarationFileContentChangedTime
|
||||
};
|
||||
diagnostics.removeKey(proj);
|
||||
projectStatus.setValue(proj, status);
|
||||
return resultFlags;
|
||||
|
||||
@@ -1204,10 +1226,8 @@ namespace ts {
|
||||
|
||||
function reportAndStoreErrors(proj: ResolvedConfigFileName, errors: ReadonlyArray<Diagnostic>) {
|
||||
reportErrors(errors);
|
||||
if (options.watch) {
|
||||
projectErrorsReported.setValue(proj, true);
|
||||
diagnostics.setValue(proj, errors);
|
||||
}
|
||||
projectErrorsReported.setValue(proj, true);
|
||||
diagnostics.setValue(proj, errors);
|
||||
}
|
||||
|
||||
function reportErrors(errors: ReadonlyArray<Diagnostic>) {
|
||||
|
||||
+209
-73
@@ -24,7 +24,85 @@ namespace ts {
|
||||
| SyntaxKind.DotToken
|
||||
| SyntaxKind.Identifier
|
||||
| SyntaxKind.NoSubstitutionTemplateLiteral
|
||||
| SyntaxKind.Unknown;
|
||||
| SyntaxKind.Unknown
|
||||
| KeywordSyntaxKind;
|
||||
|
||||
export type KeywordSyntaxKind =
|
||||
| SyntaxKind.AbstractKeyword
|
||||
| SyntaxKind.AnyKeyword
|
||||
| SyntaxKind.AsKeyword
|
||||
| SyntaxKind.BigIntKeyword
|
||||
| SyntaxKind.BooleanKeyword
|
||||
| SyntaxKind.BreakKeyword
|
||||
| SyntaxKind.CaseKeyword
|
||||
| SyntaxKind.CatchKeyword
|
||||
| SyntaxKind.ClassKeyword
|
||||
| SyntaxKind.ContinueKeyword
|
||||
| SyntaxKind.ConstKeyword
|
||||
| SyntaxKind.ConstructorKeyword
|
||||
| SyntaxKind.DebuggerKeyword
|
||||
| SyntaxKind.DeclareKeyword
|
||||
| SyntaxKind.DefaultKeyword
|
||||
| SyntaxKind.DeleteKeyword
|
||||
| SyntaxKind.DoKeyword
|
||||
| SyntaxKind.ElseKeyword
|
||||
| SyntaxKind.EnumKeyword
|
||||
| SyntaxKind.ExportKeyword
|
||||
| SyntaxKind.ExtendsKeyword
|
||||
| SyntaxKind.FalseKeyword
|
||||
| SyntaxKind.FinallyKeyword
|
||||
| SyntaxKind.ForKeyword
|
||||
| SyntaxKind.FromKeyword
|
||||
| SyntaxKind.FunctionKeyword
|
||||
| SyntaxKind.GetKeyword
|
||||
| SyntaxKind.IfKeyword
|
||||
| SyntaxKind.ImplementsKeyword
|
||||
| SyntaxKind.ImportKeyword
|
||||
| SyntaxKind.InKeyword
|
||||
| SyntaxKind.InferKeyword
|
||||
| SyntaxKind.InstanceOfKeyword
|
||||
| SyntaxKind.InterfaceKeyword
|
||||
| SyntaxKind.IsKeyword
|
||||
| SyntaxKind.KeyOfKeyword
|
||||
| SyntaxKind.LetKeyword
|
||||
| SyntaxKind.ModuleKeyword
|
||||
| SyntaxKind.NamespaceKeyword
|
||||
| SyntaxKind.NeverKeyword
|
||||
| SyntaxKind.NewKeyword
|
||||
| SyntaxKind.NullKeyword
|
||||
| SyntaxKind.NumberKeyword
|
||||
| SyntaxKind.ObjectKeyword
|
||||
| SyntaxKind.PackageKeyword
|
||||
| SyntaxKind.PrivateKeyword
|
||||
| SyntaxKind.ProtectedKeyword
|
||||
| SyntaxKind.PublicKeyword
|
||||
| SyntaxKind.ReadonlyKeyword
|
||||
| SyntaxKind.RequireKeyword
|
||||
| SyntaxKind.GlobalKeyword
|
||||
| SyntaxKind.ReturnKeyword
|
||||
| SyntaxKind.SetKeyword
|
||||
| SyntaxKind.StaticKeyword
|
||||
| SyntaxKind.StringKeyword
|
||||
| SyntaxKind.SuperKeyword
|
||||
| SyntaxKind.SwitchKeyword
|
||||
| SyntaxKind.SymbolKeyword
|
||||
| SyntaxKind.ThisKeyword
|
||||
| SyntaxKind.ThrowKeyword
|
||||
| SyntaxKind.TrueKeyword
|
||||
| SyntaxKind.TryKeyword
|
||||
| SyntaxKind.TypeKeyword
|
||||
| SyntaxKind.TypeOfKeyword
|
||||
| SyntaxKind.UndefinedKeyword
|
||||
| SyntaxKind.UniqueKeyword
|
||||
| SyntaxKind.UnknownKeyword
|
||||
| SyntaxKind.VarKeyword
|
||||
| SyntaxKind.VoidKeyword
|
||||
| SyntaxKind.WhileKeyword
|
||||
| SyntaxKind.WithKeyword
|
||||
| SyntaxKind.YieldKeyword
|
||||
| SyntaxKind.AsyncKeyword
|
||||
| SyntaxKind.AwaitKeyword
|
||||
| SyntaxKind.OfKeyword;
|
||||
|
||||
export type JsxTokenSyntaxKind =
|
||||
| SyntaxKind.LessThanSlashToken
|
||||
@@ -51,6 +129,7 @@ namespace ts {
|
||||
ConflictMarkerTrivia,
|
||||
// Literals
|
||||
NumericLiteral,
|
||||
BigIntLiteral,
|
||||
StringLiteral,
|
||||
JsxText,
|
||||
JsxTextAllWhiteSpaces,
|
||||
@@ -194,6 +273,7 @@ namespace ts {
|
||||
UnknownKeyword,
|
||||
FromKeyword,
|
||||
GlobalKeyword,
|
||||
BigIntKeyword,
|
||||
OfKeyword, // LastKeyword and LastToken and LastContextualKeyword
|
||||
|
||||
// Parse tree nodes
|
||||
@@ -639,7 +719,6 @@ namespace ts {
|
||||
export type AsteriskToken = Token<SyntaxKind.AsteriskToken>;
|
||||
export type EqualsGreaterThanToken = Token<SyntaxKind.EqualsGreaterThanToken>;
|
||||
export type EndOfFileToken = Token<SyntaxKind.EndOfFileToken> & JSDocContainer;
|
||||
export type AtToken = Token<SyntaxKind.AtToken>;
|
||||
export type ReadonlyToken = Token<SyntaxKind.ReadonlyKeyword>;
|
||||
export type AwaitKeywordToken = Token<SyntaxKind.AwaitKeyword>;
|
||||
export type PlusToken = Token<SyntaxKind.PlusToken>;
|
||||
@@ -713,7 +792,7 @@ namespace ts {
|
||||
|
||||
export type PropertyName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName;
|
||||
|
||||
export type DeclarationName = Identifier | StringLiteral | NumericLiteral | ComputedPropertyName | BindingPattern;
|
||||
export type DeclarationName = Identifier | StringLiteralLike | NumericLiteral | ComputedPropertyName | BindingPattern;
|
||||
|
||||
export interface Declaration extends Node {
|
||||
_declarationBrand: any;
|
||||
@@ -1032,6 +1111,7 @@ namespace ts {
|
||||
kind: SyntaxKind.AnyKeyword
|
||||
| SyntaxKind.UnknownKeyword
|
||||
| SyntaxKind.NumberKeyword
|
||||
| SyntaxKind.BigIntKeyword
|
||||
| SyntaxKind.ObjectKeyword
|
||||
| SyntaxKind.BooleanKeyword
|
||||
| SyntaxKind.StringKeyword
|
||||
@@ -1582,7 +1662,7 @@ namespace ts {
|
||||
OctalSpecifier = 1 << 8, // e.g. `0o777`
|
||||
ContainsSeparator = 1 << 9, // e.g. `0b1100_0101`
|
||||
BinaryOrOctalSpecifier = BinarySpecifier | OctalSpecifier,
|
||||
NumericLiteralFlags = Scientific | Octal | HexSpecifier | BinarySpecifier | OctalSpecifier | ContainsSeparator
|
||||
NumericLiteralFlags = Scientific | Octal | HexSpecifier | BinaryOrOctalSpecifier | ContainsSeparator
|
||||
}
|
||||
|
||||
export interface NumericLiteral extends LiteralExpression {
|
||||
@@ -1591,6 +1671,10 @@ namespace ts {
|
||||
numericLiteralFlags: TokenFlags;
|
||||
}
|
||||
|
||||
export interface BigIntLiteral extends LiteralExpression {
|
||||
kind: SyntaxKind.BigIntLiteral;
|
||||
}
|
||||
|
||||
export interface TemplateHead extends LiteralLikeNode {
|
||||
kind: SyntaxKind.TemplateHead;
|
||||
parent: TemplateExpression;
|
||||
@@ -1697,6 +1781,9 @@ namespace ts {
|
||||
arguments: NodeArray<Expression>;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export type BindableObjectDefinePropertyCall = CallExpression & { arguments: { 0: EntityNameExpression, 1: StringLiteralLike | NumericLiteral, 2: ObjectLiteralExpression } };
|
||||
|
||||
// see: https://tc39.github.io/ecma262/#prod-SuperCall
|
||||
export interface SuperCall extends CallExpression {
|
||||
expression: SuperExpression;
|
||||
@@ -2333,7 +2420,6 @@ namespace ts {
|
||||
|
||||
export interface JSDocTag extends Node {
|
||||
parent: JSDoc | JSDocTypeLiteral;
|
||||
atToken: AtToken;
|
||||
tagName: Identifier;
|
||||
comment?: string;
|
||||
}
|
||||
@@ -2367,7 +2453,7 @@ namespace ts {
|
||||
|
||||
export interface JSDocTemplateTag extends JSDocTag {
|
||||
kind: SyntaxKind.JSDocTemplateTag;
|
||||
constraint: TypeNode | undefined;
|
||||
constraint: JSDocTypeExpression | undefined;
|
||||
typeParameters: NodeArray<TypeParameterDeclaration>;
|
||||
}
|
||||
|
||||
@@ -2634,7 +2720,7 @@ namespace ts {
|
||||
// It is used to resolve module names in the checker.
|
||||
// Content of this field should never be used directly - use getResolvedModuleFileName/setResolvedModuleFileName functions instead
|
||||
/* @internal */ resolvedModules?: Map<ResolvedModuleFull | undefined>;
|
||||
/* @internal */ resolvedTypeReferenceDirectiveNames: Map<ResolvedTypeReferenceDirective>;
|
||||
/* @internal */ resolvedTypeReferenceDirectiveNames: Map<ResolvedTypeReferenceDirective | undefined>;
|
||||
/* @internal */ imports: ReadonlyArray<StringLiteralLike>;
|
||||
/**
|
||||
* When a file's references are redirected due to project reference directives,
|
||||
@@ -2713,7 +2799,7 @@ namespace ts {
|
||||
export interface ParseConfigHost {
|
||||
useCaseSensitiveFileNames: boolean;
|
||||
|
||||
readDirectory(rootDir: string, extensions: ReadonlyArray<string>, excludes: ReadonlyArray<string> | undefined, includes: ReadonlyArray<string>, depth?: number): string[];
|
||||
readDirectory(rootDir: string, extensions: ReadonlyArray<string>, excludes: ReadonlyArray<string> | undefined, includes: ReadonlyArray<string>, depth?: number): ReadonlyArray<string>;
|
||||
|
||||
/**
|
||||
* Gets a value indicating whether the specified path exists and is a file.
|
||||
@@ -2722,6 +2808,7 @@ namespace ts {
|
||||
fileExists(path: string): boolean;
|
||||
|
||||
readFile(path: string): string | undefined;
|
||||
trace?(s: string): void;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2809,7 +2896,7 @@ namespace ts {
|
||||
/* @internal */ getTypeCount(): number;
|
||||
|
||||
/* @internal */ getFileProcessingDiagnostics(): DiagnosticCollection;
|
||||
/* @internal */ getResolvedTypeReferenceDirectives(): Map<ResolvedTypeReferenceDirective>;
|
||||
/* @internal */ getResolvedTypeReferenceDirectives(): Map<ResolvedTypeReferenceDirective | undefined>;
|
||||
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
|
||||
isSourceFileDefaultLibrary(file: SourceFile): boolean;
|
||||
|
||||
@@ -2829,8 +2916,11 @@ namespace ts {
|
||||
/* @internal */ getResolvedModuleWithFailedLookupLocationsFromCache(moduleName: string, containingFile: string): ResolvedModuleWithFailedLookupLocations | undefined;
|
||||
|
||||
getProjectReferences(): ReadonlyArray<ProjectReference> | undefined;
|
||||
getResolvedProjectReferences(): (ResolvedProjectReference | undefined)[] | undefined;
|
||||
getResolvedProjectReferences(): ReadonlyArray<ResolvedProjectReference | undefined> | undefined;
|
||||
/*@internal*/ getProjectReferenceRedirect(fileName: string): string | undefined;
|
||||
/*@internal*/ getResolvedProjectReferenceToRedirect(fileName: string): ResolvedProjectReference | undefined;
|
||||
/*@internal*/ forEachResolvedProjectReference<T>(cb: (resolvedProjectReference: ResolvedProjectReference | undefined, resolvedProjectReferencePath: Path) => T | undefined): T | undefined;
|
||||
/*@internal*/ getResolvedProjectReferenceByPath(projectReferencePath: Path): ResolvedProjectReference | undefined;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -2839,6 +2929,7 @@ namespace ts {
|
||||
export interface ResolvedProjectReference {
|
||||
commandLine: ParsedCommandLine;
|
||||
sourceFile: SourceFile;
|
||||
references?: ReadonlyArray<ResolvedProjectReference | undefined>;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -2902,12 +2993,12 @@ namespace ts {
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export interface TypeCheckerHost {
|
||||
export interface TypeCheckerHost extends ModuleSpecifierResolutionHost {
|
||||
getCompilerOptions(): CompilerOptions;
|
||||
|
||||
getSourceFiles(): ReadonlyArray<SourceFile>;
|
||||
getSourceFile(fileName: string): SourceFile | undefined;
|
||||
getResolvedTypeReferenceDirectives(): ReadonlyMap<ResolvedTypeReferenceDirective>;
|
||||
getResolvedTypeReferenceDirectives(): ReadonlyMap<ResolvedTypeReferenceDirective | undefined>;
|
||||
|
||||
readonly redirectTargetsMap: RedirectTargetsMap;
|
||||
}
|
||||
@@ -2988,7 +3079,7 @@ namespace ts {
|
||||
|
||||
getFullyQualifiedName(symbol: Symbol): string;
|
||||
getAugmentedPropertiesOfType(type: Type): Symbol[];
|
||||
getRootSymbols(symbol: Symbol): Symbol[];
|
||||
getRootSymbols(symbol: Symbol): ReadonlyArray<Symbol>;
|
||||
getContextualType(node: Expression): Type | undefined;
|
||||
/* @internal */ getContextualTypeForObjectLiteralElement(element: ObjectLiteralElementLike): Type | undefined;
|
||||
/* @internal */ getContextualTypeForArgumentAtIndex(call: CallLikeExpression, argIndex: number): Type | undefined;
|
||||
@@ -3020,8 +3111,6 @@ namespace ts {
|
||||
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
|
||||
/** Unlike `getExportsOfModule`, this includes properties of an `export =` value. */
|
||||
/* @internal */ getExportsAndPropertiesOfModule(moduleSymbol: Symbol): Symbol[];
|
||||
|
||||
getAllAttributesTypeFromJsxOpeningLikeElement(elementNode: JsxOpeningLikeElement): Type | undefined;
|
||||
getJsxIntrinsicTagNamesAt(location: Node): Symbol[];
|
||||
isOptionalParameter(node: ParameterDeclaration): boolean;
|
||||
getAmbientModules(): Symbol[];
|
||||
@@ -3084,11 +3173,13 @@ namespace ts {
|
||||
/* @internal */ getTypeCount(): number;
|
||||
|
||||
/* @internal */ isArrayLikeType(type: Type): boolean;
|
||||
/* @internal */ getObjectFlags(type: Type): ObjectFlags;
|
||||
|
||||
/**
|
||||
* True if `contextualType` should not be considered for completions because
|
||||
* e.g. it specifies `kind: "a"` and obj has `kind: "b"`.
|
||||
*/
|
||||
/* @internal */ isTypeInvalidDueToUnionDiscriminant(contextualType: Type, obj: ObjectLiteralExpression): boolean;
|
||||
/* @internal */ isTypeInvalidDueToUnionDiscriminant(contextualType: Type, obj: ObjectLiteralExpression | JsxAttributes): boolean;
|
||||
/**
|
||||
* For a union, will include a property if it's defined in *any* of the member types.
|
||||
* So for `{ a } | { b }`, this will include both `a` and `b`.
|
||||
@@ -3177,6 +3268,8 @@ namespace ts {
|
||||
InTypeAlias = 1 << 23, // Writing type in type alias declaration
|
||||
InInitialEntityName = 1 << 24, // Set when writing the LHS of an entity name or entity name expression
|
||||
InReverseMappedType = 1 << 25,
|
||||
|
||||
/* @internal */ DoNotIncludeSymbolChain = 1 << 26, // Skip looking up and printing an accessible symbol chain
|
||||
}
|
||||
|
||||
// Ensure the shared flags between this and `NodeBuilderFlags` stay in alignment
|
||||
@@ -3239,6 +3332,9 @@ namespace ts {
|
||||
|
||||
// Prefer aliases which are not directly visible
|
||||
UseAliasDefinedOutsideCurrentScope = 0x00000008,
|
||||
|
||||
// Skip building an accessible symbol chain
|
||||
/* @internal */ DoNotIncludeSymbolChain = 0x00000010,
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -3365,6 +3461,7 @@ namespace ts {
|
||||
// of a type, such as the global `Promise` type in lib.d.ts).
|
||||
VoidNullableOrNeverType, // The TypeReferenceNode resolves to a Void-like, Nullable, or Never type.
|
||||
NumberLikeType, // The TypeReferenceNode resolves to a Number-like type.
|
||||
BigIntLikeType, // The TypeReferenceNode resolves to a BigInt-like type.
|
||||
StringLikeType, // The TypeReferenceNode resolves to a String-like type.
|
||||
BooleanType, // The TypeReferenceNode resolves to a Boolean-like type.
|
||||
ArrayLikeType, // The TypeReferenceNode resolves to an Array-like type.
|
||||
@@ -3397,7 +3494,7 @@ namespace ts {
|
||||
createTypeOfDeclaration(declaration: AccessorDeclaration | VariableLikeDeclaration | PropertyAccessExpression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker, addUndefined?: boolean): TypeNode | undefined;
|
||||
createReturnTypeOfSignatureDeclaration(signatureDeclaration: SignatureDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined;
|
||||
createTypeOfExpression(expr: Expression, enclosingDeclaration: Node, flags: NodeBuilderFlags, tracker: SymbolTracker): TypeNode | undefined;
|
||||
createLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): Expression;
|
||||
createLiteralConstValue(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration, tracker: SymbolTracker): Expression;
|
||||
isSymbolAccessible(symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags | undefined, shouldComputeAliasToMarkVisible: boolean): SymbolAccessibilityResult;
|
||||
isEntityNameVisible(entityName: EntityNameOrEntityNameExpression, enclosingDeclaration: Node): SymbolVisibilityResult;
|
||||
// Returns the constant value this property access resolves to, or 'undefined' for a non-constant
|
||||
@@ -3553,6 +3650,7 @@ namespace ts {
|
||||
originatingImport?: ImportDeclaration | ImportCall; // Import declaration which produced the symbol, present if the symbol is marked as uncallable but had call signatures in `resolveESModuleSymbol`
|
||||
lateSymbol?: Symbol; // Late-bound symbol for a computed property
|
||||
specifierCache?: Map<string>; // For symbols corresponding to external modules, a cache of incoming path -> module specifier name mappings
|
||||
variances?: Variance[]; // Alias symbol type argument variance cache
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -3589,6 +3687,7 @@ namespace ts {
|
||||
export interface ReverseMappedSymbol extends TransientSymbol {
|
||||
propertyType: Type;
|
||||
mappedType: MappedType;
|
||||
constraintType: IndexType;
|
||||
}
|
||||
|
||||
export const enum InternalSymbolName {
|
||||
@@ -3681,7 +3780,6 @@ namespace ts {
|
||||
resolvedType?: Type; // Cached type of type node
|
||||
resolvedEnumType?: Type; // Cached constraint type from enum jsdoc tag
|
||||
resolvedSignature?: Signature; // Cached signature of signature node or call expression
|
||||
resolvedSignatures?: Map<Signature[]>; // Cached signatures of jsx node
|
||||
resolvedSymbol?: Symbol; // Cached name resolution result
|
||||
resolvedIndexInfo?: IndexInfo; // Cached indexing info resolution result
|
||||
maybeTypePredicate?: boolean; // Cached check whether call expression might reference a type predicate
|
||||
@@ -3708,29 +3806,27 @@ namespace ts {
|
||||
Number = 1 << 3,
|
||||
Boolean = 1 << 4,
|
||||
Enum = 1 << 5,
|
||||
StringLiteral = 1 << 6,
|
||||
NumberLiteral = 1 << 7,
|
||||
BooleanLiteral = 1 << 8,
|
||||
EnumLiteral = 1 << 9, // Always combined with StringLiteral, NumberLiteral, or Union
|
||||
ESSymbol = 1 << 10, // Type of symbol primitive introduced in ES6
|
||||
UniqueESSymbol = 1 << 11, // unique symbol
|
||||
Void = 1 << 12,
|
||||
Undefined = 1 << 13,
|
||||
Null = 1 << 14,
|
||||
Never = 1 << 15, // Never type
|
||||
TypeParameter = 1 << 16, // Type parameter
|
||||
Object = 1 << 17, // Object type
|
||||
Union = 1 << 18, // Union (T | U)
|
||||
Intersection = 1 << 19, // Intersection (T & U)
|
||||
Index = 1 << 20, // keyof T
|
||||
IndexedAccess = 1 << 21, // T[K]
|
||||
Conditional = 1 << 22, // T extends U ? X : Y
|
||||
Substitution = 1 << 23, // Type parameter substitution
|
||||
NonPrimitive = 1 << 24, // intrinsic object type
|
||||
/* @internal */
|
||||
FreshLiteral = 1 << 25, // Fresh literal or unique type
|
||||
/* @internal */
|
||||
UnionOfPrimitiveTypes = 1 << 26, // Type is union of primitive types
|
||||
BigInt = 1 << 6,
|
||||
StringLiteral = 1 << 7,
|
||||
NumberLiteral = 1 << 8,
|
||||
BooleanLiteral = 1 << 9,
|
||||
EnumLiteral = 1 << 10, // Always combined with StringLiteral, NumberLiteral, or Union
|
||||
BigIntLiteral = 1 << 11,
|
||||
ESSymbol = 1 << 12, // Type of symbol primitive introduced in ES6
|
||||
UniqueESSymbol = 1 << 13, // unique symbol
|
||||
Void = 1 << 14,
|
||||
Undefined = 1 << 15,
|
||||
Null = 1 << 16,
|
||||
Never = 1 << 17, // Never type
|
||||
TypeParameter = 1 << 18, // Type parameter
|
||||
Object = 1 << 19, // Object type
|
||||
Union = 1 << 20, // Union (T | U)
|
||||
Intersection = 1 << 21, // Intersection (T & U)
|
||||
Index = 1 << 22, // keyof T
|
||||
IndexedAccess = 1 << 23, // T[K]
|
||||
Conditional = 1 << 24, // T extends U ? X : Y
|
||||
Substitution = 1 << 25, // Type parameter substitution
|
||||
NonPrimitive = 1 << 26, // intrinsic object type
|
||||
/* @internal */
|
||||
ContainsWideningType = 1 << 27, // Type is or contains undefined or null widening type
|
||||
/* @internal */
|
||||
@@ -3742,26 +3838,27 @@ namespace ts {
|
||||
AnyOrUnknown = Any | Unknown,
|
||||
/* @internal */
|
||||
Nullable = Undefined | Null,
|
||||
Literal = StringLiteral | NumberLiteral | BooleanLiteral,
|
||||
Literal = StringLiteral | NumberLiteral | BigIntLiteral | BooleanLiteral,
|
||||
Unit = Literal | UniqueESSymbol | Nullable,
|
||||
StringOrNumberLiteral = StringLiteral | NumberLiteral,
|
||||
/* @internal */
|
||||
StringOrNumberLiteralOrUnique = StringLiteral | NumberLiteral | UniqueESSymbol,
|
||||
/* @internal */
|
||||
DefinitelyFalsy = StringLiteral | NumberLiteral | BooleanLiteral | Void | Undefined | Null,
|
||||
PossiblyFalsy = DefinitelyFalsy | String | Number | Boolean,
|
||||
DefinitelyFalsy = StringLiteral | NumberLiteral | BigIntLiteral | BooleanLiteral | Void | Undefined | Null,
|
||||
PossiblyFalsy = DefinitelyFalsy | String | Number | BigInt | Boolean,
|
||||
/* @internal */
|
||||
Intrinsic = Any | Unknown | String | Number | Boolean | BooleanLiteral | ESSymbol | Void | Undefined | Null | Never | NonPrimitive,
|
||||
Intrinsic = Any | Unknown | String | Number | BigInt | Boolean | BooleanLiteral | ESSymbol | Void | Undefined | Null | Never | NonPrimitive,
|
||||
/* @internal */
|
||||
Primitive = String | Number | Boolean | Enum | EnumLiteral | ESSymbol | Void | Undefined | Null | Literal | UniqueESSymbol,
|
||||
Primitive = String | Number | BigInt | Boolean | Enum | EnumLiteral | ESSymbol | Void | Undefined | Null | Literal | UniqueESSymbol,
|
||||
StringLike = String | StringLiteral,
|
||||
NumberLike = Number | NumberLiteral | Enum,
|
||||
BigIntLike = BigInt | BigIntLiteral,
|
||||
BooleanLike = Boolean | BooleanLiteral,
|
||||
EnumLike = Enum | EnumLiteral,
|
||||
ESSymbolLike = ESSymbol | UniqueESSymbol,
|
||||
VoidLike = Void | Undefined,
|
||||
/* @internal */
|
||||
DisjointDomains = NonPrimitive | StringLike | NumberLike | BooleanLike | ESSymbolLike | VoidLike | Null,
|
||||
DisjointDomains = NonPrimitive | StringLike | NumberLike | BigIntLike | BooleanLike | ESSymbolLike | VoidLike | Null,
|
||||
UnionOrIntersection = Union | Intersection,
|
||||
StructuredType = Object | Union | Intersection,
|
||||
TypeVariable = TypeParameter | IndexedAccess,
|
||||
@@ -3772,7 +3869,7 @@ namespace ts {
|
||||
|
||||
// 'Narrowable' types are types where narrowing actually narrows.
|
||||
// This *should* be every type other than null, undefined, void, and never
|
||||
Narrowable = Any | Unknown | StructuredOrInstantiable | StringLike | NumberLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive,
|
||||
Narrowable = Any | Unknown | StructuredOrInstantiable | StringLike | NumberLike | BigIntLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive,
|
||||
NotUnionOrUnit = Any | Unknown | ESSymbol | Object | NonPrimitive,
|
||||
/* @internal */
|
||||
NotPrimitiveUnion = Any | Unknown | Enum | Void | Never | StructuredOrInstantiable,
|
||||
@@ -3805,6 +3902,7 @@ namespace ts {
|
||||
pattern?: DestructuringPattern; // Destructuring pattern represented by type (if any)
|
||||
aliasSymbol?: Symbol; // Alias associated with type
|
||||
aliasTypeArguments?: ReadonlyArray<Type>; // Alias type arguments (if any)
|
||||
/* @internal */ aliasTypeArgumentsContainsMarker?: boolean; // Alias type arguments (if any)
|
||||
/* @internal */
|
||||
wildcardInstantiation?: Type; // Instantiation with type parameters mapped to wildcard type
|
||||
/* @internal */
|
||||
@@ -3828,10 +3926,11 @@ namespace ts {
|
||||
|
||||
// String literal types (TypeFlags.StringLiteral)
|
||||
// Numeric literal types (TypeFlags.NumberLiteral)
|
||||
// BigInt literal types (TypeFlags.BigIntLiteral)
|
||||
export interface LiteralType extends Type {
|
||||
value: string | number; // Value of literal
|
||||
freshType: LiteralType; // Fresh version of type
|
||||
regularType: LiteralType; // Regular version of type
|
||||
value: string | number | PseudoBigInt; // Value of literal
|
||||
freshType: LiteralType; // Fresh version of type
|
||||
regularType: LiteralType; // Regular version of type
|
||||
}
|
||||
|
||||
// Unique symbol types (TypeFlags.UniqueESSymbol)
|
||||
@@ -3847,6 +3946,10 @@ namespace ts {
|
||||
value: number;
|
||||
}
|
||||
|
||||
export interface BigIntLiteralType extends LiteralType {
|
||||
value: PseudoBigInt;
|
||||
}
|
||||
|
||||
// Enum types (TypeFlags.Enum)
|
||||
export interface EnumType extends Type {
|
||||
}
|
||||
@@ -3867,6 +3970,7 @@ namespace ts {
|
||||
JsxAttributes = 1 << 12, // Jsx attributes type
|
||||
MarkerType = 1 << 13, // Marker type used for variance probing
|
||||
JSLiteral = 1 << 14, // Object type declared in JS - disables errors on read/write of nonexisting members
|
||||
FreshLiteral = 1 << 15, // Fresh object literal
|
||||
ClassOrInterface = Class | Interface
|
||||
}
|
||||
|
||||
@@ -3962,7 +4066,10 @@ namespace ts {
|
||||
couldContainTypeVariables: boolean;
|
||||
}
|
||||
|
||||
export interface UnionType extends UnionOrIntersectionType { }
|
||||
export interface UnionType extends UnionOrIntersectionType {
|
||||
/* @internal */
|
||||
primitiveTypesOnly: boolean;
|
||||
}
|
||||
|
||||
export interface IntersectionType extends UnionOrIntersectionType {
|
||||
/* @internal */
|
||||
@@ -3986,6 +4093,7 @@ namespace ts {
|
||||
templateType?: Type;
|
||||
modifiersType?: Type;
|
||||
resolvedApparentType?: Type;
|
||||
instantiating?: boolean;
|
||||
}
|
||||
|
||||
export interface EvolvingArrayType extends ObjectType {
|
||||
@@ -3997,6 +4105,7 @@ namespace ts {
|
||||
export interface ReverseMappedType extends ObjectType {
|
||||
source: Type;
|
||||
mappedType: MappedType;
|
||||
constraintType: IndexType;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -4121,6 +4230,13 @@ namespace ts {
|
||||
substitute: Type; // Type to substitute for type parameter
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export const enum JsxReferenceKind {
|
||||
Component,
|
||||
Function,
|
||||
Mixed
|
||||
}
|
||||
|
||||
export const enum SignatureKind {
|
||||
Call,
|
||||
Construct,
|
||||
@@ -4257,6 +4373,15 @@ namespace ts {
|
||||
Property,
|
||||
// F.prototype = { ... }
|
||||
Prototype,
|
||||
// Object.defineProperty(x, 'name', { value: any, writable?: boolean (false by default) });
|
||||
// Object.defineProperty(x, 'name', { get: Function, set: Function });
|
||||
// Object.defineProperty(x, 'name', { get: Function });
|
||||
// Object.defineProperty(x, 'name', { set: Function });
|
||||
ObjectDefinePropertyValue,
|
||||
// Object.defineProperty(exports || module.exports, 'name', ...);
|
||||
ObjectDefinePropertyExports,
|
||||
// Object.defineProperty(Foo.prototype, 'name', ...);
|
||||
ObjectDefinePrototypeProperty,
|
||||
}
|
||||
|
||||
/** @deprecated Use FileExtensionInfo instead. */
|
||||
@@ -4370,6 +4495,7 @@ namespace ts {
|
||||
downlevelIteration?: boolean;
|
||||
emitBOM?: boolean;
|
||||
emitDecoratorMetadata?: boolean;
|
||||
experimentalBigInt?: boolean;
|
||||
experimentalDecorators?: boolean;
|
||||
forceConsistentCasingInFileNames?: boolean;
|
||||
/*@internal*/help?: boolean;
|
||||
@@ -4442,6 +4568,7 @@ namespace ts {
|
||||
/*@internal*/ version?: boolean;
|
||||
/*@internal*/ watch?: boolean;
|
||||
esModuleInterop?: boolean;
|
||||
/* @internal */ showConfig?: boolean;
|
||||
|
||||
[option: string]: CompilerOptionsValue | TsConfigSourceFile | undefined;
|
||||
}
|
||||
@@ -4840,6 +4967,8 @@ namespace ts {
|
||||
// The location of the .d.ts file we located, or undefined if resolution failed
|
||||
resolvedFileName: string | undefined;
|
||||
packageId?: PackageId;
|
||||
/** True if `resolvedFileName` comes from `node_modules`. */
|
||||
isExternalLibraryImport?: boolean;
|
||||
}
|
||||
|
||||
export interface ResolvedTypeReferenceDirectiveWithFailedLookupLocations {
|
||||
@@ -4871,13 +5000,13 @@ namespace ts {
|
||||
* If resolveModuleNames is implemented then implementation for members from ModuleResolutionHost can be just
|
||||
* 'throw new Error("NotImplemented")'
|
||||
*/
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): (ResolvedModule | undefined)[];
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference): (ResolvedModule | undefined)[];
|
||||
/**
|
||||
* This method is a companion for 'resolveModuleNames' and is used to resolve 'types' references to actual type declaration files
|
||||
*/
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): (ResolvedTypeReferenceDirective | undefined)[];
|
||||
getEnvironmentVariable?(name: string): string | undefined;
|
||||
/* @internal */ onReleaseOldSourceFile?(oldSourceFile: SourceFile, oldOptions: CompilerOptions): void;
|
||||
/* @internal */ onReleaseOldSourceFile?(oldSourceFile: SourceFile, oldOptions: CompilerOptions, hasSourceFileByPath: boolean): void;
|
||||
/* @internal */ hasInvalidatedResolution?: HasInvalidatedResolution;
|
||||
/* @internal */ hasChangedAutomaticTypeDirectiveNames?: boolean;
|
||||
createHash?(data: string): string;
|
||||
@@ -5091,7 +5220,6 @@ namespace ts {
|
||||
useCaseSensitiveFileNames(): boolean;
|
||||
getCurrentDirectory(): string;
|
||||
|
||||
/* @internal */
|
||||
isSourceFileFromExternalLibrary(file: SourceFile): boolean;
|
||||
getLibFileFromReference(ref: FileReference): SourceFile | undefined;
|
||||
|
||||
@@ -5449,7 +5577,7 @@ namespace ts {
|
||||
reportInaccessibleThisError?(): void;
|
||||
reportPrivateInBaseOfClassExpression?(propertyName: string): void;
|
||||
reportInaccessibleUniqueSymbolError?(): void;
|
||||
moduleResolverHost?: EmitHost;
|
||||
moduleResolverHost?: ModuleSpecifierResolutionHost & { getSourceFiles(): ReadonlyArray<SourceFile>, getCommonSourceDirectory(): string };
|
||||
trackReferencedAmbientModule?(decl: ModuleDeclaration, symbol: Symbol): void;
|
||||
trackExternalModuleSymbolOfImportTypeNode?(symbol: Symbol): void;
|
||||
}
|
||||
@@ -5502,33 +5630,34 @@ namespace ts {
|
||||
BarDelimited = 1 << 2, // Each list item is space-and-bar (" |") delimited.
|
||||
AmpersandDelimited = 1 << 3, // Each list item is space-and-ampersand (" &") delimited.
|
||||
CommaDelimited = 1 << 4, // Each list item is comma (",") delimited.
|
||||
DelimitersMask = BarDelimited | AmpersandDelimited | CommaDelimited,
|
||||
AsteriskDelimited = 1 << 5, // Each list item is asterisk ("\n *") delimited, used with JSDoc.
|
||||
DelimitersMask = BarDelimited | AmpersandDelimited | CommaDelimited | AsteriskDelimited,
|
||||
|
||||
AllowTrailingComma = 1 << 5, // Write a trailing comma (",") if present.
|
||||
AllowTrailingComma = 1 << 6, // Write a trailing comma (",") if present.
|
||||
|
||||
// Whitespace
|
||||
Indented = 1 << 6, // The list should be indented.
|
||||
SpaceBetweenBraces = 1 << 7, // Inserts a space after the opening brace and before the closing brace.
|
||||
SpaceBetweenSiblings = 1 << 8, // Inserts a space between each sibling node.
|
||||
Indented = 1 << 7, // The list should be indented.
|
||||
SpaceBetweenBraces = 1 << 8, // Inserts a space after the opening brace and before the closing brace.
|
||||
SpaceBetweenSiblings = 1 << 9, // Inserts a space between each sibling node.
|
||||
|
||||
// Brackets/Braces
|
||||
Braces = 1 << 9, // The list is surrounded by "{" and "}".
|
||||
Parenthesis = 1 << 10, // The list is surrounded by "(" and ")".
|
||||
AngleBrackets = 1 << 11, // The list is surrounded by "<" and ">".
|
||||
SquareBrackets = 1 << 12, // The list is surrounded by "[" and "]".
|
||||
Braces = 1 << 10, // The list is surrounded by "{" and "}".
|
||||
Parenthesis = 1 << 11, // The list is surrounded by "(" and ")".
|
||||
AngleBrackets = 1 << 12, // The list is surrounded by "<" and ">".
|
||||
SquareBrackets = 1 << 13, // The list is surrounded by "[" and "]".
|
||||
BracketsMask = Braces | Parenthesis | AngleBrackets | SquareBrackets,
|
||||
|
||||
OptionalIfUndefined = 1 << 13, // Do not emit brackets if the list is undefined.
|
||||
OptionalIfEmpty = 1 << 14, // Do not emit brackets if the list is empty.
|
||||
OptionalIfUndefined = 1 << 14, // Do not emit brackets if the list is undefined.
|
||||
OptionalIfEmpty = 1 << 15, // Do not emit brackets if the list is empty.
|
||||
Optional = OptionalIfUndefined | OptionalIfEmpty,
|
||||
|
||||
// Other
|
||||
PreferNewLine = 1 << 15, // Prefer adding a LineTerminator between synthesized nodes.
|
||||
NoTrailingNewLine = 1 << 16, // Do not emit a trailing NewLine for a MultiLine list.
|
||||
NoInterveningComments = 1 << 17, // Do not emit comments between each node
|
||||
PreferNewLine = 1 << 16, // Prefer adding a LineTerminator between synthesized nodes.
|
||||
NoTrailingNewLine = 1 << 17, // Do not emit a trailing NewLine for a MultiLine list.
|
||||
NoInterveningComments = 1 << 18, // Do not emit comments between each node
|
||||
|
||||
NoSpaceIfEmpty = 1 << 18, // If the literal is empty, do not add spaces between braces.
|
||||
SingleElement = 1 << 19,
|
||||
NoSpaceIfEmpty = 1 << 19, // If the literal is empty, do not add spaces between braces.
|
||||
SingleElement = 1 << 20,
|
||||
|
||||
// Precomputed Formats
|
||||
Modifiers = SingleLine | SpaceBetweenSiblings | NoInterveningComments,
|
||||
@@ -5568,6 +5697,7 @@ namespace ts {
|
||||
TypeParameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | AngleBrackets | Optional,
|
||||
Parameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Parenthesis,
|
||||
IndexSignatureParameters = CommaDelimited | SpaceBetweenSiblings | SingleLine | Indented | SquareBrackets,
|
||||
JSDocComment = MultiLine | AsteriskDelimited,
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
@@ -5716,4 +5846,10 @@ namespace ts {
|
||||
readonly importModuleSpecifierEnding?: "minimal" | "index" | "js";
|
||||
readonly allowTextChangesInNewFiles?: boolean;
|
||||
}
|
||||
|
||||
/** Represents a bigint literal value without requiring bigint support */
|
||||
export interface PseudoBigInt {
|
||||
negative: boolean;
|
||||
base10Value: string;
|
||||
}
|
||||
}
|
||||
|
||||
+164
-31
@@ -7,7 +7,7 @@ namespace ts {
|
||||
return pathIsRelative(moduleName) || isRootedDiskPath(moduleName);
|
||||
}
|
||||
|
||||
export function sortAndDeduplicateDiagnostics<T extends Diagnostic>(diagnostics: ReadonlyArray<T>): T[] {
|
||||
export function sortAndDeduplicateDiagnostics<T extends Diagnostic>(diagnostics: ReadonlyArray<T>): SortedReadonlyArray<T> {
|
||||
return sortAndDeduplicate<T>(diagnostics, compareDiagnostics);
|
||||
}
|
||||
}
|
||||
@@ -228,9 +228,9 @@ namespace ts {
|
||||
sourceFile.resolvedModules.set(moduleNameText, resolvedModule);
|
||||
}
|
||||
|
||||
export function setResolvedTypeReferenceDirective(sourceFile: SourceFile, typeReferenceDirectiveName: string, resolvedTypeReferenceDirective: ResolvedTypeReferenceDirective): void {
|
||||
export function setResolvedTypeReferenceDirective(sourceFile: SourceFile, typeReferenceDirectiveName: string, resolvedTypeReferenceDirective?: ResolvedTypeReferenceDirective): void {
|
||||
if (!sourceFile.resolvedTypeReferenceDirectiveNames) {
|
||||
sourceFile.resolvedTypeReferenceDirectiveNames = createMap<ResolvedTypeReferenceDirective>();
|
||||
sourceFile.resolvedTypeReferenceDirectiveNames = createMap<ResolvedTypeReferenceDirective | undefined>();
|
||||
}
|
||||
|
||||
sourceFile.resolvedTypeReferenceDirectiveNames.set(typeReferenceDirectiveName, resolvedTypeReferenceDirective);
|
||||
@@ -528,7 +528,10 @@ namespace ts {
|
||||
export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile, neverAsciiEscape: boolean | undefined) {
|
||||
// If we don't need to downlevel and we can reach the original source text using
|
||||
// the node's parent reference, then simply get the text as it was originally written.
|
||||
if (!nodeIsSynthesized(node) && node.parent && !(isNumericLiteral(node) && node.numericLiteralFlags & TokenFlags.ContainsSeparator)) {
|
||||
if (!nodeIsSynthesized(node) && node.parent && !(
|
||||
(isNumericLiteral(node) && node.numericLiteralFlags & TokenFlags.ContainsSeparator) ||
|
||||
isBigIntLiteral(node)
|
||||
)) {
|
||||
return getSourceTextOfNodeFromSourceFile(sourceFile, node);
|
||||
}
|
||||
|
||||
@@ -555,6 +558,7 @@ namespace ts {
|
||||
case SyntaxKind.TemplateTail:
|
||||
return "}" + escapeText(node.text, CharacterCodes.backtick) + "`";
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.RegularExpressionLiteral:
|
||||
return node.text;
|
||||
}
|
||||
@@ -766,12 +770,13 @@ namespace ts {
|
||||
return info.declaration ? declarationNameToString(info.declaration.parameters[0].name) : undefined;
|
||||
}
|
||||
|
||||
export function getTextOfPropertyName(name: PropertyName): __String {
|
||||
export function getTextOfPropertyName(name: PropertyName | NoSubstitutionTemplateLiteral): __String {
|
||||
switch (name.kind) {
|
||||
case SyntaxKind.Identifier:
|
||||
return name.escapedText;
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
return escapeLeadingUnderscores(name.text);
|
||||
case SyntaxKind.ComputedPropertyName:
|
||||
return isStringOrNumericLiteralLike(name.expression) ? escapeLeadingUnderscores(name.expression.text) : undefined!; // TODO: GH#18217 Almost all uses of this assume the result to be defined!
|
||||
@@ -976,6 +981,7 @@ namespace ts {
|
||||
case SyntaxKind.AnyKeyword:
|
||||
case SyntaxKind.UnknownKeyword:
|
||||
case SyntaxKind.NumberKeyword:
|
||||
case SyntaxKind.BigIntKeyword:
|
||||
case SyntaxKind.StringKeyword:
|
||||
case SyntaxKind.BooleanKeyword:
|
||||
case SyntaxKind.SymbolKeyword:
|
||||
@@ -1599,6 +1605,7 @@ namespace ts {
|
||||
}
|
||||
// falls through
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.ThisKeyword:
|
||||
return isInExpressionContext(node);
|
||||
@@ -1771,7 +1778,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function isAssignmentDeclaration(decl: Declaration) {
|
||||
return isBinaryExpression(decl) || isPropertyAccessExpression(decl) || isIdentifier(decl);
|
||||
return isBinaryExpression(decl) || isPropertyAccessExpression(decl) || isIdentifier(decl) || isCallExpression(decl);
|
||||
}
|
||||
|
||||
/** Get the initializer, taking into account defaulted Javascript initializers */
|
||||
@@ -1790,16 +1797,26 @@ namespace ts {
|
||||
return init && getExpandoInitializer(init, isPrototypeAccess(node.name));
|
||||
}
|
||||
|
||||
function hasExpandoValueProperty(node: ObjectLiteralExpression, isPrototypeAssignment: boolean) {
|
||||
return forEach(node.properties, p => isPropertyAssignment(p) && isIdentifier(p.name) && p.name.escapedText === "value" && p.initializer && getExpandoInitializer(p.initializer, isPrototypeAssignment));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the assignment 'initializer' -- the righthand side-- when the initializer is container-like (See getExpandoInitializer).
|
||||
* We treat the right hand side of assignments with container-like initalizers as declarations.
|
||||
*/
|
||||
export function getAssignedExpandoInitializer(node: Node) {
|
||||
export function getAssignedExpandoInitializer(node: Node | undefined) {
|
||||
if (node && node.parent && isBinaryExpression(node.parent) && node.parent.operatorToken.kind === SyntaxKind.EqualsToken) {
|
||||
const isPrototypeAssignment = isPrototypeAccess(node.parent.left);
|
||||
return getExpandoInitializer(node.parent.right, isPrototypeAssignment) ||
|
||||
getDefaultedExpandoInitializer(node.parent.left as EntityNameExpression, node.parent.right, isPrototypeAssignment);
|
||||
}
|
||||
if (node && isCallExpression(node) && isBindableObjectDefinePropertyCall(node)) {
|
||||
const result = hasExpandoValueProperty(node.arguments[2], node.arguments[1].text === "prototype");
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1906,12 +1923,35 @@ namespace ts {
|
||||
|
||||
/// Given a BinaryExpression, returns SpecialPropertyAssignmentKind for the various kinds of property
|
||||
/// assignments we treat as special in the binder
|
||||
export function getAssignmentDeclarationKind(expr: BinaryExpression): AssignmentDeclarationKind {
|
||||
export function getAssignmentDeclarationKind(expr: BinaryExpression | CallExpression): AssignmentDeclarationKind {
|
||||
const special = getAssignmentDeclarationKindWorker(expr);
|
||||
return special === AssignmentDeclarationKind.Property || isInJSFile(expr) ? special : AssignmentDeclarationKind.None;
|
||||
}
|
||||
|
||||
function getAssignmentDeclarationKindWorker(expr: BinaryExpression): AssignmentDeclarationKind {
|
||||
export function isBindableObjectDefinePropertyCall(expr: CallExpression): expr is BindableObjectDefinePropertyCall {
|
||||
return length(expr.arguments) === 3 &&
|
||||
isPropertyAccessExpression(expr.expression) &&
|
||||
isIdentifier(expr.expression.expression) &&
|
||||
idText(expr.expression.expression) === "Object" &&
|
||||
idText(expr.expression.name) === "defineProperty" &&
|
||||
isStringOrNumericLiteralLike(expr.arguments[1]) &&
|
||||
isEntityNameExpression(expr.arguments[0]);
|
||||
}
|
||||
|
||||
function getAssignmentDeclarationKindWorker(expr: BinaryExpression | CallExpression): AssignmentDeclarationKind {
|
||||
if (isCallExpression(expr)) {
|
||||
if (!isBindableObjectDefinePropertyCall(expr)) {
|
||||
return AssignmentDeclarationKind.None;
|
||||
}
|
||||
const entityName = expr.arguments[0];
|
||||
if (isExportsIdentifier(entityName) || isModuleExportsPropertyAccessExpression(entityName)) {
|
||||
return AssignmentDeclarationKind.ObjectDefinePropertyExports;
|
||||
}
|
||||
if (isPropertyAccessExpression(entityName) && entityName.name.escapedText === "prototype" && isEntityNameExpression(entityName.expression)) {
|
||||
return AssignmentDeclarationKind.ObjectDefinePrototypeProperty;
|
||||
}
|
||||
return AssignmentDeclarationKind.ObjectDefinePropertyValue;
|
||||
}
|
||||
if (expr.operatorToken.kind !== SyntaxKind.EqualsToken ||
|
||||
!isPropertyAccessExpression(expr.left)) {
|
||||
return AssignmentDeclarationKind.None;
|
||||
@@ -1928,7 +1968,7 @@ namespace ts {
|
||||
if (lhs.expression.kind === SyntaxKind.ThisKeyword) {
|
||||
return AssignmentDeclarationKind.ThisProperty;
|
||||
}
|
||||
else if (isIdentifier(lhs.expression) && lhs.expression.escapedText === "module" && lhs.name.escapedText === "exports") {
|
||||
else if (isModuleExportsPropertyAccessExpression(lhs)) {
|
||||
// module.exports = expr
|
||||
return AssignmentDeclarationKind.ModuleExports;
|
||||
}
|
||||
@@ -1993,7 +2033,7 @@ namespace ts {
|
||||
case SyntaxKind.ExternalModuleReference:
|
||||
return (node.parent as ExternalModuleReference).parent as AnyValidImportOrReExport;
|
||||
case SyntaxKind.CallExpression:
|
||||
return node.parent as AnyValidImportOrReExport;
|
||||
return isImportCall(node.parent) || isRequireCall(node.parent, /*checkArg*/ false) ? node.parent as RequireOrImportCall : undefined;
|
||||
case SyntaxKind.LiteralType:
|
||||
Debug.assert(isStringLiteral(node));
|
||||
return tryCast(node.parent.parent, isImportTypeNode) as ValidImportTypeNode | undefined;
|
||||
@@ -2457,6 +2497,7 @@ namespace ts {
|
||||
// export { x as <symbol> } from ...
|
||||
// export = <EntityNameExpression>
|
||||
// export default <EntityNameExpression>
|
||||
// module.exports = <EntityNameExpression>
|
||||
export function isAliasSymbolDeclaration(node: Node): boolean {
|
||||
return node.kind === SyntaxKind.ImportEqualsDeclaration ||
|
||||
node.kind === SyntaxKind.NamespaceExportDeclaration ||
|
||||
@@ -2465,7 +2506,7 @@ namespace ts {
|
||||
node.kind === SyntaxKind.ImportSpecifier ||
|
||||
node.kind === SyntaxKind.ExportSpecifier ||
|
||||
node.kind === SyntaxKind.ExportAssignment && exportAssignmentIsAlias(<ExportAssignment>node) ||
|
||||
isBinaryExpression(node) && getAssignmentDeclarationKind(node) === AssignmentDeclarationKind.ModuleExports;
|
||||
isBinaryExpression(node) && getAssignmentDeclarationKind(node) === AssignmentDeclarationKind.ModuleExports && exportAssignmentIsAlias(node);
|
||||
}
|
||||
|
||||
export function exportAssignmentIsAlias(node: ExportAssignment | BinaryExpression): boolean {
|
||||
@@ -2552,6 +2593,10 @@ namespace ts {
|
||||
return token !== undefined && isNonContextualKeyword(token);
|
||||
}
|
||||
|
||||
export function isIdentifierANonContextualKeyword({ originalKeywordKind }: Identifier): boolean {
|
||||
return !!originalKeywordKind && !isContextualKeyword(originalKeywordKind);
|
||||
}
|
||||
|
||||
export type TriviaKind = SyntaxKind.SingleLineCommentTrivia
|
||||
| SyntaxKind.MultiLineCommentTrivia
|
||||
| SyntaxKind.NewLineTrivia
|
||||
@@ -2867,6 +2912,7 @@ namespace ts {
|
||||
case SyntaxKind.TrueKeyword:
|
||||
case SyntaxKind.FalseKeyword:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.ArrayLiteralExpression:
|
||||
case SyntaxKind.ObjectLiteralExpression:
|
||||
@@ -2888,7 +2934,6 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function getBinaryOperatorPrecedence(kind: SyntaxKind): number {
|
||||
switch (kind) {
|
||||
case SyntaxKind.BarBarToken:
|
||||
@@ -3005,7 +3050,7 @@ namespace ts {
|
||||
return fileDiagnostics.get(fileName) || [];
|
||||
}
|
||||
|
||||
const fileDiags: Diagnostic[] = flatMap(filesWithDiagnostics, f => fileDiagnostics.get(f));
|
||||
const fileDiags: Diagnostic[] = flatMapToMutable(filesWithDiagnostics, f => fileDiagnostics.get(f));
|
||||
if (!nonFileDiagnostics.length) {
|
||||
return fileDiags;
|
||||
}
|
||||
@@ -3066,7 +3111,7 @@ namespace ts {
|
||||
|
||||
export function isIntrinsicJsxName(name: __String | string) {
|
||||
const ch = (name as string).charCodeAt(0);
|
||||
return (ch >= CharacterCodes.a && ch <= CharacterCodes.z) || (name as string).indexOf("-") > -1;
|
||||
return (ch >= CharacterCodes.a && ch <= CharacterCodes.z) || stringContains((name as string), "-");
|
||||
}
|
||||
|
||||
function get16BitUnicodeEscapeSequence(charCode: number): string {
|
||||
@@ -3311,7 +3356,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
export interface EmitFileNames {
|
||||
jsFilePath: string;
|
||||
jsFilePath: string | undefined;
|
||||
sourceMapFilePath: string | undefined;
|
||||
declarationFilePath: string | undefined;
|
||||
declarationMapPath: string | undefined;
|
||||
@@ -5043,14 +5088,19 @@ namespace ts {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SyntaxKind.CallExpression:
|
||||
case SyntaxKind.BinaryExpression: {
|
||||
const expr = declaration as BinaryExpression;
|
||||
const expr = declaration as BinaryExpression | CallExpression;
|
||||
switch (getAssignmentDeclarationKind(expr)) {
|
||||
case AssignmentDeclarationKind.ExportsProperty:
|
||||
case AssignmentDeclarationKind.ThisProperty:
|
||||
case AssignmentDeclarationKind.Property:
|
||||
case AssignmentDeclarationKind.PrototypeProperty:
|
||||
return (expr.left as PropertyAccessExpression).name;
|
||||
return ((expr as BinaryExpression).left as PropertyAccessExpression).name;
|
||||
case AssignmentDeclarationKind.ObjectDefinePropertyValue:
|
||||
case AssignmentDeclarationKind.ObjectDefinePropertyExports:
|
||||
case AssignmentDeclarationKind.ObjectDefinePrototypeProperty:
|
||||
return (expr as BindableObjectDefinePropertyCall).arguments[1];
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
@@ -5261,7 +5311,7 @@ namespace ts {
|
||||
}
|
||||
if (isJSDocTypeAlias(node)) {
|
||||
Debug.assert(node.parent.kind === SyntaxKind.JSDocComment);
|
||||
return flatMap(node.parent.tags, tag => isJSDocTemplateTag(tag) ? tag.typeParameters : undefined) as ReadonlyArray<TypeParameterDeclaration>;
|
||||
return flatMap(node.parent.tags, tag => isJSDocTemplateTag(tag) ? tag.typeParameters : undefined);
|
||||
}
|
||||
if (node.typeParameters) {
|
||||
return node.typeParameters;
|
||||
@@ -5294,6 +5344,10 @@ namespace ts {
|
||||
return node.kind === SyntaxKind.NumericLiteral;
|
||||
}
|
||||
|
||||
export function isBigIntLiteral(node: Node): node is BigIntLiteral {
|
||||
return node.kind === SyntaxKind.BigIntLiteral;
|
||||
}
|
||||
|
||||
export function isStringLiteral(node: Node): node is StringLiteral {
|
||||
return node.kind === SyntaxKind.StringLiteral;
|
||||
}
|
||||
@@ -6237,6 +6291,7 @@ namespace ts {
|
||||
|| kind === SyntaxKind.AnyKeyword
|
||||
|| kind === SyntaxKind.UnknownKeyword
|
||||
|| kind === SyntaxKind.NumberKeyword
|
||||
|| kind === SyntaxKind.BigIntKeyword
|
||||
|| kind === SyntaxKind.ObjectKeyword
|
||||
|| kind === SyntaxKind.BooleanKeyword
|
||||
|| kind === SyntaxKind.StringKeyword
|
||||
@@ -6419,6 +6474,7 @@ namespace ts {
|
||||
case SyntaxKind.Identifier:
|
||||
case SyntaxKind.RegularExpressionLiteral:
|
||||
case SyntaxKind.NumericLiteral:
|
||||
case SyntaxKind.BigIntLiteral:
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
case SyntaxKind.TemplateExpression:
|
||||
@@ -6861,7 +6917,6 @@ namespace ts {
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
/** @internal */
|
||||
export function isNamedImportsOrExports(node: Node): node is NamedImportsOrExports {
|
||||
return node.kind === SyntaxKind.NamedImports || node.kind === SyntaxKind.NamedExports;
|
||||
}
|
||||
@@ -6925,7 +6980,6 @@ namespace ts {
|
||||
getSourceMapSourceConstructor: () => <any>SourceMapSource,
|
||||
};
|
||||
|
||||
/* @internal */
|
||||
export function formatStringFromArgs(text: string, args: ArrayLike<string>, baseIndex = 0): string {
|
||||
return text.replace(/{(\d+)}/g, (_match, index: string) => Debug.assertDefined(args[+index + baseIndex]));
|
||||
}
|
||||
@@ -6936,7 +6990,6 @@ namespace ts {
|
||||
return localizedDiagnosticMessages && localizedDiagnosticMessages[message.key] || message.message;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: (string | number | undefined)[]): DiagnosticWithLocation;
|
||||
export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage): DiagnosticWithLocation {
|
||||
Debug.assertGreaterThanOrEqual(start, 0);
|
||||
@@ -6965,7 +7018,6 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function formatMessage(_dummy: any, message: DiagnosticMessage): string {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
|
||||
@@ -6976,7 +7028,6 @@ namespace ts {
|
||||
return text;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createCompilerDiagnostic(message: DiagnosticMessage, ...args: (string | number | undefined)[]): Diagnostic;
|
||||
export function createCompilerDiagnostic(message: DiagnosticMessage): Diagnostic {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
@@ -6997,7 +7048,6 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function createCompilerDiagnosticFromMessageChain(chain: DiagnosticMessageChain): Diagnostic {
|
||||
return {
|
||||
file: undefined,
|
||||
@@ -7010,7 +7060,6 @@ namespace ts {
|
||||
};
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain | undefined, message: DiagnosticMessage, ...args: (string | undefined)[]): DiagnosticMessageChain;
|
||||
export function chainDiagnosticMessages(details: DiagnosticMessageChain | undefined, message: DiagnosticMessage): DiagnosticMessageChain {
|
||||
let text = getLocaleSpecificMessage(message);
|
||||
@@ -7042,14 +7091,12 @@ namespace ts {
|
||||
return diagnostic.file ? diagnostic.file.path : undefined;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function compareDiagnostics(d1: Diagnostic, d2: Diagnostic): Comparison {
|
||||
return compareDiagnosticsSkipRelatedInformation(d1, d2) ||
|
||||
compareRelatedInformation(d1, d2) ||
|
||||
Comparison.EqualTo;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function compareDiagnosticsSkipRelatedInformation(d1: Diagnostic, d2: Diagnostic): Comparison {
|
||||
return compareStringsCaseSensitive(getDiagnosticFilePath(d1), getDiagnosticFilePath(d2)) ||
|
||||
compareValues(d1.start, d2.start) ||
|
||||
@@ -7387,7 +7434,6 @@ namespace ts {
|
||||
return rootLength > 0 && rootLength === path.length;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function convertToRelativePath(absoluteOrRelativePath: string, basePath: string, getCanonicalFileName: (path: string) => string): string {
|
||||
return !isRootedDiskPath(absoluteOrRelativePath)
|
||||
? absoluteOrRelativePath
|
||||
@@ -7804,7 +7850,7 @@ namespace ts {
|
||||
return `^(${pattern})${terminator}`;
|
||||
}
|
||||
|
||||
function getRegularExpressionsForWildcards(specs: ReadonlyArray<string> | undefined, basePath: string, usage: "files" | "directories" | "exclude"): string[] | undefined {
|
||||
export function getRegularExpressionsForWildcards(specs: ReadonlyArray<string> | undefined, basePath: string, usage: "files" | "directories" | "exclude"): ReadonlyArray<string> | undefined {
|
||||
if (specs === undefined || specs.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -8069,12 +8115,16 @@ namespace ts {
|
||||
* List of supported extensions in order of file resolution precedence.
|
||||
*/
|
||||
export const supportedTSExtensions: ReadonlyArray<Extension> = [Extension.Ts, Extension.Tsx, Extension.Dts];
|
||||
export const supportedTSExtensionsWithJson: ReadonlyArray<Extension> = [Extension.Ts, Extension.Tsx, Extension.Dts, Extension.Json];
|
||||
/** Must have ".d.ts" first because if ".ts" goes first, that will be detected as the extension instead of ".d.ts". */
|
||||
export const supportedTSExtensionsForExtractExtension: ReadonlyArray<Extension> = [Extension.Dts, Extension.Ts, Extension.Tsx];
|
||||
export const supportedJSExtensions: ReadonlyArray<Extension> = [Extension.Js, Extension.Jsx];
|
||||
export const supportedJSAndJsonExtensions: ReadonlyArray<Extension> = [Extension.Js, Extension.Jsx, Extension.Json];
|
||||
const allSupportedExtensions: ReadonlyArray<Extension> = [...supportedTSExtensions, ...supportedJSExtensions];
|
||||
const allSupportedExtensionsWithJson: ReadonlyArray<Extension> = [...supportedTSExtensions, ...supportedJSExtensions, Extension.Json];
|
||||
|
||||
export function getSupportedExtensions(options?: CompilerOptions): ReadonlyArray<Extension>;
|
||||
export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: ReadonlyArray<FileExtensionInfo>): ReadonlyArray<string>;
|
||||
export function getSupportedExtensions(options?: CompilerOptions, extraFileExtensions?: ReadonlyArray<FileExtensionInfo>): ReadonlyArray<string> {
|
||||
const needJsExtensions = options && options.allowJs;
|
||||
|
||||
@@ -8090,6 +8140,13 @@ namespace ts {
|
||||
return deduplicate<string>(extensions, equateStringsCaseSensitive, compareStringsCaseSensitive);
|
||||
}
|
||||
|
||||
export function getSuppoertedExtensionsWithJsonIfResolveJsonModule(options: CompilerOptions | undefined, supportedExtensions: ReadonlyArray<string>): ReadonlyArray<string> {
|
||||
if (!options || !options.resolveJsonModule) { return supportedExtensions; }
|
||||
if (supportedExtensions === allSupportedExtensions) { return allSupportedExtensionsWithJson; }
|
||||
if (supportedExtensions === supportedTSExtensions) { return supportedTSExtensionsWithJson; }
|
||||
return [...supportedExtensions, Extension.Json];
|
||||
}
|
||||
|
||||
function isJSLike(scriptKind: ScriptKind | undefined): boolean {
|
||||
return scriptKind === ScriptKind.JS || scriptKind === ScriptKind.JSX;
|
||||
}
|
||||
@@ -8109,7 +8166,8 @@ namespace ts {
|
||||
export function isSupportedSourceFileName(fileName: string, compilerOptions?: CompilerOptions, extraFileExtensions?: ReadonlyArray<FileExtensionInfo>) {
|
||||
if (!fileName) { return false; }
|
||||
|
||||
for (const extension of getSupportedExtensions(compilerOptions, extraFileExtensions)) {
|
||||
const supportedExtensions = getSupportedExtensions(compilerOptions, extraFileExtensions);
|
||||
for (const extension of getSuppoertedExtensionsWithJsonIfResolveJsonModule(compilerOptions, supportedExtensions)) {
|
||||
if (fileExtensionIs(fileName, extension)) {
|
||||
return true;
|
||||
}
|
||||
@@ -8448,4 +8506,79 @@ namespace ts {
|
||||
return got;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a bigint literal string, e.g. `0x1234n`,
|
||||
* to its decimal string representation, e.g. `4660`.
|
||||
*/
|
||||
export function parsePseudoBigInt(stringValue: string): string {
|
||||
let log2Base: number;
|
||||
switch (stringValue.charCodeAt(1)) { // "x" in "0x123"
|
||||
case CharacterCodes.b:
|
||||
case CharacterCodes.B: // 0b or 0B
|
||||
log2Base = 1;
|
||||
break;
|
||||
case CharacterCodes.o:
|
||||
case CharacterCodes.O: // 0o or 0O
|
||||
log2Base = 3;
|
||||
break;
|
||||
case CharacterCodes.x:
|
||||
case CharacterCodes.X: // 0x or 0X
|
||||
log2Base = 4;
|
||||
break;
|
||||
default: // already in decimal; omit trailing "n"
|
||||
const nIndex = stringValue.length - 1;
|
||||
// Skip leading 0s
|
||||
let nonZeroStart = 0;
|
||||
while (stringValue.charCodeAt(nonZeroStart) === CharacterCodes._0) {
|
||||
nonZeroStart++;
|
||||
}
|
||||
return stringValue.slice(nonZeroStart, nIndex) || "0";
|
||||
}
|
||||
|
||||
// Omit leading "0b", "0o", or "0x", and trailing "n"
|
||||
const startIndex = 2, endIndex = stringValue.length - 1;
|
||||
const bitsNeeded = (endIndex - startIndex) * log2Base;
|
||||
// Stores the value specified by the string as a LE array of 16-bit integers
|
||||
// using Uint16 instead of Uint32 so combining steps can use bitwise operators
|
||||
const segments = new Uint16Array((bitsNeeded >>> 4) + (bitsNeeded & 15 ? 1 : 0));
|
||||
// Add the digits, one at a time
|
||||
for (let i = endIndex - 1, bitOffset = 0; i >= startIndex; i--, bitOffset += log2Base) {
|
||||
const segment = bitOffset >>> 4;
|
||||
const digitChar = stringValue.charCodeAt(i);
|
||||
// Find character range: 0-9 < A-F < a-f
|
||||
const digit = digitChar <= CharacterCodes._9
|
||||
? digitChar - CharacterCodes._0
|
||||
: 10 + digitChar -
|
||||
(digitChar <= CharacterCodes.F ? CharacterCodes.A : CharacterCodes.a);
|
||||
const shiftedDigit = digit << (bitOffset & 15);
|
||||
segments[segment] |= shiftedDigit;
|
||||
const residual = shiftedDigit >>> 16;
|
||||
if (residual) segments[segment + 1] |= residual; // overflows segment
|
||||
}
|
||||
// Repeatedly divide segments by 10 and add remainder to base10Value
|
||||
let base10Value = "";
|
||||
let firstNonzeroSegment = segments.length - 1;
|
||||
let segmentsRemaining = true;
|
||||
while (segmentsRemaining) {
|
||||
let mod10 = 0;
|
||||
segmentsRemaining = false;
|
||||
for (let segment = firstNonzeroSegment; segment >= 0; segment--) {
|
||||
const newSegment = mod10 << 16 | segments[segment];
|
||||
const segmentValue = (newSegment / 10) | 0;
|
||||
segments[segment] = segmentValue;
|
||||
mod10 = newSegment - segmentValue * 10;
|
||||
if (segmentValue && !segmentsRemaining) {
|
||||
firstNonzeroSegment = segment;
|
||||
segmentsRemaining = true;
|
||||
}
|
||||
}
|
||||
base10Value = mod10 + base10Value;
|
||||
}
|
||||
return base10Value;
|
||||
}
|
||||
|
||||
export function pseudoBigIntToString({negative, base10Value}: PseudoBigInt): string {
|
||||
return (negative && base10Value !== "0" ? "-" : "") + base10Value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1111,6 +1111,7 @@ namespace ts {
|
||||
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
result = reduceNode((<TaggedTemplateExpression>node).tag, cbNode, result);
|
||||
result = reduceNodes((<TaggedTemplateExpression>node).typeArguments, cbNodes, result);
|
||||
result = reduceNode((<TaggedTemplateExpression>node).template, cbNode, result);
|
||||
break;
|
||||
|
||||
@@ -1377,6 +1378,7 @@ namespace ts {
|
||||
case SyntaxKind.JsxSelfClosingElement:
|
||||
case SyntaxKind.JsxOpeningElement:
|
||||
result = reduceNode((<JsxSelfClosingElement | JsxOpeningElement>node).tagName, cbNode, result);
|
||||
result = reduceNodes((<JsxSelfClosingElement | JsxOpeningElement>node).typeArguments, cbNode, result);
|
||||
result = reduceNode((<JsxSelfClosingElement | JsxOpeningElement>node).attributes, cbNode, result);
|
||||
break;
|
||||
|
||||
|
||||
+44
-23
@@ -43,7 +43,6 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export const screenStartingMessageCodes: number[] = [
|
||||
Diagnostics.Starting_compilation_in_watch_mode.code,
|
||||
Diagnostics.File_change_detected_Starting_incremental_compilation.code,
|
||||
@@ -106,6 +105,22 @@ namespace ts {
|
||||
|
||||
export type ReportEmitErrorSummary = (errorCount: number) => void;
|
||||
|
||||
export function getErrorCountForSummary(diagnostics: ReadonlyArray<Diagnostic>) {
|
||||
return countWhere(diagnostics, diagnostic => diagnostic.category === DiagnosticCategory.Error);
|
||||
}
|
||||
|
||||
export function getWatchErrorSummaryDiagnosticMessage(errorCount: number) {
|
||||
return errorCount === 1 ?
|
||||
Diagnostics.Found_1_error_Watching_for_file_changes :
|
||||
Diagnostics.Found_0_errors_Watching_for_file_changes;
|
||||
}
|
||||
|
||||
export function getErrorSummaryText(errorCount: number, newLine: string) {
|
||||
if (errorCount === 0) return "";
|
||||
const d = createCompilerDiagnostic(errorCount === 1 ? Diagnostics.Found_1_error : Diagnostics.Found_0_errors, errorCount);
|
||||
return `${newLine}${flattenDiagnosticMessageText(d.messageText, newLine)}${newLine}${newLine}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper that emit files, report diagnostics and lists emitted and/or source files depending on compiler options
|
||||
*/
|
||||
@@ -151,7 +166,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (reportSummary) {
|
||||
reportSummary(diagnostics.filter(diagnostic => diagnostic.category === DiagnosticCategory.Error).length);
|
||||
reportSummary(getErrorCountForSummary(diagnostics));
|
||||
}
|
||||
|
||||
if (emitSkipped && diagnostics.length > 0) {
|
||||
@@ -227,16 +242,16 @@ namespace ts {
|
||||
const compilerOptions = builderProgram.getCompilerOptions();
|
||||
const newLine = getNewLineCharacter(compilerOptions, () => system.newLine);
|
||||
|
||||
const reportSummary = (errorCount: number) => {
|
||||
if (errorCount === 1) {
|
||||
onWatchStatusChange!(createCompilerDiagnostic(Diagnostics.Found_1_error_Watching_for_file_changes, errorCount), newLine, compilerOptions);
|
||||
}
|
||||
else {
|
||||
onWatchStatusChange!(createCompilerDiagnostic(Diagnostics.Found_0_errors_Watching_for_file_changes, errorCount, errorCount), newLine, compilerOptions);
|
||||
}
|
||||
};
|
||||
|
||||
emitFilesAndReportErrors(builderProgram, reportDiagnostic, writeFileName, reportSummary);
|
||||
emitFilesAndReportErrors(
|
||||
builderProgram,
|
||||
reportDiagnostic,
|
||||
writeFileName,
|
||||
errorCount => onWatchStatusChange!(
|
||||
createCompilerDiagnostic(getWatchErrorSummaryDiagnosticMessage(errorCount), errorCount),
|
||||
newLine,
|
||||
compilerOptions
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -338,9 +353,9 @@ namespace ts {
|
||||
getEnvironmentVariable?(name: string): string | undefined;
|
||||
|
||||
/** If provided, used to resolve the module names, otherwise typescript's default module resolution */
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[]): ResolvedModule[];
|
||||
resolveModuleNames?(moduleNames: string[], containingFile: string, reusedNames?: string[], redirectedReference?: ResolvedProjectReference): (ResolvedModule | undefined)[];
|
||||
/** If provided, used to resolve type reference directives, otherwise typescript's default resolution */
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string): ResolvedTypeReferenceDirective[];
|
||||
resolveTypeReferenceDirectives?(typeReferenceDirectiveNames: string[], containingFile: string, redirectedReference?: ResolvedProjectReference): (ResolvedTypeReferenceDirective | undefined)[];
|
||||
}
|
||||
|
||||
/** Internal interface used to wire emit through same host */
|
||||
@@ -484,7 +499,8 @@ namespace ts {
|
||||
fileExists: path => host.fileExists(path),
|
||||
readFile,
|
||||
getCurrentDirectory,
|
||||
onUnRecoverableConfigFileDiagnostic: host.onUnRecoverableConfigFileDiagnostic
|
||||
onUnRecoverableConfigFileDiagnostic: host.onUnRecoverableConfigFileDiagnostic,
|
||||
trace: host.trace ? s => host.trace!(s) : undefined
|
||||
};
|
||||
|
||||
// From tsc we want to get already parsed result and hence check for rootFileNames
|
||||
@@ -558,11 +574,11 @@ namespace ts {
|
||||
);
|
||||
// Resolve module using host module resolution strategy if provided otherwise use resolution cache to resolve module names
|
||||
compilerHost.resolveModuleNames = host.resolveModuleNames ?
|
||||
((moduleNames, containingFile, reusedNames) => host.resolveModuleNames!(moduleNames, containingFile, reusedNames)) :
|
||||
((moduleNames, containingFile, reusedNames) => resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames));
|
||||
((moduleNames, containingFile, reusedNames, redirectedReference) => host.resolveModuleNames!(moduleNames, containingFile, reusedNames, redirectedReference)) :
|
||||
((moduleNames, containingFile, reusedNames, redirectedReference) => resolutionCache.resolveModuleNames(moduleNames, containingFile, reusedNames, redirectedReference));
|
||||
compilerHost.resolveTypeReferenceDirectives = host.resolveTypeReferenceDirectives ?
|
||||
((typeDirectiveNames, containingFile) => host.resolveTypeReferenceDirectives!(typeDirectiveNames, containingFile)) :
|
||||
((typeDirectiveNames, containingFile) => resolutionCache.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile));
|
||||
((typeDirectiveNames, containingFile, redirectedReference) => host.resolveTypeReferenceDirectives!(typeDirectiveNames, containingFile, redirectedReference)) :
|
||||
((typeDirectiveNames, containingFile, redirectedReference) => resolutionCache.resolveTypeReferenceDirectives(typeDirectiveNames, containingFile, redirectedReference));
|
||||
const userProvidedResolution = !!host.resolveModuleNames || !!host.resolveTypeReferenceDirectives;
|
||||
|
||||
synchronizeProgram();
|
||||
@@ -764,8 +780,8 @@ namespace ts {
|
||||
return !hostSourceFile || isFileMissingOnHost(hostSourceFile) ? undefined : hostSourceFile.version.toString();
|
||||
}
|
||||
|
||||
function onReleaseOldSourceFile(oldSourceFile: SourceFile, _oldOptions: CompilerOptions) {
|
||||
const hostSourceFileInfo = sourceFilesCache.get(oldSourceFile.path);
|
||||
function onReleaseOldSourceFile(oldSourceFile: SourceFile, _oldOptions: CompilerOptions, hasSourceFileByPath: boolean) {
|
||||
const hostSourceFileInfo = sourceFilesCache.get(oldSourceFile.resolvedPath);
|
||||
// If this is the source file thats in the cache and new program doesnt need it,
|
||||
// remove the cached entry.
|
||||
// Note we arent deleting entry if file became missing in new program or
|
||||
@@ -779,8 +795,10 @@ namespace ts {
|
||||
if ((hostSourceFileInfo as FilePresentOnHost).fileWatcher) {
|
||||
(hostSourceFileInfo as FilePresentOnHost).fileWatcher.close();
|
||||
}
|
||||
sourceFilesCache.delete(oldSourceFile.path);
|
||||
resolutionCache.removeResolutionsOfFile(oldSourceFile.path);
|
||||
sourceFilesCache.delete(oldSourceFile.resolvedPath);
|
||||
if (!hasSourceFileByPath) {
|
||||
resolutionCache.removeResolutionsOfFile(oldSourceFile.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -875,6 +893,7 @@ namespace ts {
|
||||
if (eventKind === FileWatcherEventKind.Deleted && sourceFilesCache.get(path)) {
|
||||
resolutionCache.invalidateResolutionOfFile(path);
|
||||
}
|
||||
resolutionCache.removeResolutionsFromProjectReferenceRedirects(path);
|
||||
nextSourceFileVersion(path);
|
||||
|
||||
// Update the program
|
||||
@@ -934,6 +953,8 @@ namespace ts {
|
||||
}
|
||||
nextSourceFileVersion(fileOrDirectoryPath);
|
||||
|
||||
if (isPathInNodeModulesStartingWithDot(fileOrDirectoryPath)) return;
|
||||
|
||||
// If the the added or created file or directory is not supported file name, ignore the file
|
||||
// But when watched directory is added/removed, we need to reload the file list
|
||||
if (fileOrDirectoryPath !== directory && hasExtension(fileOrDirectoryPath) && !isSupportedSourceFileName(fileOrDirectory, compilerOptions)) {
|
||||
|
||||
Reference in New Issue
Block a user