Merge branch 'main' into fix44572

This commit is contained in:
Anders Hejlsberg
2021-08-29 16:57:31 -07:00
53 changed files with 792 additions and 463 deletions
+32 -15
View File
@@ -8402,12 +8402,12 @@ namespace ts {
}
function isNullOrUndefined(node: Expression) {
const expr = skipParentheses(node);
const expr = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true);
return expr.kind === SyntaxKind.NullKeyword || expr.kind === SyntaxKind.Identifier && getResolvedSymbol(expr as Identifier) === undefinedSymbol;
}
function isEmptyArrayLiteral(node: Expression) {
const expr = skipParentheses(node);
const expr = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true);
return expr.kind === SyntaxKind.ArrayLiteralExpression && (expr as ArrayLiteralExpression).elements.length === 0;
}
@@ -11800,7 +11800,7 @@ namespace ts {
// Flags we want to propagate to the result if they exist in all source symbols
let optionalFlag = isUnion ? SymbolFlags.None : SymbolFlags.Optional;
let syntheticFlag = CheckFlags.SyntheticMethod;
let checkFlags = 0;
let checkFlags = isUnion ? 0 : CheckFlags.Readonly;
let mergedInstantiations = false;
for (const current of containingType.types) {
const type = getApparentType(current);
@@ -11839,8 +11839,13 @@ namespace ts {
}
}
}
checkFlags |= (isReadonlySymbol(prop) ? CheckFlags.Readonly : 0) |
(!(modifiers & ModifierFlags.NonPublicAccessibilityModifier) ? CheckFlags.ContainsPublic : 0) |
if (isUnion && isReadonlySymbol(prop)) {
checkFlags |= CheckFlags.Readonly;
}
else if (!isUnion && !isReadonlySymbol(prop)) {
checkFlags &= ~CheckFlags.Readonly;
}
checkFlags |= (!(modifiers & ModifierFlags.NonPublicAccessibilityModifier) ? CheckFlags.ContainsPublic : 0) |
(modifiers & ModifierFlags.Protected ? CheckFlags.ContainsProtected : 0) |
(modifiers & ModifierFlags.Private ? CheckFlags.ContainsPrivate : 0) |
(modifiers & ModifierFlags.Static ? CheckFlags.ContainsStatic : 0);
@@ -22966,7 +22971,7 @@ namespace ts {
}
function isFalseExpression(expr: Expression): boolean {
const node = skipParentheses(expr);
const node = skipParentheses(expr, /*excludeJSDocTypeAssertions*/ true);
return node.kind === SyntaxKind.FalseKeyword || node.kind === SyntaxKind.BinaryExpression && (
(node as BinaryExpression).operatorToken.kind === SyntaxKind.AmpersandAmpersandToken && (isFalseExpression((node as BinaryExpression).left) || isFalseExpression((node as BinaryExpression).right)) ||
(node as BinaryExpression).operatorToken.kind === SyntaxKind.BarBarToken && isFalseExpression((node as BinaryExpression).left) && isFalseExpression((node as BinaryExpression).right));
@@ -23288,7 +23293,7 @@ namespace ts {
}
function narrowTypeByAssertion(type: Type, expr: Expression): Type {
const node = skipParentheses(expr);
const node = skipParentheses(expr, /*excludeJSDocTypeAssertions*/ true);
if (node.kind === SyntaxKind.FalseKeyword) {
return unreachableNeverType;
}
@@ -25872,7 +25877,9 @@ namespace ts {
case SyntaxKind.ParenthesizedExpression: {
// Like in `checkParenthesizedExpression`, an `/** @type {xyz} */` comment before a parenthesized expression acts as a type cast.
const tag = isInJSFile(parent) ? getJSDocTypeTag(parent) : undefined;
return tag ? getTypeFromTypeNode(tag.typeExpression.type) : getContextualType(parent as ParenthesizedExpression, contextFlags);
return !tag ? getContextualType(parent as ParenthesizedExpression, contextFlags) :
isJSDocTypeTag(tag) && isConstTypeReference(tag.typeExpression.type) ? tryFindWhenConstTypeReference(parent as ParenthesizedExpression) :
getTypeFromTypeNode(tag.typeExpression.type);
}
case SyntaxKind.NonNullExpression:
return getContextualType(parent as NonNullExpression, contextFlags);
@@ -32855,8 +32862,10 @@ namespace ts {
}
function isTypeAssertion(node: Expression) {
node = skipParentheses(node);
return node.kind === SyntaxKind.TypeAssertionExpression || node.kind === SyntaxKind.AsExpression;
node = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true);
return node.kind === SyntaxKind.TypeAssertionExpression ||
node.kind === SyntaxKind.AsExpression ||
isJSDocTypeAssertion(node);
}
function checkDeclarationInitializer(declaration: HasExpressionInitializer, contextualType?: Type | undefined) {
@@ -32931,6 +32940,7 @@ namespace ts {
function isConstContext(node: Expression): boolean {
const parent = node.parent;
return isAssertionExpression(parent) && isConstTypeReference(parent.type) ||
isJSDocTypeAssertion(parent) && isConstTypeReference(getJSDocTypeAssertionType(parent)) ||
(isParenthesizedExpression(parent) || isArrayLiteralExpression(parent) || isSpreadElement(parent)) && isConstContext(parent) ||
(isPropertyAssignment(parent) || isShorthandPropertyAssignment(parent) || isTemplateSpan(parent)) && isConstContext(parent.parent);
}
@@ -33143,7 +33153,14 @@ namespace ts {
}
function getQuickTypeOfExpression(node: Expression) {
const expr = skipParentheses(node);
let expr = skipParentheses(node, /*excludeJSDocTypeAssertions*/ true);
if (isJSDocTypeAssertion(expr)) {
const type = getJSDocTypeAssertionType(expr);
if (!isConstTypeReference(type)) {
return getTypeFromTypeNode(type);
}
}
expr = skipParentheses(node);
// Optimize for the common case of a call to a function with a single non-generic call
// signature where we can just fetch the return type without checking the arguments.
if (isCallExpression(expr) && expr.expression.kind !== SyntaxKind.SuperKeyword && !isRequireCall(expr, /*checkArgumentIsStringLiteralLike*/ true) && !isSymbolOrSymbolForCall(expr)) {
@@ -33230,9 +33247,9 @@ namespace ts {
}
function checkParenthesizedExpression(node: ParenthesizedExpression, checkMode?: CheckMode): Type {
const tag = isInJSFile(node) ? getJSDocTypeTag(node) : undefined;
if (tag) {
return checkAssertionWorker(tag.typeExpression.type, tag.typeExpression.type, node.expression, checkMode);
if (isJSDocTypeAssertion(node)) {
const type = getJSDocTypeAssertionType(node);
return checkAssertionWorker(type, type, node.expression, checkMode);
}
return checkExpression(node.expression, checkMode);
}
@@ -36182,7 +36199,7 @@ namespace ts {
if (getFalsyFlags(type)) return;
const location = isBinaryExpression(condExpr) ? condExpr.right : condExpr;
if (isPropertyAccessExpression(location) && isAssertionExpression(skipParentheses(location.expression))) {
if (isPropertyAccessExpression(location) && isTypeAssertion(location.expression)) {
return;
}
+15
View File
@@ -416,9 +416,24 @@ namespace ts {
node.kind === SyntaxKind.CommaListExpression;
}
export function isJSDocTypeAssertion(node: Node): node is JSDocTypeAssertion {
return isParenthesizedExpression(node)
&& isInJSFile(node)
&& !!getJSDocTypeTag(node);
}
export function getJSDocTypeAssertionType(node: JSDocTypeAssertion) {
const type = getJSDocType(node);
Debug.assertIsDefined(type);
return type;
}
export function isOuterExpression(node: Node, kinds = OuterExpressionKinds.All): node is OuterExpression {
switch (node.kind) {
case SyntaxKind.ParenthesizedExpression:
if (kinds & OuterExpressionKinds.ExcludeJSDocTypeAssertion && isJSDocTypeAssertion(node)) {
return false;
}
return (kinds & OuterExpressionKinds.Parentheses) !== 0;
case SyntaxKind.TypeAssertionExpression:
case SyntaxKind.AsExpression:
+9 -5
View File
@@ -280,6 +280,11 @@ namespace ts {
}
const nodeModulesAtTypes = combinePaths("node_modules", "@types");
function arePathsEqual(path1: string, path2: string, host: ModuleResolutionHost): boolean {
const useCaseSensitiveFileNames = typeof host.useCaseSensitiveFileNames === "function" ? host.useCaseSensitiveFileNames() : host.useCaseSensitiveFileNames;
return comparePaths(path1, path2, !useCaseSensitiveFileNames) === Comparison.EqualTo;
}
/**
* @param {string | undefined} containingFile - file that contains type reference directive, can be undefined if containing file is unknown.
* This is possible in case if resolution is performed for directives specified via 'types' parameter. In this case initial path for secondary lookups
@@ -343,7 +348,7 @@ namespace ts {
resolvedTypeReferenceDirective = {
primary,
resolvedFileName,
originalPath: fileName === resolvedFileName ? undefined : fileName,
originalPath: arePathsEqual(fileName, resolvedFileName, host) ? undefined : fileName,
packageId,
isExternalLibraryImport: pathContainsNodeModules(fileName),
};
@@ -1078,9 +1083,8 @@ namespace ts {
}
/* @internal */
export function tryResolveJSModule(moduleName: string, initialDir: string, host: ModuleResolutionHost): string | undefined {
const { resolvedModule } = tryResolveJSModuleWorker(moduleName, initialDir, host);
return resolvedModule && resolvedModule.resolvedFileName;
export function tryResolveJSModule(moduleName: string, initialDir: string, host: ModuleResolutionHost) {
return tryResolveJSModuleWorker(moduleName, initialDir, host).resolvedModule;
}
const jsOnlyExtensions = [Extensions.JavaScript];
@@ -1123,7 +1127,7 @@ namespace ts {
let resolvedValue = resolved.value;
if (!compilerOptions.preserveSymlinks && resolvedValue && !resolvedValue.originalPath) {
const path = realPath(resolvedValue.path, host, traceEnabled);
const originalPath = path === resolvedValue.path ? undefined : resolvedValue.path;
const originalPath = arePathsEqual(path, resolvedValue.path, host) ? undefined : resolvedValue.path;
resolvedValue = { ...resolvedValue, path, originalPath };
}
// For node_modules lookups, get the real path so that multiple accesses to an `npm link`-ed module do not create duplicate files.
+20 -22
View File
@@ -1163,7 +1163,7 @@ namespace ts {
// The originalFileName could not be actual source file name if file found was d.ts from referecned project
// So in this case try to look up if this is output from referenced project, if it is use the redirected project in that case
const resultFromDts = getRedirectReferenceForResolutionFromSourceOfProject(file.originalFileName, file.path);
const resultFromDts = getRedirectReferenceForResolutionFromSourceOfProject(file.path);
if (resultFromDts) return resultFromDts;
// If preserveSymlinks is true, module resolution wont jump the symlink
@@ -1171,13 +1171,12 @@ namespace ts {
// Note:: Currently we try the real path only if the
// file is from node_modules to avoid having to run real path on all file paths
if (!host.realpath || !options.preserveSymlinks || !stringContains(file.originalFileName, nodeModulesPathPart)) return undefined;
const realDeclarationFileName = host.realpath(file.originalFileName);
const realDeclarationPath = toPath(realDeclarationFileName);
return realDeclarationPath === file.path ? undefined : getRedirectReferenceForResolutionFromSourceOfProject(realDeclarationFileName, realDeclarationPath);
const realDeclarationPath = toPath(host.realpath(file.originalFileName));
return realDeclarationPath === file.path ? undefined : getRedirectReferenceForResolutionFromSourceOfProject(realDeclarationPath);
}
function getRedirectReferenceForResolutionFromSourceOfProject(fileName: string, filePath: Path) {
const source = getSourceOfProjectReferenceRedirect(fileName);
function getRedirectReferenceForResolutionFromSourceOfProject(filePath: Path) {
const source = getSourceOfProjectReferenceRedirect(filePath);
if (isString(source)) return getResolvedProjectReferenceToRedirect(source);
if (!source) return undefined;
// Output of .d.ts file so return resolved ref that matches the out file name
@@ -2472,7 +2471,7 @@ namespace ts {
function processSourceFile(fileName: string, isDefaultLib: boolean, ignoreNoDefaultLib: boolean, packageId: PackageId | undefined, reason: FileIncludeReason): void {
getSourceFileFromReferenceWorker(
fileName,
fileName => findSourceFile(fileName, toPath(fileName), isDefaultLib, ignoreNoDefaultLib, reason, packageId), // TODO: GH#18217
fileName => findSourceFile(fileName, isDefaultLib, ignoreNoDefaultLib, reason, packageId), // TODO: GH#18217
(diagnostic, ...args) => addFilePreprocessingFileExplainingDiagnostic(/*file*/ undefined, reason, diagnostic, args),
reason
);
@@ -2514,20 +2513,21 @@ namespace ts {
}
// Get source file from normalized fileName
function findSourceFile(fileName: string, path: Path, isDefaultLib: boolean, ignoreNoDefaultLib: boolean, reason: FileIncludeReason, packageId: PackageId | undefined): SourceFile | undefined {
function findSourceFile(fileName: string, isDefaultLib: boolean, ignoreNoDefaultLib: boolean, reason: FileIncludeReason, packageId: PackageId | undefined): SourceFile | undefined {
tracing?.push(tracing.Phase.Program, "findSourceFile", {
fileName,
isDefaultLib: isDefaultLib || undefined,
fileIncludeKind: (FileIncludeKind as any)[reason.kind],
});
const result = findSourceFileWorker(fileName, path, isDefaultLib, ignoreNoDefaultLib, reason, packageId);
const result = findSourceFileWorker(fileName, isDefaultLib, ignoreNoDefaultLib, reason, packageId);
tracing?.pop();
return result;
}
function findSourceFileWorker(fileName: string, path: Path, isDefaultLib: boolean, ignoreNoDefaultLib: boolean, reason: FileIncludeReason, packageId: PackageId | undefined): SourceFile | undefined {
function findSourceFileWorker(fileName: string, isDefaultLib: boolean, ignoreNoDefaultLib: boolean, reason: FileIncludeReason, packageId: PackageId | undefined): SourceFile | undefined {
const path = toPath(fileName);
if (useSourceOfProjectReferenceRedirect) {
let source = getSourceOfProjectReferenceRedirect(fileName);
let source = getSourceOfProjectReferenceRedirect(path);
// If preserveSymlinks is true, module resolution wont jump the symlink
// but the resolved real path may be the .d.ts from project reference
// Note:: Currently we try the real path only if the
@@ -2537,12 +2537,12 @@ namespace ts {
options.preserveSymlinks &&
isDeclarationFileName(fileName) &&
stringContains(fileName, nodeModulesPathPart)) {
const realPath = host.realpath(fileName);
if (realPath !== fileName) source = getSourceOfProjectReferenceRedirect(realPath);
const realPath = toPath(host.realpath(fileName));
if (realPath !== path) source = getSourceOfProjectReferenceRedirect(realPath);
}
if (source) {
const file = isString(source) ?
findSourceFile(source, toPath(source), isDefaultLib, ignoreNoDefaultLib, reason, packageId) :
findSourceFile(source, isDefaultLib, ignoreNoDefaultLib, reason, packageId) :
undefined;
if (file) addFileToFilesByName(file, path, /*redirectedPath*/ undefined);
return file;
@@ -2750,8 +2750,8 @@ namespace ts {
return ts.forEachResolvedProjectReference(resolvedProjectReferences, cb);
}
function getSourceOfProjectReferenceRedirect(file: string) {
if (!isDeclarationFileName(file)) return undefined;
function getSourceOfProjectReferenceRedirect(path: Path) {
if (!isDeclarationFileName(path)) return undefined;
if (mapFromToProjectReferenceRedirectSource === undefined) {
mapFromToProjectReferenceRedirectSource = new Map();
forEachResolvedProjectReference(resolvedRef => {
@@ -2772,7 +2772,7 @@ namespace ts {
}
});
}
return mapFromToProjectReferenceRedirectSource.get(toPath(file));
return mapFromToProjectReferenceRedirectSource.get(path);
}
function isSourceOfProjectReferenceRedirect(fileName: string) {
@@ -2954,10 +2954,8 @@ namespace ts {
modulesWithElidedImports.set(file.path, true);
}
else if (shouldAddFile) {
const path = toPath(resolvedFileName);
findSourceFile(
resolvedFileName,
path,
/*isDefaultLib*/ false,
/*ignoreNoDefaultLib*/ false,
{ kind: FileIncludeKind.Import, file: file.path, index, },
@@ -3691,7 +3689,7 @@ namespace ts {
useSourceOfProjectReferenceRedirect: boolean;
toPath(fileName: string): Path;
getResolvedProjectReferences(): readonly (ResolvedProjectReference | undefined)[] | undefined;
getSourceOfProjectReferenceRedirect(fileName: string): SourceOfProjectReferenceRedirect | undefined;
getSourceOfProjectReferenceRedirect(path: Path): SourceOfProjectReferenceRedirect | undefined;
forEachResolvedProjectReference<T>(cb: (resolvedProjectReference: ResolvedProjectReference) => T | undefined): T | undefined;
}
@@ -3778,9 +3776,9 @@ namespace ts {
}
function fileExistsIfProjectReferenceDts(file: string) {
const source = host.getSourceOfProjectReferenceRedirect(file);
const source = host.getSourceOfProjectReferenceRedirect(host.toPath(file));
return source !== undefined ?
isString(source) ? originalFileExists.call(host.compilerHost, source) : true :
isString(source) ? originalFileExists.call(host.compilerHost, source) as boolean : true :
undefined;
}
+1 -1
View File
@@ -1279,7 +1279,7 @@ namespace ts {
const platform: string = _os.platform();
const useCaseSensitiveFileNames = isFileSystemCaseSensitive();
const realpathSync = useCaseSensitiveFileNames ? (_fs.realpathSync.native ?? _fs.realpathSync) : _fs.realpathSync;
const realpathSync = _fs.realpathSync.native ?? _fs.realpathSync;
const fsSupportsRecursiveFsWatch = isNode4OrLater && (process.platform === "win32" || process.platform === "darwin");
const getCurrentDirectory = memoize(() => process.cwd());
+9 -1
View File
@@ -2253,6 +2253,11 @@ namespace ts {
readonly expression: Expression;
}
/* @internal */
export interface JSDocTypeAssertion extends ParenthesizedExpression {
readonly _jsDocTypeAssertionBrand: never;
}
export interface ArrayLiteralExpression extends PrimaryExpression {
readonly kind: SyntaxKind.ArrayLiteralExpression;
readonly elements: NodeArray<Expression>;
@@ -6460,6 +6465,7 @@ namespace ts {
realpath?(path: string): string;
getCurrentDirectory?(): string;
getDirectories?(path: string): string[];
useCaseSensitiveFileNames?: boolean | (() => boolean);
}
/**
@@ -6889,7 +6895,9 @@ namespace ts {
PartiallyEmittedExpressions = 1 << 3,
Assertions = TypeAssertions | NonNullAssertions,
All = Parentheses | Assertions | PartiallyEmittedExpressions
All = Parentheses | Assertions | PartiallyEmittedExpressions,
ExcludeJSDocTypeAssertion = 1 << 4,
}
/* @internal */
+31 -6
View File
@@ -2634,13 +2634,13 @@ namespace ts {
let result: (JSDoc | JSDocTag)[] | undefined;
// Pull parameter comments from declaring function as well
if (isVariableLike(hostNode) && hasInitializer(hostNode) && hasJSDocNodes(hostNode.initializer!)) {
result = append(result, last((hostNode.initializer as HasJSDoc).jsDoc!));
result = addRange(result, filterOwnedJSDocTags(hostNode, last((hostNode.initializer as HasJSDoc).jsDoc!)));
}
let node: Node | undefined = hostNode;
while (node && node.parent) {
if (hasJSDocNodes(node)) {
result = append(result, last(node.jsDoc!));
result = addRange(result, filterOwnedJSDocTags(hostNode, last(node.jsDoc!)));
}
if (node.kind === SyntaxKind.Parameter) {
@@ -2656,6 +2656,26 @@ namespace ts {
return result || emptyArray;
}
function filterOwnedJSDocTags(hostNode: Node, jsDoc: JSDoc | JSDocTag) {
if (isJSDoc(jsDoc)) {
const ownedTags = filter(jsDoc.tags, tag => ownsJSDocTag(hostNode, tag));
return jsDoc.tags === ownedTags ? [jsDoc] : ownedTags;
}
return ownsJSDocTag(hostNode, jsDoc) ? [jsDoc] : undefined;
}
/**
* Determines whether a host node owns a jsDoc tag. A `@type` tag attached to a
* a ParenthesizedExpression belongs only to the ParenthesizedExpression.
*/
function ownsJSDocTag(hostNode: Node, tag: JSDocTag) {
return !isJSDocTypeTag(tag)
|| !tag.parent
|| !isJSDoc(tag.parent)
|| !isParenthesizedExpression(tag.parent.parent)
|| tag.parent.parent === hostNode;
}
export function getNextJSDocCommentLocation(node: Node) {
const parent = node.parent;
if (parent.kind === SyntaxKind.PropertyAssignment ||
@@ -2899,10 +2919,13 @@ namespace ts {
return [child, node];
}
export function skipParentheses(node: Expression): Expression;
export function skipParentheses(node: Node): Node;
export function skipParentheses(node: Node): Node {
return skipOuterExpressions(node, OuterExpressionKinds.Parentheses);
export function skipParentheses(node: Expression, excludeJSDocTypeAssertions?: boolean): Expression;
export function skipParentheses(node: Node, excludeJSDocTypeAssertions?: boolean): Node;
export function skipParentheses(node: Node, excludeJSDocTypeAssertions?: boolean): Node {
const flags = excludeJSDocTypeAssertions ?
OuterExpressionKinds.Parentheses | OuterExpressionKinds.ExcludeJSDocTypeAssertion :
OuterExpressionKinds.Parentheses;
return skipOuterExpressions(node, flags);
}
// a node is delete target iff. it is PropertyAccessExpression/ElementAccessExpression with parentheses skipped
@@ -6210,7 +6233,9 @@ namespace ts {
}
export interface SymlinkedDirectory {
/** Matches the casing returned by `realpath`. Used to compute the `realpath` of children. */
real: string;
/** toPath(real). Stored to avoid repeated recomputation. */
realPath: Path;
}
+7
View File
@@ -138,6 +138,13 @@ namespace ts.server {
this.processResponse(request, /*expectEmptyBody*/ true);
}
/*@internal*/
setCompilerOptionsForInferredProjects(options: protocol.CompilerOptions) {
const args: protocol.SetCompilerOptionsForInferredProjectsArgs = { options };
const request = this.processRequest(CommandNames.CompilerOptionsForInferredProjects, args);
this.processResponse(request, /*expectEmptyBody*/ false);
}
openFile(file: string, fileContent?: string, scriptKindName?: "TS" | "JS" | "TSX" | "JSX"): void {
const args: protocol.OpenRequestArgs = { file, fileContent, scriptKindName };
this.processRequest(CommandNames.Open, args);
+7 -2
View File
@@ -3935,6 +3935,11 @@ namespace FourSlash {
(this.languageService as ts.server.SessionClient).configurePlugin(pluginName, configuration);
}
public setCompilerOptionsForInferredProjects(options: ts.server.protocol.CompilerOptions) {
ts.Debug.assert(this.testType === FourSlashTestType.Server);
(this.languageService as ts.server.SessionClient).setCompilerOptionsForInferredProjects(options);
}
public toggleLineComment(newFileContent: string): void {
const changes: ts.TextChange[] = [];
for (const range of this.getRanges()) {
@@ -4077,7 +4082,7 @@ namespace FourSlash {
try {
const test = new FourSlashInterface.Test(state);
const goTo = new FourSlashInterface.GoTo(state);
const plugins = new FourSlashInterface.Plugins(state);
const config = new FourSlashInterface.Config(state);
const verify = new FourSlashInterface.Verify(state);
const edit = new FourSlashInterface.Edit(state);
const debug = new FourSlashInterface.Debug(state);
@@ -4085,7 +4090,7 @@ namespace FourSlash {
const cancellation = new FourSlashInterface.Cancellation(state);
// eslint-disable-next-line no-eval
const f = eval(wrappedCode);
f(test, goTo, plugins, verify, edit, debug, format, cancellation, FourSlashInterface.classification, FourSlashInterface.Completion, verifyOperationIsCancelled);
f(test, goTo, config, verify, edit, debug, format, cancellation, FourSlashInterface.classification, FourSlashInterface.Completion, verifyOperationIsCancelled);
}
catch (err) {
// ensure 'source-map-support' is triggered while we still have the handler attached by accessing `error.stack`.
+5 -1
View File
@@ -48,13 +48,17 @@ namespace FourSlashInterface {
}
}
export class Plugins {
export class Config {
constructor(private state: FourSlash.TestState) {
}
public configurePlugin(pluginName: string, configuration: any): void {
this.state.configurePlugin(pluginName, configuration);
}
public setCompilerOptionsForInferredProjects(options: ts.server.protocol.CompilerOptions): void {
this.state.setCompilerOptionsForInferredProjects(options);
}
}
export class GoTo {
+3 -2
View File
@@ -325,7 +325,8 @@ namespace Harness.LanguageService {
readFile: fileName => {
const scriptInfo = this.getScriptInfo(fileName);
return scriptInfo && scriptInfo.content;
}
},
useCaseSensitiveFileNames: this.useCaseSensitiveFileNames()
};
this.getModuleResolutionsForFile = (fileName) => {
const scriptInfo = this.getScriptInfo(fileName)!;
@@ -829,7 +830,7 @@ namespace Harness.LanguageService {
setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): any {
// eslint-disable-next-line no-restricted-globals
return setTimeout(callback, ms, args);
return setTimeout(callback, ms, ...args);
}
clearTimeout(timeoutId: any): void {
+1 -1
View File
@@ -1261,7 +1261,7 @@ interface Array<T> {
* Sorts an array in place.
* This method mutates the array and returns a reference to the same array.
* @param compareFn Function used to determine the order of the elements. It is expected to return
* a negative value if first argument is less than second argument, zero if they're equal and a positive
* a negative value if the first argument is less than the second argument, zero if they're equal, and a positive
* value otherwise. If omitted, the elements are sorted in ascending, ASCII character order.
* ```ts
* [11,2,22,1].sort((a, b) => a - b)
@@ -7098,6 +7098,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_decl_7058" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[If the '{0}' package actually exposes this module, try adding a new declaration (.d.ts) file containing `declare module '{1}';`]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[如果“{0}”包实际公开了此模块,请尝试添加包含 `declare module‘{1}';` 的新声明(.d.ts)文件]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Ignore_this_error_message_90019" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Ignore this error message]]></Val>
@@ -7098,6 +7098,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_decl_7058" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[If the '{0}' package actually exposes this module, try adding a new declaration (.d.ts) file containing `declare module '{1}';`]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[如果 '{0}' 套件的確公開了此模組,請嘗試新增包含 `declare module '{1}';` 的宣告 (.d.ts) 檔案。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Ignore_this_error_message_90019" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Ignore this error message]]></Val>
@@ -7107,6 +7107,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_decl_7058" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[If the '{0}' package actually exposes this module, try adding a new declaration (.d.ts) file containing `declare module '{1}';`]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Pokud balíček {0} skutečně zpřístupňuje tento modul, zkuste přidat nový soubor deklarace (.d.ts), který obsahuje declare module {1};]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Ignore_this_error_message_90019" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Ignore this error message]]></Val>
@@ -7095,6 +7095,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_decl_7058" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[If the '{0}' package actually exposes this module, try adding a new declaration (.d.ts) file containing `declare module '{1}';`]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Wenn das Paket "{0}" dieses Modul tatsächlich verfügbar macht, versuchen Sie, eine neue Deklarationsdatei (.d.ts) hinzuzufügen, die Declare-Modul "{1}" enthält.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Ignore_this_error_message_90019" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Ignore this error message]]></Val>
@@ -7110,6 +7110,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_decl_7058" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[If the '{0}' package actually exposes this module, try adding a new declaration (.d.ts) file containing `declare module '{1}';`]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Si el paquete '{0}' realmente expone este módulo, intente agregar un nuevo archivo de declaración (.d.ts) que contenga 'declarar módulo '{1}';`]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Ignore_this_error_message_90019" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Ignore this error message]]></Val>
@@ -7110,6 +7110,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_decl_7058" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[If the '{0}' package actually exposes this module, try adding a new declaration (.d.ts) file containing `declare module '{1}';`]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Si le package' {0} 'expose effectivement ce module, essayez d’ajouter un nouveau fichier de déclaration (. d. TS) contenant’declare module' {1} '; ']]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Ignore_this_error_message_90019" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Ignore this error message]]></Val>
@@ -7098,6 +7098,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_decl_7058" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[If the '{0}' package actually exposes this module, try adding a new declaration (.d.ts) file containing `declare module '{1}';`]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Se il pacchetto ' {0}' espone effettivamente il modulo, provare ad aggiungere un nuovo file di dichiarazione (.d.ts) contenente ' Dichiara modulo' {1}';']]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Ignore_this_error_message_90019" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Ignore this error message]]></Val>
@@ -7098,6 +7098,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_decl_7058" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[If the '{0}' package actually exposes this module, try adding a new declaration (.d.ts) file containing `declare module '{1}';`]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['{0}' パッケージが実際にこのモジュールを公開する場合は、'declare module '{1}';' を含む新しい宣言 (d.ts) ファイルを追加してみてください。]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Ignore_this_error_message_90019" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Ignore this error message]]></Val>
@@ -7098,6 +7098,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_decl_7058" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[If the '{0}' package actually exposes this module, try adding a new declaration (.d.ts) file containing `declare module '{1}';`]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA['{0}' 패키지가 실제로 이 모듈을 노출하는 경우 'declare module {1}';'이(가) 포함된 새 선언(.d.ts) 파일을 추가해 보세요.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Ignore_this_error_message_90019" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Ignore this error message]]></Val>
@@ -7088,6 +7088,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_decl_7058" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[If the '{0}' package actually exposes this module, try adding a new declaration (.d.ts) file containing `declare module '{1}';`]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Jeśli pakiet „{0}” rzeczywiście uwidacznia ten moduł, spróbuj dodać nowy plik deklaracji (.d.ts) zawierający „declare module”{1}';`]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Ignore_this_error_message_90019" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Ignore this error message]]></Val>
@@ -7091,6 +7091,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_decl_7058" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[If the '{0}' package actually exposes this module, try adding a new declaration (.d.ts) file containing `declare module '{1}';`]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Se o pacote '{0}' realmente expõe este módulo, tente adicionar um novo arquivo de declaração (.d.ts) contendo o módulo `declare '{1}';`]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Ignore_this_error_message_90019" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Ignore this error message]]></Val>
@@ -7097,6 +7097,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_decl_7058" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[If the '{0}' package actually exposes this module, try adding a new declaration (.d.ts) file containing `declare module '{1}';`]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Если пакет "{0}" действительно предоставляет этот модуль, попробуйте добавить новый файл объявления (. d. TS), содержащий "declare module" "{1}";`]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Ignore_this_error_message_90019" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Ignore this error message]]></Val>
@@ -7091,6 +7091,15 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";If_the_0_package_actually_exposes_this_module_try_adding_a_new_declaration_d_ts_file_containing_decl_7058" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[If the '{0}' package actually exposes this module, try adding a new declaration (.d.ts) file containing `declare module '{1}';`]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[‘{0}’ paketi bu modülü fiili olarak kullanıma sunuyorsa `'{1}' modülünü bildir;` ifadesini içeren yeni bir bildirim (.d.ts) dosyası eklemeyi deneyin]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Ignore_this_error_message_90019" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Ignore this error message]]></Val>
+17 -7
View File
@@ -1706,6 +1706,7 @@ namespace ts.server {
readFile: this.projectService.host.readFile.bind(this.projectService.host),
getDirectories: this.projectService.host.getDirectories.bind(this.projectService.host),
trace: this.projectService.host.trace?.bind(this.projectService.host),
useCaseSensitiveFileNames: this.program.useCaseSensitiveFileNames(),
};
}
return this.projectService.host;
@@ -1919,16 +1920,25 @@ namespace ts.server {
}
if (dependencyNames) {
const resolutions = map(arrayFrom(dependencyNames.keys()), name => resolveTypeReferenceDirective(
name,
rootFileName,
compilerOptions,
moduleResolutionHost));
const resolutions = mapDefined(arrayFrom(dependencyNames.keys()), name => {
const types = resolveTypeReferenceDirective(
name,
rootFileName,
compilerOptions,
moduleResolutionHost);
if (types.resolvedTypeReferenceDirective) {
return types.resolvedTypeReferenceDirective;
}
if (compilerOptions.allowJs && compilerOptions.maxNodeModuleJsDepth) {
return tryResolveJSModule(name, hostProject.currentDirectory, moduleResolutionHost);
}
});
const symlinkCache = hostProject.getSymlinkCache();
for (const resolution of resolutions) {
if (!resolution.resolvedTypeReferenceDirective?.resolvedFileName) continue;
const { resolvedFileName, originalPath } = resolution.resolvedTypeReferenceDirective;
if (!resolution.resolvedFileName) continue;
const { resolvedFileName, originalPath } = resolution;
if (!program.getSourceFile(resolvedFileName) && (!originalPath || !program.getSourceFile(originalPath))) {
rootNames = append(rootNames, resolvedFileName);
// Avoid creating a large project that would significantly slow down time to editor interactivity
+11 -5
View File
@@ -1338,13 +1338,16 @@ namespace ts.Completions {
case SyntaxKind.PropertyAccessExpression:
propertyAccessToConvert = parent as PropertyAccessExpression;
node = propertyAccessToConvert.expression;
if ((isCallExpression(node) || isFunctionLike(node)) &&
node.end === contextToken.pos &&
node.getChildCount(sourceFile) &&
last(node.getChildren(sourceFile)).kind !== SyntaxKind.CloseParenToken) {
const leftmostAccessExpression = getLeftmostAccessExpression(propertyAccessToConvert);
if (nodeIsMissing(leftmostAccessExpression) ||
((isCallExpression(node) || isFunctionLike(node)) &&
node.end === contextToken.pos &&
node.getChildCount(sourceFile) &&
last(node.getChildren(sourceFile)).kind !== SyntaxKind.CloseParenToken)) {
// This is likely dot from incorrectly parsed expression and user is starting to write spread
// eg: Math.min(./**/)
// const x = function (./**/) {}
// ({./**/})
return undefined;
}
break;
@@ -1497,7 +1500,10 @@ namespace ts.Completions {
log("getCompletionData: Semantic work: " + (timestamp() - semanticStart));
const contextualType = previousToken && getContextualType(previousToken, position, sourceFile, typeChecker);
const literals = mapDefined(contextualType && (contextualType.isUnion() ? contextualType.types : [contextualType]), t => t.isLiteral() ? t.value : undefined);
const literals = mapDefined(
contextualType && (contextualType.isUnion() ? contextualType.types : [contextualType]),
t => t.isLiteral() && !(t.flags & TypeFlags.EnumLiteral) ? t.value : undefined);
const recommendedCompletion = previousToken && contextualType && getRecommendedCompletion(previousToken, contextualType, typeChecker);
return {
+3 -2
View File
@@ -65,11 +65,12 @@ namespace ts {
fileExists: path => {
assert.isTrue(directories.has(getDirectoryPath(path)), `'fileExists' '${path}' request in non-existing directory`);
return map.has(path);
}
},
useCaseSensitiveFileNames: true
};
}
else {
return { readFile, realpath, fileExists: path => map.has(path) };
return { readFile, realpath, fileExists: path => map.has(path), useCaseSensitiveFileNames: true };
}
function readFile(path: string): string | undefined {
const file = map.get(path);