mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-23 01:42:07 -06:00
Merge branch 'master' into tsconfig_canonicalpath
This commit is contained in:
commit
e39f679c45
@ -172,6 +172,8 @@ namespace ts {
|
||||
es2018: ScriptTarget.ES2018,
|
||||
esnext: ScriptTarget.ESNext,
|
||||
}),
|
||||
affectsSourceFile: true,
|
||||
affectsModuleResolution: true,
|
||||
paramType: Diagnostics.VERSION,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Basic_Options,
|
||||
@ -190,6 +192,7 @@ namespace ts {
|
||||
es2015: ModuleKind.ES2015,
|
||||
esnext: ModuleKind.ESNext
|
||||
}),
|
||||
affectsModuleResolution: true,
|
||||
paramType: Diagnostics.KIND,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Basic_Options,
|
||||
@ -202,6 +205,7 @@ namespace ts {
|
||||
name: "lib",
|
||||
type: libMap
|
||||
},
|
||||
affectsModuleResolution: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Basic_Options,
|
||||
description: Diagnostics.Specify_library_files_to_be_included_in_the_compilation
|
||||
@ -209,6 +213,7 @@ namespace ts {
|
||||
{
|
||||
name: "allowJs",
|
||||
type: "boolean",
|
||||
affectsModuleResolution: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Basic_Options,
|
||||
description: Diagnostics.Allow_javascript_files_to_be_compiled
|
||||
@ -226,6 +231,7 @@ namespace ts {
|
||||
"react-native": JsxEmit.ReactNative,
|
||||
"react": JsxEmit.React
|
||||
}),
|
||||
affectsSourceFile: true,
|
||||
paramType: Diagnostics.KIND,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Basic_Options,
|
||||
@ -336,6 +342,7 @@ namespace ts {
|
||||
{
|
||||
name: "noImplicitAny",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
@ -344,6 +351,7 @@ namespace ts {
|
||||
{
|
||||
name: "strictNullChecks",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
@ -352,6 +360,7 @@ namespace ts {
|
||||
{
|
||||
name: "strictFunctionTypes",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
@ -360,6 +369,7 @@ namespace ts {
|
||||
{
|
||||
name: "strictPropertyInitialization",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
@ -368,6 +378,7 @@ namespace ts {
|
||||
{
|
||||
name: "noImplicitThis",
|
||||
type: "boolean",
|
||||
affectsSemanticDiagnostics: true,
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
@ -376,6 +387,7 @@ namespace ts {
|
||||
{
|
||||
name: "alwaysStrict",
|
||||
type: "boolean",
|
||||
affectsSourceFile: true,
|
||||
strictFlag: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Strict_Type_Checking_Options,
|
||||
@ -410,6 +422,7 @@ namespace ts {
|
||||
{
|
||||
name: "noFallthroughCasesInSwitch",
|
||||
type: "boolean",
|
||||
affectsBindDiagnostics: true,
|
||||
affectsSemanticDiagnostics: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Additional_Checks,
|
||||
@ -423,6 +436,7 @@ namespace ts {
|
||||
node: ModuleResolutionKind.NodeJs,
|
||||
classic: ModuleResolutionKind.Classic,
|
||||
}),
|
||||
affectsModuleResolution: true,
|
||||
paramType: Diagnostics.STRATEGY,
|
||||
category: Diagnostics.Module_Resolution_Options,
|
||||
description: Diagnostics.Specify_module_resolution_strategy_Colon_node_Node_js_or_classic_TypeScript_pre_1_6,
|
||||
@ -430,6 +444,7 @@ namespace ts {
|
||||
{
|
||||
name: "baseUrl",
|
||||
type: "string",
|
||||
affectsModuleResolution: true,
|
||||
isFilePath: true,
|
||||
category: Diagnostics.Module_Resolution_Options,
|
||||
description: Diagnostics.Base_directory_to_resolve_non_absolute_module_names
|
||||
@ -439,6 +454,7 @@ namespace ts {
|
||||
// use type = object to copy the value as-is
|
||||
name: "paths",
|
||||
type: "object",
|
||||
affectsModuleResolution: true,
|
||||
isTSConfigOnly: true,
|
||||
category: Diagnostics.Module_Resolution_Options,
|
||||
description: Diagnostics.A_series_of_entries_which_re_map_imports_to_lookup_locations_relative_to_the_baseUrl
|
||||
@ -454,6 +470,7 @@ namespace ts {
|
||||
type: "string",
|
||||
isFilePath: true
|
||||
},
|
||||
affectsModuleResolution: true,
|
||||
category: Diagnostics.Module_Resolution_Options,
|
||||
description: Diagnostics.List_of_root_folders_whose_combined_content_represents_the_structure_of_the_project_at_runtime
|
||||
},
|
||||
@ -465,6 +482,7 @@ namespace ts {
|
||||
type: "string",
|
||||
isFilePath: true
|
||||
},
|
||||
affectsModuleResolution: true,
|
||||
category: Diagnostics.Module_Resolution_Options,
|
||||
description: Diagnostics.List_of_folders_to_include_type_definitions_from
|
||||
},
|
||||
@ -475,6 +493,7 @@ namespace ts {
|
||||
name: "types",
|
||||
type: "string"
|
||||
},
|
||||
affectsModuleResolution: true,
|
||||
showInSimplifiedHelpView: true,
|
||||
category: Diagnostics.Module_Resolution_Options,
|
||||
description: Diagnostics.Type_declaration_files_to_be_included_in_compilation
|
||||
@ -633,12 +652,14 @@ namespace ts {
|
||||
{
|
||||
name: "noLib",
|
||||
type: "boolean",
|
||||
affectsModuleResolution: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Do_not_include_the_default_library_file_lib_d_ts
|
||||
},
|
||||
{
|
||||
name: "noResolve",
|
||||
type: "boolean",
|
||||
affectsModuleResolution: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Do_not_add_triple_slash_references_or_imported_modules_to_the_list_of_compiled_files
|
||||
},
|
||||
@ -651,6 +672,7 @@ namespace ts {
|
||||
{
|
||||
name: "disableSizeLimit",
|
||||
type: "boolean",
|
||||
affectsSourceFile: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Disable_size_limitations_on_JavaScript_projects
|
||||
},
|
||||
@ -696,6 +718,7 @@ namespace ts {
|
||||
{
|
||||
name: "allowUnusedLabels",
|
||||
type: "boolean",
|
||||
affectsBindDiagnostics: true,
|
||||
affectsSemanticDiagnostics: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Do_not_report_errors_on_unused_labels
|
||||
@ -703,6 +726,7 @@ namespace ts {
|
||||
{
|
||||
name: "allowUnreachableCode",
|
||||
type: "boolean",
|
||||
affectsBindDiagnostics: true,
|
||||
affectsSemanticDiagnostics: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.Do_not_report_errors_on_unreachable_code
|
||||
@ -730,6 +754,7 @@ namespace ts {
|
||||
{
|
||||
name: "maxNodeModuleJsDepth",
|
||||
type: "number",
|
||||
// TODO: GH#27108 affectsModuleResolution: true,
|
||||
category: Diagnostics.Advanced_Options,
|
||||
description: Diagnostics.The_maximum_dependency_depth_to_search_under_node_modules_and_load_JavaScript_files
|
||||
},
|
||||
@ -759,6 +784,18 @@ namespace ts {
|
||||
}
|
||||
];
|
||||
|
||||
/* @internal */
|
||||
export const semanticDiagnosticsOptionDeclarations: ReadonlyArray<CommandLineOption> =
|
||||
optionDeclarations.filter(option => !!option.affectsSemanticDiagnostics);
|
||||
|
||||
/* @internal */
|
||||
export const moduleResolutionOptionDeclarations: ReadonlyArray<CommandLineOption> =
|
||||
optionDeclarations.filter(option => !!option.affectsModuleResolution);
|
||||
|
||||
/* @internal */
|
||||
export const sourceFileAffectingCompilerOptions: ReadonlyArray<CommandLineOption> = optionDeclarations.filter(option =>
|
||||
!!option.affectsSourceFile || !!option.affectsModuleResolution || !!option.affectsBindDiagnostics);
|
||||
|
||||
/* @internal */
|
||||
export const buildOpts: CommandLineOption[] = [
|
||||
...commonOptionsWithBuild,
|
||||
|
||||
@ -1041,7 +1041,7 @@ namespace ts {
|
||||
// SyntaxKind.TemplateMiddle
|
||||
// SyntaxKind.TemplateTail
|
||||
function emitLiteral(node: LiteralLikeNode) {
|
||||
const text = getLiteralTextOfNode(node);
|
||||
const text = getLiteralTextOfNode(node, printerOptions.neverAsciiEscape);
|
||||
if ((printerOptions.sourceMap || printerOptions.inlineSourceMap)
|
||||
&& (node.kind === SyntaxKind.StringLiteral || isTemplateLiteralKind(node.kind))) {
|
||||
writeLiteral(text);
|
||||
@ -1532,7 +1532,7 @@ namespace ts {
|
||||
expression = skipPartiallyEmittedExpressions(expression);
|
||||
if (isNumericLiteral(expression)) {
|
||||
// check if numeric literal is a decimal literal that was originally written with a dot
|
||||
const text = getLiteralTextOfNode(<LiteralExpression>expression);
|
||||
const text = getLiteralTextOfNode(<LiteralExpression>expression, /*neverAsciiEscape*/ true);
|
||||
return !expression.numericLiteralFlags
|
||||
&& !stringContains(text, tokenToString(SyntaxKind.DotToken)!);
|
||||
}
|
||||
@ -3306,20 +3306,20 @@ namespace ts {
|
||||
return getSourceTextOfNodeFromSourceFile(currentSourceFile, node, includeTrivia);
|
||||
}
|
||||
|
||||
function getLiteralTextOfNode(node: LiteralLikeNode): string {
|
||||
function getLiteralTextOfNode(node: LiteralLikeNode, neverAsciiEscape: boolean | undefined): string {
|
||||
if (node.kind === SyntaxKind.StringLiteral && (<StringLiteral>node).textSourceNode) {
|
||||
const textSourceNode = (<StringLiteral>node).textSourceNode!;
|
||||
if (isIdentifier(textSourceNode)) {
|
||||
return getEmitFlags(node) & EmitFlags.NoAsciiEscaping ?
|
||||
return neverAsciiEscape || (getEmitFlags(node) & EmitFlags.NoAsciiEscaping) ?
|
||||
`"${escapeString(getTextOfNode(textSourceNode))}"` :
|
||||
`"${escapeNonAsciiString(getTextOfNode(textSourceNode))}"`;
|
||||
}
|
||||
else {
|
||||
return getLiteralTextOfNode(textSourceNode);
|
||||
return getLiteralTextOfNode(textSourceNode, neverAsciiEscape);
|
||||
}
|
||||
}
|
||||
|
||||
return getLiteralText(node, currentSourceFile);
|
||||
return getLiteralText(node, currentSourceFile, neverAsciiEscape);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -496,23 +496,15 @@ namespace ts {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determined if source file needs to be re-created even if its text hasn't changed
|
||||
* Determine if source file needs to be re-created even if its text hasn't changed
|
||||
*/
|
||||
function shouldProgramCreateNewSourceFiles(program: Program | undefined, newOptions: CompilerOptions) {
|
||||
// If any of these options change, we can't reuse old source file even if version match
|
||||
// The change in options like these could result in change in syntax tree change
|
||||
const oldOptions = program && program.getCompilerOptions();
|
||||
return oldOptions && (
|
||||
oldOptions.target !== newOptions.target ||
|
||||
oldOptions.module !== newOptions.module ||
|
||||
oldOptions.moduleResolution !== newOptions.moduleResolution ||
|
||||
oldOptions.noResolve !== newOptions.noResolve ||
|
||||
oldOptions.jsx !== newOptions.jsx ||
|
||||
oldOptions.allowJs !== newOptions.allowJs ||
|
||||
oldOptions.disableSizeLimit !== newOptions.disableSizeLimit ||
|
||||
oldOptions.baseUrl !== newOptions.baseUrl ||
|
||||
!equalOwnProperties(oldOptions.paths, newOptions.paths)
|
||||
);
|
||||
function shouldProgramCreateNewSourceFiles(program: Program | undefined, newOptions: CompilerOptions): boolean {
|
||||
if (!program) return false;
|
||||
// If any compiler options change, we can't reuse old source file even if version match
|
||||
// The change in options like these could result in change in syntax tree or `sourceFile.bindDiagnostics`.
|
||||
const oldOptions = program.getCompilerOptions();
|
||||
return !!sourceFileAffectingCompilerOptions.some(option =>
|
||||
!isJsonEqual(getCompilerOptionValue(oldOptions, option), getCompilerOptionValue(newOptions, option)));
|
||||
}
|
||||
|
||||
function createCreateProgramOptions(rootNames: ReadonlyArray<string>, options: CompilerOptions, host?: CompilerHost, oldProgram?: Program, configFileParsingDiagnostics?: ReadonlyArray<Diagnostic>): CreateProgramOptions {
|
||||
|
||||
@ -4569,6 +4569,9 @@ namespace ts {
|
||||
showInSimplifiedHelpView?: boolean;
|
||||
category?: DiagnosticMessage;
|
||||
strictFlag?: true; // true if the option is one of the flag under strict
|
||||
affectsSourceFile?: true; // true if we should recreate SourceFiles after this option changes
|
||||
affectsModuleResolution?: true; // currently same effect as `affectsSourceFile`
|
||||
affectsBindDiagnostics?: true; // true if this affects binding (currently same effect as `affectsSourceFile`)
|
||||
affectsSemanticDiagnostics?: true; // true if option affects semantic diagnostics
|
||||
}
|
||||
|
||||
@ -4964,7 +4967,7 @@ namespace ts {
|
||||
/* @internal */
|
||||
export interface EmitNode {
|
||||
annotatedNodes?: Node[]; // Tracks Parse-tree nodes with EmitNodes for eventual cleanup.
|
||||
flags: EmitFlags; // Flags that customize emit
|
||||
flags: EmitFlags; // Flags that customize emit
|
||||
leadingComments?: SynthesizedComment[]; // Synthesized leading comments
|
||||
trailingComments?: SynthesizedComment[]; // Synthesized trailing comments
|
||||
commentRange?: TextRange; // The text range to use when emitting leading or trailing comments
|
||||
@ -5324,6 +5327,7 @@ namespace ts {
|
||||
/*@internal*/ inlineSourceMap?: boolean;
|
||||
/*@internal*/ extendedDiagnostics?: boolean;
|
||||
/*@internal*/ onlyPrintJsDocStyle?: boolean;
|
||||
/*@internal*/ neverAsciiEscape?: boolean;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
|
||||
@ -101,22 +101,8 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function changesAffectModuleResolution(oldOptions: CompilerOptions, newOptions: CompilerOptions): boolean {
|
||||
return !oldOptions ||
|
||||
(oldOptions.module !== newOptions.module) ||
|
||||
(oldOptions.moduleResolution !== newOptions.moduleResolution) ||
|
||||
(oldOptions.noResolve !== newOptions.noResolve) ||
|
||||
(oldOptions.target !== newOptions.target) ||
|
||||
(oldOptions.noLib !== newOptions.noLib) ||
|
||||
(oldOptions.jsx !== newOptions.jsx) ||
|
||||
(oldOptions.allowJs !== newOptions.allowJs) ||
|
||||
(oldOptions.rootDir !== newOptions.rootDir) ||
|
||||
(oldOptions.configFilePath !== newOptions.configFilePath) ||
|
||||
(oldOptions.baseUrl !== newOptions.baseUrl) ||
|
||||
(oldOptions.maxNodeModuleJsDepth !== newOptions.maxNodeModuleJsDepth) ||
|
||||
!arrayIsEqualTo(oldOptions.lib, newOptions.lib) ||
|
||||
!arrayIsEqualTo(oldOptions.typeRoots, newOptions.typeRoots) ||
|
||||
!arrayIsEqualTo(oldOptions.rootDirs, newOptions.rootDirs) ||
|
||||
!equalOwnProperties(oldOptions.paths, newOptions.paths);
|
||||
return oldOptions.configFilePath !== newOptions.configFilePath || moduleResolutionOptionDeclarations.some(o =>
|
||||
!isJsonEqual(getCompilerOptionValue(oldOptions, o), getCompilerOptionValue(newOptions, o)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -538,14 +524,14 @@ namespace ts {
|
||||
return emitNode && emitNode.flags || 0;
|
||||
}
|
||||
|
||||
export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile) {
|
||||
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)) {
|
||||
return getSourceTextOfNodeFromSourceFile(sourceFile, node);
|
||||
}
|
||||
|
||||
const escapeText = getEmitFlags(node) & EmitFlags.NoAsciiEscaping ? escapeString : escapeNonAsciiString;
|
||||
const escapeText = neverAsciiEscape || (getEmitFlags(node) & EmitFlags.NoAsciiEscaping) ? escapeString : escapeNonAsciiString;
|
||||
|
||||
// If we can't reach the original source text, use the canonical form if it's a number,
|
||||
// or a (possibly escaped) quoted form of the original text if it's string-like.
|
||||
@ -7106,13 +7092,13 @@ namespace ts {
|
||||
return compilerOptions[flag] === undefined ? !!compilerOptions.strict : !!compilerOptions[flag];
|
||||
}
|
||||
|
||||
export function compilerOptionsAffectSemanticDiagnostics(newOptions: CompilerOptions, oldOptions: CompilerOptions) {
|
||||
if (oldOptions === newOptions) {
|
||||
return false;
|
||||
}
|
||||
export function compilerOptionsAffectSemanticDiagnostics(newOptions: CompilerOptions, oldOptions: CompilerOptions): boolean {
|
||||
return oldOptions !== newOptions &&
|
||||
semanticDiagnosticsOptionDeclarations.some(option => !isJsonEqual(getCompilerOptionValue(oldOptions, option), getCompilerOptionValue(newOptions, option)));
|
||||
}
|
||||
|
||||
return optionDeclarations.some(option => (!!option.strictFlag && getStrictOptionValue(newOptions, option.name as StrictOptionName) !== getStrictOptionValue(oldOptions, option.name as StrictOptionName)) ||
|
||||
(!!option.affectsSemanticDiagnostics && !newOptions[option.name] !== !oldOptions[option.name]));
|
||||
export function getCompilerOptionValue(options: CompilerOptions, option: CommandLineOption): unknown {
|
||||
return option.strictFlag ? getStrictOptionValue(options, option.name as StrictOptionName) : options[option.name];
|
||||
}
|
||||
|
||||
export function hasZeroOrOneAsteriskCharacter(str: string): boolean {
|
||||
@ -8380,4 +8366,8 @@ namespace ts {
|
||||
// '/// <reference no-default-lib="true"/>' directive.
|
||||
return options.skipLibCheck && sourceFile.isDeclarationFile || options.skipDefaultLibCheck && sourceFile.hasNoDefaultLib;
|
||||
}
|
||||
|
||||
export function isJsonEqual(a: unknown, b: unknown): boolean {
|
||||
return a === b || typeof a === "object" && a !== null && typeof b === "object" && b !== null && equalOwnProperties(a as MapLike<unknown>, b as MapLike<unknown>, isJsonEqual);
|
||||
}
|
||||
}
|
||||
|
||||
@ -654,7 +654,7 @@ interface Array<T> {}`
|
||||
invokeWatcherCallbacks(this.watchedDirectoriesRecursive.get(this.toPath(folderFullPath))!, cb => this.directoryCallback(cb, relativePath));
|
||||
}
|
||||
|
||||
invokeFileWatcher(fileFullPath: string, eventKind: FileWatcherEventKind, useFileNameInCallback?: boolean) {
|
||||
private invokeFileWatcher(fileFullPath: string, eventKind: FileWatcherEventKind, useFileNameInCallback?: boolean) {
|
||||
invokeWatcherCallbacks(this.watchedFiles.get(this.toPath(fileFullPath))!, ({ cb, fileName }) => cb(useFileNameInCallback ? fileName : fileFullPath, eventKind));
|
||||
}
|
||||
|
||||
|
||||
@ -121,10 +121,6 @@ namespace ts {
|
||||
const buckets = createMap<Map<DocumentRegistryEntry>>();
|
||||
const getCanonicalFileName = createGetCanonicalFileName(!!useCaseSensitiveFileNames);
|
||||
|
||||
function getKeyForCompilationSettings(settings: CompilerOptions): DocumentRegistryBucketKey {
|
||||
return <DocumentRegistryBucketKey>`_${settings.target}|${settings.module}|${settings.noResolve}|${settings.jsx}|${settings.allowJs}|${settings.baseUrl}|${JSON.stringify(settings.typeRoots)}|${JSON.stringify(settings.rootDirs)}|${JSON.stringify(settings.paths)}`;
|
||||
}
|
||||
|
||||
function getBucketForCompilationSettings(key: DocumentRegistryBucketKey, createIfMissing: boolean): Map<DocumentRegistryEntry> {
|
||||
let bucket = buckets.get(key);
|
||||
if (!bucket && createIfMissing) {
|
||||
@ -273,4 +269,8 @@ namespace ts {
|
||||
getKeyForCompilationSettings
|
||||
};
|
||||
}
|
||||
|
||||
function getKeyForCompilationSettings(settings: CompilerOptions): DocumentRegistryBucketKey {
|
||||
return sourceFileAffectingCompilerOptions.map(option => getCompilerOptionValue(settings, option)).join("|") as DocumentRegistryBucketKey;
|
||||
}
|
||||
}
|
||||
|
||||
@ -781,7 +781,7 @@ namespace ts.textChanges {
|
||||
function getNonformattedText(node: Node, sourceFile: SourceFile | undefined, newLineCharacter: string): { text: string, node: Node } {
|
||||
const writer = new Writer(newLineCharacter);
|
||||
const newLine = newLineCharacter === "\n" ? NewLineKind.LineFeed : NewLineKind.CarriageReturnLineFeed;
|
||||
createPrinter({ newLine }, writer).writeNode(EmitHint.Unspecified, node, sourceFile, writer);
|
||||
createPrinter({ newLine, neverAsciiEscape: true }, writer).writeNode(EmitHint.Unspecified, node, sourceFile, writer);
|
||||
return { text: writer.getText(), node: assignPositionsToNode(node) };
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,10 +305,10 @@ namespace ts {
|
||||
assert.equal(program1.structureIsReused, StructureIsReused.Not);
|
||||
});
|
||||
|
||||
it("fails if rootdir changes", () => {
|
||||
it("succeeds if rootdir changes", () => {
|
||||
const program1 = newProgram(files, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/b" });
|
||||
updateProgram(program1, ["a.ts"], { target, module: ModuleKind.CommonJS, rootDir: "/a/c" }, noop);
|
||||
assert.equal(program1.structureIsReused, StructureIsReused.Not);
|
||||
assert.equal(program1.structureIsReused, StructureIsReused.Completely);
|
||||
});
|
||||
|
||||
it("fails if config path changes", () => {
|
||||
|
||||
@ -443,6 +443,33 @@ namespace ts.tscWatch {
|
||||
checkOutputErrorsIncremental(host, emptyArray);
|
||||
});
|
||||
|
||||
it("Updates diagnostics when '--noUnusedLabels' changes", () => {
|
||||
const aTs: File = { path: "/a.ts", content: "label: while (1) {}" };
|
||||
const files = [libFile, aTs];
|
||||
const paths = files.map(f => f.path);
|
||||
const options = (allowUnusedLabels: boolean) => `{ "compilerOptions": { "allowUnusedLabels": ${allowUnusedLabels} } }`;
|
||||
const tsconfig: File = { path: "/tsconfig.json", content: options(/*allowUnusedLabels*/ true) };
|
||||
|
||||
const host = createWatchedSystem([...files, tsconfig]);
|
||||
const watch = createWatchOfConfigFile(tsconfig.path, host);
|
||||
|
||||
checkProgramActualFiles(watch(), paths);
|
||||
checkOutputErrorsInitial(host, emptyArray);
|
||||
|
||||
host.modifyFile(tsconfig.path, options(/*allowUnusedLabels*/ false));
|
||||
host.checkTimeoutQueueLengthAndRun(1); // reload the configured project
|
||||
|
||||
checkProgramActualFiles(watch(), paths);
|
||||
checkOutputErrorsIncremental(host, [
|
||||
getDiagnosticOfFileFromProgram(watch(), aTs.path, 0, "label".length, Diagnostics.Unused_label),
|
||||
]);
|
||||
|
||||
host.modifyFile(tsconfig.path, options(/*allowUnusedLabels*/ true));
|
||||
host.checkTimeoutQueueLengthAndRun(1); // reload the configured project
|
||||
checkProgramActualFiles(watch(), paths);
|
||||
checkOutputErrorsIncremental(host, emptyArray);
|
||||
});
|
||||
|
||||
it("files explicitly excluded in config file", () => {
|
||||
const configFile: File = {
|
||||
path: "/a/b/tsconfig.json",
|
||||
@ -1190,7 +1217,7 @@ namespace ts.tscWatch {
|
||||
host.reloadFS(files);
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkProgramActualFiles(watch(), files.map(file => file.path));
|
||||
checkOutputErrorsIncremental(host, []);
|
||||
checkOutputErrorsIncremental(host, emptyArray);
|
||||
});
|
||||
|
||||
it("watched files when file is deleted and new file is added as part of change", () => {
|
||||
@ -1322,12 +1349,10 @@ export class B
|
||||
path: `${currentDirectory}/a.ts`,
|
||||
content: `declare function foo(): null | { hello: any };
|
||||
foo().hello`
|
||||
};
|
||||
const compilerOptions: CompilerOptions = {
|
||||
};
|
||||
const config: File = {
|
||||
path: `${currentDirectory}/tsconfig.json`,
|
||||
content: JSON.stringify({ compilerOptions })
|
||||
content: JSON.stringify({ compilerOptions: {} })
|
||||
};
|
||||
const files = [aFile, config, libFile];
|
||||
const host = createWatchedSystem(files, { currentDirectory });
|
||||
@ -1335,8 +1360,7 @@ foo().hello`
|
||||
checkProgramActualFiles(watch(), [aFile.path, libFile.path]);
|
||||
checkOutputErrorsInitial(host, emptyArray);
|
||||
const modifiedTimeOfAJs = host.getModifiedTime(`${currentDirectory}/a.js`);
|
||||
compilerOptions.strictNullChecks = true;
|
||||
host.writeFile(config.path, JSON.stringify({ compilerOptions }));
|
||||
host.writeFile(config.path, JSON.stringify({ compilerOptions: { strictNullChecks: true } }));
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
const expectedStrictNullErrors = [
|
||||
getDiagnosticOfFileFromProgram(watch(), aFile.path, aFile.content.lastIndexOf("foo()"), 5, Diagnostics.Object_is_possibly_null)
|
||||
@ -1344,15 +1368,12 @@ foo().hello`
|
||||
checkOutputErrorsIncremental(host, expectedStrictNullErrors);
|
||||
// File a need not be rewritten
|
||||
assert.equal(host.getModifiedTime(`${currentDirectory}/a.js`), modifiedTimeOfAJs);
|
||||
compilerOptions.strict = true;
|
||||
delete (compilerOptions.strictNullChecks);
|
||||
host.writeFile(config.path, JSON.stringify({ compilerOptions }));
|
||||
host.writeFile(config.path, JSON.stringify({ compilerOptions: { strict: true, alwaysStrict: false } })); // Avoid changing 'alwaysStrict' or must re-bind
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkOutputErrorsIncremental(host, expectedStrictNullErrors);
|
||||
// File a need not be rewritten
|
||||
assert.equal(host.getModifiedTime(`${currentDirectory}/a.js`), modifiedTimeOfAJs);
|
||||
delete (compilerOptions.strict);
|
||||
host.writeFile(config.path, JSON.stringify({ compilerOptions }));
|
||||
host.writeFile(config.path, JSON.stringify({ compilerOptions: {} }));
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
checkOutputErrorsIncremental(host, emptyArray);
|
||||
// File a need not be rewritten
|
||||
|
||||
@ -10217,6 +10217,35 @@ declare class TestLib {
|
||||
});
|
||||
});
|
||||
|
||||
describe("tsserverProjectSystem config file change", () => {
|
||||
it("Updates diagnostics when '--noUnusedLabels' changes", () => {
|
||||
const aTs: File = { path: "/a.ts", content: "label: while (1) {}" };
|
||||
const options = (allowUnusedLabels: boolean) => `{ "compilerOptions": { "allowUnusedLabels": ${allowUnusedLabels} } }`;
|
||||
const tsconfig: File = { path: "/tsconfig.json", content: options(/*allowUnusedLabels*/ true) };
|
||||
|
||||
const host = createServerHost([aTs, tsconfig]);
|
||||
const session = createSession(host);
|
||||
openFilesForSession([aTs], session);
|
||||
|
||||
host.modifyFile(tsconfig.path, options(/*allowUnusedLabels*/ false));
|
||||
host.runQueuedTimeoutCallbacks();
|
||||
|
||||
const response = executeSessionRequest<protocol.SemanticDiagnosticsSyncRequest, protocol.SemanticDiagnosticsSyncResponse>(session, protocol.CommandTypes.SemanticDiagnosticsSync, { file: aTs.path }) as protocol.Diagnostic[] | undefined;
|
||||
assert.deepEqual<protocol.Diagnostic[] | undefined>(response, [
|
||||
{
|
||||
start: { line: 1, offset: 1 },
|
||||
end: { line: 1, offset: 1 + "label".length },
|
||||
text: "Unused label.",
|
||||
category: "error",
|
||||
code: Diagnostics.Unused_label.code,
|
||||
relatedInformation: undefined,
|
||||
reportsUnnecessary: true,
|
||||
source: undefined,
|
||||
},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
function makeReferenceItem(file: File, isDefinition: boolean, text: string, lineText: string, options?: SpanFromSubstringOptions): protocol.ReferencesResponseItem {
|
||||
return {
|
||||
...protocolFileSpanFromSubstring(file, text, options),
|
||||
|
||||
@ -2,12 +2,12 @@
|
||||
|
||||
//// [|f1/*0*/();|]
|
||||
|
||||
// @Filename: module.ts
|
||||
// @Filename: jalapeño.ts
|
||||
//// export function f1() {}
|
||||
//// export var v1 = 5;
|
||||
|
||||
verify.importFixAtPosition([
|
||||
`import { f1 } from "./module";
|
||||
`import { f1 } from "./jalapeño";
|
||||
|
||||
f1();`
|
||||
]);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user