getTokenAtPosition: default includeJsDocComment to true (#25015)
* getTokenAtPosition: default includeJsDocComment to true * Update API (#24966) * Flip meaning of parameter * Update API (#24966) * Remove all `ignoreJsDocComment` uses (fixes #25162)
This commit is contained in:
parent
f4a2ee456d
commit
13bc46d970
|
@ -697,10 +697,11 @@ namespace ts {
|
|||
bindJSDocTypeAlias(node as JSDocTypedefTag | JSDocCallbackTag);
|
||||
break;
|
||||
// In source files and blocks, bind functions first to match hoisting that occurs at runtime
|
||||
case SyntaxKind.SourceFile:
|
||||
case SyntaxKind.SourceFile: {
|
||||
bindEachFunctionsFirst((node as SourceFile).statements);
|
||||
bind((node as SourceFile).endOfFileToken);
|
||||
break;
|
||||
}
|
||||
case SyntaxKind.Block:
|
||||
case SyntaxKind.ModuleBlock:
|
||||
bindEachFunctionsFirst((node as Block).statements);
|
||||
|
@ -1975,7 +1976,10 @@ namespace ts {
|
|||
}
|
||||
else if (!skipTransformFlagAggregation && (node.transformFlags & TransformFlags.HasComputedFlags) === 0) {
|
||||
subtreeTransformFlags |= computeTransformFlagsForNode(node, 0);
|
||||
const saveParent = parent;
|
||||
if (node.kind === SyntaxKind.EndOfFileToken) parent = node;
|
||||
bindJSDoc(node);
|
||||
parent = saveParent;
|
||||
}
|
||||
inStrictMode = saveInStrictMode;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace ts.BreakpointResolver {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
let tokenAtLocation = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
|
||||
let tokenAtLocation = getTokenAtPosition(sourceFile, position);
|
||||
const lineOfPosition = sourceFile.getLineAndCharacterOfPosition(position).line;
|
||||
if (sourceFile.getLineAndCharacterOfPosition(tokenAtLocation.getStart(sourceFile)).line > lineOfPosition) {
|
||||
// Get previous token if the token is returned starts on new line
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace ts.codefix {
|
|||
});
|
||||
|
||||
function makeChange(changeTracker: textChanges.ChangeTracker, sourceFile: SourceFile, pos: number) {
|
||||
const token = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false);
|
||||
const token = getTokenAtPosition(sourceFile, pos);
|
||||
const decorator = findAncestor(token, isDecorator)!;
|
||||
Debug.assert(!!decorator, "Expected position to be owned by a decorator.");
|
||||
const replacement = createCall(decorator.expression, /*typeArguments*/ undefined, /*argumentsArray*/ undefined);
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace ts.codefix {
|
|||
});
|
||||
|
||||
function getDeclaration(file: SourceFile, pos: number): DeclarationWithType | undefined {
|
||||
const name = getTokenAtPosition(file, pos, /*includeJsDocComment*/ false);
|
||||
const name = getTokenAtPosition(file, pos);
|
||||
// For an arrow function with no name, 'name' lands on the first parameter.
|
||||
return tryCast(isParameter(name.parent) ? name.parent.parent : name.parent, parameterShouldGetTypeFromJSDoc);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace ts.codefix {
|
|||
|
||||
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, position: number, checker: TypeChecker): void {
|
||||
const deletedNodes: { node: Node, inList: boolean }[] = [];
|
||||
const ctorSymbol = checker.getSymbolAtLocation(getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false))!;
|
||||
const ctorSymbol = checker.getSymbolAtLocation(getTokenAtPosition(sourceFile, position))!;
|
||||
|
||||
if (!ctorSymbol || !(ctorSymbol.flags & (SymbolFlags.Function | SymbolFlags.Variable))) {
|
||||
// Bad input
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace ts.codefix {
|
|||
|
||||
interface Info { readonly indexSignature: IndexSignatureDeclaration; readonly container: FixableDeclaration; }
|
||||
function getInfo(sourceFile: SourceFile, pos: number): Info | undefined {
|
||||
const token = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false);
|
||||
const token = getTokenAtPosition(sourceFile, pos);
|
||||
const indexSignature = cast(token.parent.parent, isIndexSignatureDeclaration);
|
||||
if (isClassDeclaration(indexSignature.parent)) return undefined;
|
||||
const container = isInterfaceDeclaration(indexSignature.parent) ? indexSignature.parent : cast(indexSignature.parent.parent, isTypeAliasDeclaration);
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace ts.codefix {
|
|||
});
|
||||
|
||||
function getQualifiedName(sourceFile: SourceFile, pos: number): QualifiedName & { left: Identifier } | undefined {
|
||||
const qualifiedName = findAncestor(getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ true), isQualifiedName)!;
|
||||
const qualifiedName = findAncestor(getTokenAtPosition(sourceFile, pos), isQualifiedName)!;
|
||||
Debug.assert(!!qualifiedName, "Expected position to be owned by a qualified name.");
|
||||
return isIdentifier(qualifiedName.left) ? qualifiedName as QualifiedName & { left: Identifier } : undefined;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace ts.codefix {
|
|||
// The identifier of the missing property. eg:
|
||||
// this.missing = 1;
|
||||
// ^^^^^^^
|
||||
const token = getTokenAtPosition(tokenSourceFile, tokenPos, /*includeJsDocComment*/ false);
|
||||
const token = getTokenAtPosition(tokenSourceFile, tokenPos);
|
||||
if (!isIdentifier(token)) {
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace ts.codefix {
|
|||
});
|
||||
|
||||
function getImportTypeNode(sourceFile: SourceFile, pos: number): ImportTypeNode {
|
||||
const token = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false);
|
||||
const token = getTokenAtPosition(sourceFile, pos);
|
||||
Debug.assert(token.kind === SyntaxKind.ImportKeyword);
|
||||
Debug.assert(token.parent.kind === SyntaxKind.ImportType);
|
||||
return <ImportTypeNode>token.parent;
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace ts.codefix {
|
|||
}
|
||||
|
||||
function getNodes(sourceFile: SourceFile, start: number): { insertBefore: Node, returnType: TypeNode | undefined } | undefined {
|
||||
const token = getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false);
|
||||
const token = getTokenAtPosition(sourceFile, start);
|
||||
const containingFunction = getContainingFunction(token);
|
||||
if (!containingFunction) {
|
||||
return;
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace ts.codefix {
|
|||
}
|
||||
|
||||
function getTypesPackageNameToInstall(host: LanguageServiceHost, sourceFile: SourceFile, pos: number, diagCode: number): string | undefined {
|
||||
const moduleName = cast(getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false), isStringLiteral).text;
|
||||
const moduleName = cast(getTokenAtPosition(sourceFile, pos), isStringLiteral).text;
|
||||
const { packageName } = getPackageName(moduleName);
|
||||
return diagCode === errorCodeCannotFindModule
|
||||
? (JsTyping.nodeCoreModules.has(packageName) ? "@types/node" : undefined)
|
||||
|
|
|
@ -28,7 +28,7 @@ namespace ts.codefix {
|
|||
function getClass(sourceFile: SourceFile, pos: number): ClassLikeDeclaration {
|
||||
// Token is the identifier in the case of a class declaration
|
||||
// or the class keyword token in the case of a class expression.
|
||||
const token = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false);
|
||||
const token = getTokenAtPosition(sourceFile, pos);
|
||||
return cast(token.parent, isClassLike);
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace ts.codefix {
|
|||
});
|
||||
|
||||
function getClass(sourceFile: SourceFile, pos: number): ClassLikeDeclaration {
|
||||
return Debug.assertDefined(getContainingClass(getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false)));
|
||||
return Debug.assertDefined(getContainingClass(getTokenAtPosition(sourceFile, pos)));
|
||||
}
|
||||
|
||||
function symbolPointsToNonPrivateMember (symbol: Symbol) {
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace ts.codefix {
|
|||
}
|
||||
|
||||
function getNodes(sourceFile: SourceFile, pos: number): { readonly constructor: ConstructorDeclaration, readonly superCall: ExpressionStatement } | undefined {
|
||||
const token = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false);
|
||||
const token = getTokenAtPosition(sourceFile, pos);
|
||||
if (token.kind !== SyntaxKind.ThisKeyword) return undefined;
|
||||
const constructor = getContainingFunction(token) as ConstructorDeclaration;
|
||||
const superCall = findSuperCall(constructor.body!);
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace ts.codefix {
|
|||
});
|
||||
|
||||
function getNode(sourceFile: SourceFile, pos: number): ConstructorDeclaration {
|
||||
const token = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false);
|
||||
const token = getTokenAtPosition(sourceFile, pos);
|
||||
Debug.assert(token.kind === SyntaxKind.ConstructorKeyword);
|
||||
return token.parent as ConstructorDeclaration;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ namespace ts.codefix {
|
|||
});
|
||||
|
||||
function getNodes(sourceFile: SourceFile, pos: number) {
|
||||
const token = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false);
|
||||
const token = getTokenAtPosition(sourceFile, pos);
|
||||
const heritageClauses = getContainingClass(token)!.heritageClauses!;
|
||||
const extendsToken = heritageClauses[0].getFirstToken()!;
|
||||
return extendsToken.kind === SyntaxKind.ExtendsKeyword ? { extendsToken, heritageClauses } : undefined;
|
||||
|
|
|
@ -26,7 +26,7 @@ namespace ts.codefix {
|
|||
|
||||
interface Info { readonly node: Identifier; readonly className: string | undefined; }
|
||||
function getInfo(sourceFile: SourceFile, pos: number, diagCode: number): Info | undefined {
|
||||
const node = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false);
|
||||
const node = getTokenAtPosition(sourceFile, pos);
|
||||
if (!isIdentifier(node)) return undefined;
|
||||
return { node, className: diagCode === didYouMeanStaticMemberCode ? getContainingClass(node)!.name!.text : undefined };
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace ts.codefix {
|
|||
function getActionsForUsageOfInvalidImport(context: CodeFixContext): CodeFixAction[] | undefined {
|
||||
const sourceFile = context.sourceFile;
|
||||
const targetKind = Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures.code === context.errorCode ? SyntaxKind.CallExpression : SyntaxKind.NewExpression;
|
||||
const node = findAncestor(getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false), a => a.kind === targetKind && a.getStart() === context.span.start && a.getEnd() === (context.span.start + context.span.length)) as CallExpression | NewExpression;
|
||||
const node = findAncestor(getTokenAtPosition(sourceFile, context.span.start), a => a.kind === targetKind && a.getStart() === context.span.start && a.getEnd() === (context.span.start + context.span.length)) as CallExpression | NewExpression;
|
||||
if (!node) {
|
||||
return [];
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ namespace ts.codefix {
|
|||
|
||||
function getActionsForInvalidImportLocation(context: CodeFixContext): CodeFixAction[] | undefined {
|
||||
const sourceFile = context.sourceFile;
|
||||
const node = findAncestor(getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false), a => a.getStart() === context.span.start && a.getEnd() === (context.span.start + context.span.length));
|
||||
const node = findAncestor(getTokenAtPosition(sourceFile, context.span.start), a => a.getStart() === context.span.start && a.getEnd() === (context.span.start + context.span.length));
|
||||
if (!node) {
|
||||
return [];
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace ts.codefix {
|
|||
}
|
||||
|
||||
function getInfo(sourceFile: SourceFile, pos: number, checker: TypeChecker): { readonly typeNode: TypeNode, readonly type: Type } | undefined {
|
||||
const decl = findAncestor(getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false), isTypeContainer);
|
||||
const decl = findAncestor(getTokenAtPosition(sourceFile, pos), isTypeContainer);
|
||||
const typeNode = decl && decl.type;
|
||||
return typeNode && { typeNode, type: checker.getTypeFromTypeNode(typeNode) };
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace ts.codefix {
|
|||
// This is the identifier of the misspelled word. eg:
|
||||
// this.speling = 1;
|
||||
// ^^^^^^^
|
||||
const node = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false); // TODO: GH#15852
|
||||
const node = getTokenAtPosition(sourceFile, pos);
|
||||
const checker = context.program.getTypeChecker();
|
||||
|
||||
let suggestion: string | undefined;
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace ts.codefix {
|
|||
});
|
||||
|
||||
function getPropertyDeclaration (sourceFile: SourceFile, pos: number): PropertyDeclaration | undefined {
|
||||
const token = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false);
|
||||
const token = getTokenAtPosition(sourceFile, pos);
|
||||
return isIdentifier(token) ? cast(token.parent, isPropertyDeclaration) : undefined;
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace ts.codefix {
|
|||
});
|
||||
|
||||
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, start: number): void {
|
||||
const token = getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false);
|
||||
const token = getTokenAtPosition(sourceFile, start);
|
||||
const statement = findAncestor(token, isStatement)!;
|
||||
Debug.assert(statement.getStart(sourceFile) === token.getStart(sourceFile));
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace ts.codefix {
|
|||
getCodeActions(context) {
|
||||
const { errorCode, sourceFile, program } = context;
|
||||
const checker = program.getTypeChecker();
|
||||
const startToken = getTokenAtPosition(sourceFile, context.span.start, /*includeJsDocComment*/ false);
|
||||
const startToken = getTokenAtPosition(sourceFile, context.span.start);
|
||||
|
||||
const importDecl = tryGetFullImport(startToken);
|
||||
if (importDecl) {
|
||||
|
@ -54,7 +54,7 @@ namespace ts.codefix {
|
|||
const { sourceFile, program } = context;
|
||||
const checker = program.getTypeChecker();
|
||||
return codeFixAll(context, errorCodes, (changes, diag) => {
|
||||
const startToken = getTokenAtPosition(sourceFile, diag.start, /*includeJsDocComment*/ false);
|
||||
const startToken = getTokenAtPosition(sourceFile, diag.start);
|
||||
const token = findPrecedingToken(textSpanEnd(diag), diag.file)!;
|
||||
switch (context.fixId) {
|
||||
case fixIdPrefix:
|
||||
|
@ -173,8 +173,8 @@ namespace ts.codefix {
|
|||
const typeParameters = getEffectiveTypeParameterDeclarations(<DeclarationWithTypeParameters>parent.parent);
|
||||
if (typeParameters.length === 1) {
|
||||
const { pos, end } = cast(typeParameters, isNodeArray);
|
||||
const previousToken = getTokenAtPosition(sourceFile, pos - 1, /*includeJsDocComment*/ true);
|
||||
const nextToken = getTokenAtPosition(sourceFile, end, /*includeJsDocComment*/ true);
|
||||
const previousToken = getTokenAtPosition(sourceFile, pos - 1);
|
||||
const nextToken = getTokenAtPosition(sourceFile, end);
|
||||
Debug.assert(previousToken.kind === SyntaxKind.LessThanToken);
|
||||
Debug.assert(nextToken.kind === SyntaxKind.GreaterThanToken);
|
||||
|
||||
|
@ -251,7 +251,7 @@ namespace ts.codefix {
|
|||
else {
|
||||
// import |d,| * as ns from './file'
|
||||
const start = importClause.name!.getStart(sourceFile);
|
||||
const nextToken = getTokenAtPosition(sourceFile, importClause.name!.end, /*includeJsDocComment*/ false);
|
||||
const nextToken = getTokenAtPosition(sourceFile, importClause.name!.end);
|
||||
if (nextToken && nextToken.kind === SyntaxKind.CommaToken) {
|
||||
// shift first non-whitespace position after comma to the start position of the node
|
||||
const end = skipTrivia(sourceFile.text, nextToken.end, /*stopAfterLineBreaks*/ false, /*stopAtComments*/ true);
|
||||
|
@ -285,7 +285,7 @@ namespace ts.codefix {
|
|||
// Delete named imports while preserving the default import
|
||||
// import d|, * as ns| from './file'
|
||||
// import d|, { a }| from './file'
|
||||
const previousToken = getTokenAtPosition(sourceFile, namedBindings.pos - 1, /*includeJsDocComment*/ false);
|
||||
const previousToken = getTokenAtPosition(sourceFile, namedBindings.pos - 1);
|
||||
if (previousToken && previousToken.kind === SyntaxKind.CommaToken) {
|
||||
changes.deleteRange(sourceFile, { pos: previousToken.getStart(), end: namedBindings.end });
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace ts.codefix {
|
|||
});
|
||||
|
||||
function doChange(changes: textChanges.ChangeTracker, sourceFile: SourceFile, start: number): void {
|
||||
const token = getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false);
|
||||
const token = getTokenAtPosition(sourceFile, start);
|
||||
const labeledStatement = cast(token.parent, isLabeledStatement);
|
||||
const pos = token.getStart(sourceFile);
|
||||
const statementPos = labeledStatement.statement.getStart(sourceFile);
|
||||
|
|
|
@ -326,7 +326,7 @@ namespace ts.codefix {
|
|||
}
|
||||
|
||||
function getActionsForUMDImport(context: CodeFixContext): CodeFixAction[] | undefined {
|
||||
const token = getTokenAtPosition(context.sourceFile, context.span.start, /*includeJsDocComment*/ false);
|
||||
const token = getTokenAtPosition(context.sourceFile, context.span.start);
|
||||
const checker = context.program.getTypeChecker();
|
||||
|
||||
let umdSymbol: Symbol | undefined;
|
||||
|
@ -385,7 +385,7 @@ namespace ts.codefix {
|
|||
// This will always be an Identifier, since the diagnostics we fix only fail on identifiers.
|
||||
const { sourceFile, span, program, cancellationToken } = context;
|
||||
const checker = program.getTypeChecker();
|
||||
const symbolToken = getTokenAtPosition(sourceFile, span.start, /*includeJsDocComment*/ false);
|
||||
const symbolToken = getTokenAtPosition(sourceFile, span.start);
|
||||
// If we're at `<Foo/>`, we must check if `Foo` is already in scope, and if so, get an import for `React` instead.
|
||||
const symbolName = isJsxOpeningLikeElement(symbolToken.parent)
|
||||
&& symbolToken.parent.tagName === symbolToken
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace ts.codefix {
|
|||
return undefined; // TODO: GH#20113
|
||||
}
|
||||
|
||||
const token = getTokenAtPosition(sourceFile, start, /*includeJsDocComment*/ false);
|
||||
const token = getTokenAtPosition(sourceFile, start);
|
||||
let declaration!: Declaration | undefined;
|
||||
const changes = textChanges.ChangeTracker.with(context, changes => { declaration = doChange(changes, sourceFile, token, errorCode, program, cancellationToken, /*markSeenseen*/ returnTrue); });
|
||||
const name = getNameOfDeclaration(declaration!);
|
||||
|
@ -42,7 +42,7 @@ namespace ts.codefix {
|
|||
const { sourceFile, program, cancellationToken } = context;
|
||||
const markSeen = nodeSeenTracker();
|
||||
return codeFixAll(context, errorCodes, (changes, err) => {
|
||||
doChange(changes, sourceFile, getTokenAtPosition(err.file, err.start, /*includeJsDocComment*/ false), err.code, program, cancellationToken, markSeen);
|
||||
doChange(changes, sourceFile, getTokenAtPosition(err.file, err.start), err.code, program, cancellationToken, markSeen);
|
||||
});
|
||||
},
|
||||
});
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace ts.codefix {
|
|||
|
||||
interface Info { readonly statement: VariableStatement; readonly name: Identifier; readonly required: StringLiteralLike; }
|
||||
function getInfo(sourceFile: SourceFile, pos: number): Info {
|
||||
const { parent } = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false);
|
||||
const { parent } = getTokenAtPosition(sourceFile, pos);
|
||||
if (!isRequireCall(parent, /*checkArgumentIsStringLiteralLike*/ true)) throw Debug.failBadSyntaxKind(parent);
|
||||
const decl = cast(parent.parent, isVariableDeclaration);
|
||||
return { statement: cast(decl.parent.parent, isVariableStatement), name: cast(decl.name, isIdentifier), required: parent.arguments[0] };
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace ts.codefix {
|
|||
readonly moduleSpecifier: Expression;
|
||||
}
|
||||
function getInfo(sourceFile: SourceFile, pos: number): Info | undefined {
|
||||
const name = getTokenAtPosition(sourceFile, pos, /*includeJsDocComment*/ false);
|
||||
const name = getTokenAtPosition(sourceFile, pos);
|
||||
if (!isIdentifier(name)) return undefined; // bad input
|
||||
const { parent } = name;
|
||||
if (isImportEqualsDeclaration(parent) && isExternalModuleReference(parent.moduleReference)) {
|
||||
|
|
|
@ -797,13 +797,12 @@ namespace ts.Completions {
|
|||
const typeChecker = program.getTypeChecker();
|
||||
|
||||
let start = timestamp();
|
||||
let currentToken = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false); // TODO: GH#15853
|
||||
let currentToken = getTokenAtPosition(sourceFile, position); // TODO: GH#15853
|
||||
// We will check for jsdoc comments with insideComment and getJsDocTagAtPosition. (TODO: that seems rather inefficient to check the same thing so many times.)
|
||||
|
||||
log("getCompletionData: Get current token: " + (timestamp() - start));
|
||||
|
||||
start = timestamp();
|
||||
// Completion not allowed inside comments, bail out if this is the case
|
||||
const insideComment = isInComment(sourceFile, position, currentToken);
|
||||
log("getCompletionData: Is inside comment: " + (timestamp() - start));
|
||||
|
||||
|
@ -849,7 +848,7 @@ namespace ts.Completions {
|
|||
return { kind: CompletionDataKind.JsDocTagName };
|
||||
}
|
||||
if (isTagWithTypeExpression(tag) && tag.typeExpression && tag.typeExpression.kind === SyntaxKind.JSDocTypeExpression) {
|
||||
currentToken = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ true);
|
||||
currentToken = getTokenAtPosition(sourceFile, position);
|
||||
if (!currentToken ||
|
||||
(!isDeclarationName(currentToken) &&
|
||||
(currentToken.parent.kind !== SyntaxKind.JSDocPropertyTag ||
|
||||
|
@ -2156,32 +2155,8 @@ namespace ts.Completions {
|
|||
|
||||
/** Get the corresponding JSDocTag node if the position is in a jsDoc comment */
|
||||
function getJsDocTagAtPosition(node: Node, position: number): JSDocTag | undefined {
|
||||
const { jsDoc } = getJsDocHavingNode(node) as JSDocContainer;
|
||||
if (!jsDoc) return undefined;
|
||||
|
||||
for (const { pos, end, tags } of jsDoc) {
|
||||
if (!tags || position < pos || position > end) continue;
|
||||
for (let i = tags.length - 1; i >= 0; i--) {
|
||||
const tag = tags[i];
|
||||
if (position >= tag.pos) {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getJsDocHavingNode(node: Node): Node {
|
||||
if (!isToken(node)) return node;
|
||||
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.VarKeyword:
|
||||
case SyntaxKind.LetKeyword:
|
||||
case SyntaxKind.ConstKeyword:
|
||||
// if the current token is var, let or const, skip the VariableDeclarationList
|
||||
return node.parent.parent;
|
||||
default:
|
||||
return node.parent;
|
||||
}
|
||||
const jsdoc = findAncestor(node, isJSDoc);
|
||||
return jsdoc && jsdoc.tags && (rangeContainsPosition(jsdoc, position) ? findLast(jsdoc.tags, tag => tag.pos < position) : undefined);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1148,8 +1148,10 @@ namespace ts.formatting {
|
|||
position: number,
|
||||
onlyMultiLine: boolean,
|
||||
precedingToken?: Node | null, // tslint:disable-line:no-null-keyword
|
||||
tokenAtPosition = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false),
|
||||
tokenAtPosition = getTokenAtPosition(sourceFile, position),
|
||||
predicate?: (c: CommentRange) => boolean): CommentRange | undefined {
|
||||
const jsdoc = findAncestor(tokenAtPosition, isJSDoc);
|
||||
if (jsdoc) tokenAtPosition = jsdoc.parent;
|
||||
const tokenStart = tokenAtPosition.getStart(sourceFile);
|
||||
if (tokenStart <= position && position < tokenAtPosition.getEnd()) {
|
||||
return undefined;
|
||||
|
|
|
@ -242,7 +242,7 @@ namespace ts.JsDoc {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
const tokenAtPos = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
|
||||
const tokenAtPos = getTokenAtPosition(sourceFile, position);
|
||||
const tokenStart = tokenAtPos.getStart(sourceFile);
|
||||
if (!tokenAtPos || tokenStart < position) {
|
||||
return undefined;
|
||||
|
|
|
@ -304,7 +304,7 @@ namespace ts.Completions.PathCompletions {
|
|||
}
|
||||
|
||||
export function getTripleSlashReferenceCompletion(sourceFile: SourceFile, position: number, compilerOptions: CompilerOptions, host: LanguageServiceHost): ReadonlyArray<PathCompletion> | undefined {
|
||||
const token = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
|
||||
const token = getTokenAtPosition(sourceFile, position);
|
||||
const commentRanges = getLeadingCommentRanges(sourceFile.text, token.pos);
|
||||
const range = commentRanges && find(commentRanges, commentRange => position >= commentRange.pos && position <= commentRange.end);
|
||||
if (!range) {
|
||||
|
|
|
@ -69,7 +69,7 @@ namespace ts.refactor.addOrRemoveBracesToArrowFunction {
|
|||
}
|
||||
|
||||
function getConvertibleArrowFunctionAtPosition(file: SourceFile, startPosition: number): Info | undefined {
|
||||
const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false);
|
||||
const node = getTokenAtPosition(file, startPosition);
|
||||
const func = getContainingFunction(node);
|
||||
if (!func || !isArrowFunction(func) || (!rangeContainsRange(func, node) || rangeContainsRange(func.body, node))) return undefined;
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace ts.refactor {
|
|||
function getInfo(context: RefactorContext): Info | undefined {
|
||||
const { file } = context;
|
||||
const span = getRefactorContextSpan(context);
|
||||
const token = getTokenAtPosition(file, span.start, /*includeJsDocComment*/ false);
|
||||
const token = getTokenAtPosition(file, span.start);
|
||||
const exportNode = getParentNodeInSpan(token, file, span);
|
||||
if (!exportNode || (!isSourceFile(exportNode.parent) && !(isModuleBlock(exportNode.parent) && isAmbientModule(exportNode.parent.parent)))) {
|
||||
return undefined;
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace ts.refactor {
|
|||
function getImportToConvert(context: RefactorContext): NamedImportBindings | undefined {
|
||||
const { file } = context;
|
||||
const span = getRefactorContextSpan(context);
|
||||
const token = getTokenAtPosition(file, span.start, /*includeJsDocComment*/ false);
|
||||
const token = getTokenAtPosition(file, span.start);
|
||||
const importDecl = getParentNodeInSpan(token, file, span);
|
||||
if (!importDecl || !isImportDeclaration(importDecl)) return undefined;
|
||||
const { importClause } = importDecl;
|
||||
|
|
|
@ -194,7 +194,7 @@ namespace ts.refactor.extractSymbol {
|
|||
|
||||
// Walk up starting from the the start position until we find a non-SourceFile node that subsumes the selected span.
|
||||
// This may fail (e.g. you select two statements in the root of a source file)
|
||||
const start = getParentNodeInSpan(getTokenAtPosition(sourceFile, span.start, /*includeJsDocComment*/ false), sourceFile, span);
|
||||
const start = getParentNodeInSpan(getTokenAtPosition(sourceFile, span.start), sourceFile, span);
|
||||
// Do the same for the ending position
|
||||
const end = getParentNodeInSpan(findTokenOnLeftOfPosition(sourceFile, textSpanEnd(span)), sourceFile, span);
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ namespace ts.refactor.generateGetAccessorAndSetAccessor {
|
|||
function getConvertibleFieldAtPosition(context: RefactorContext): Info | undefined {
|
||||
const { file, startPosition, endPosition } = context;
|
||||
|
||||
const node = getTokenAtPosition(file, startPosition, /*includeJsDocComment*/ false);
|
||||
const node = getTokenAtPosition(file, startPosition);
|
||||
const declaration = findAncestor(node.parent, isAcceptedDeclaration);
|
||||
// make sure declaration have AccessibilityModifier or Static Modifier or Readonly Modifier
|
||||
const meaning = ModifierFlags.AccessibilityModifier | ModifierFlags.Static | ModifierFlags.Readonly;
|
||||
|
|
|
@ -261,7 +261,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
public getChildren(): Node[] {
|
||||
return emptyArray;
|
||||
return this.kind === SyntaxKind.EndOfFileToken ? (this as EndOfFileToken).jsDoc || emptyArray : emptyArray;
|
||||
}
|
||||
|
||||
public getFirstToken(): Node | undefined {
|
||||
|
|
|
@ -576,7 +576,7 @@ namespace ts.textChanges {
|
|||
if (index !== containingList.length - 1) {
|
||||
// any element except the last one
|
||||
// use next sibling as an anchor
|
||||
const nextToken = getTokenAtPosition(sourceFile, after.end, /*includeJsDocComment*/ false);
|
||||
const nextToken = getTokenAtPosition(sourceFile, after.end);
|
||||
if (nextToken && isSeparator(after, nextToken)) {
|
||||
// for list
|
||||
// a, b, c
|
||||
|
|
|
@ -665,19 +665,14 @@ namespace ts {
|
|||
}
|
||||
|
||||
/** Returns a token if position is in [start-of-leading-trivia, end) */
|
||||
export function getTokenAtPosition(sourceFile: SourceFile, position: number, includeJsDocComment: boolean, includeEndPosition = false): Node {
|
||||
return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ true, /*includePrecedingTokenAtEndPosition*/ undefined, includeEndPosition, includeJsDocComment);
|
||||
export function getTokenAtPosition(sourceFile: SourceFile, position: number): Node {
|
||||
return getTokenAtPositionWorker(sourceFile, position, /*allowPositionInLeadingTrivia*/ true, /*includePrecedingTokenAtEndPosition*/ undefined, /*includeEndPosition*/ false, /*includeJsDocComment*/ true);
|
||||
}
|
||||
|
||||
/** Get the token whose text contains the position */
|
||||
function getTokenAtPositionWorker(sourceFile: SourceFile, position: number, allowPositionInLeadingTrivia: boolean, includePrecedingTokenAtEndPosition: ((n: Node) => boolean) | undefined, includeEndPosition: boolean, includeJsDocComment: boolean): Node {
|
||||
let current: Node = sourceFile;
|
||||
outer: while (true) {
|
||||
if (isToken(current)) {
|
||||
// exit early
|
||||
return current;
|
||||
}
|
||||
|
||||
// find the child that contains 'position'
|
||||
for (const child of current.getChildren()) {
|
||||
if (!includeJsDocComment && isJSDocNode(child)) {
|
||||
|
@ -718,7 +713,7 @@ namespace ts {
|
|||
export function findTokenOnLeftOfPosition(file: SourceFile, position: number): Node | undefined {
|
||||
// Ideally, getTokenAtPosition should return a token. However, it is currently
|
||||
// broken, so we do a check to make sure the result was indeed a token.
|
||||
const tokenAtPosition = getTokenAtPosition(file, position, /*includeJsDocComment*/ false);
|
||||
const tokenAtPosition = getTokenAtPosition(file, position);
|
||||
if (isToken(tokenAtPosition) && position > tokenAtPosition.getStart(file) && position < tokenAtPosition.getEnd()) {
|
||||
return tokenAtPosition;
|
||||
}
|
||||
|
@ -861,7 +856,7 @@ namespace ts {
|
|||
* returns true if the position is in between the open and close elements of an JSX expression.
|
||||
*/
|
||||
export function isInsideJsxElementOrAttribute(sourceFile: SourceFile, position: number) {
|
||||
const token = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
|
||||
const token = getTokenAtPosition(sourceFile, position);
|
||||
|
||||
if (!token) {
|
||||
return false;
|
||||
|
@ -901,7 +896,7 @@ namespace ts {
|
|||
}
|
||||
|
||||
export function isInTemplateString(sourceFile: SourceFile, position: number) {
|
||||
const token = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
|
||||
const token = getTokenAtPosition(sourceFile, position);
|
||||
return isTemplateLiteralKind(token.kind) && position > token.getStart(sourceFile);
|
||||
}
|
||||
|
||||
|
@ -1037,18 +1032,9 @@ namespace ts {
|
|||
return !!formatting.getRangeOfEnclosingComment(sourceFile, position, /*onlyMultiLine*/ false, /*precedingToken*/ undefined, tokenAtPosition, predicate);
|
||||
}
|
||||
|
||||
export function hasDocComment(sourceFile: SourceFile, position: number) {
|
||||
const token = getTokenAtPosition(sourceFile, position, /*includeJsDocComment*/ false);
|
||||
|
||||
// First, we have to see if this position actually landed in a comment.
|
||||
const commentRanges = getLeadingCommentRanges(sourceFile.text, token.pos);
|
||||
|
||||
return forEach(commentRanges, jsDocPrefix);
|
||||
|
||||
function jsDocPrefix(c: CommentRange): boolean {
|
||||
const text = sourceFile.text;
|
||||
return text.length >= c.pos + 3 && text[c.pos] === "/" && text[c.pos + 1] === "*" && text[c.pos + 2] === "*";
|
||||
}
|
||||
export function hasDocComment(sourceFile: SourceFile, position: number): boolean {
|
||||
const token = getTokenAtPosition(sourceFile, position);
|
||||
return !!findAncestor(token, isJSDoc);
|
||||
}
|
||||
|
||||
function nodeHasTokens(n: Node, sourceFile: SourceFileLike): boolean {
|
||||
|
|
|
@ -261,20 +261,22 @@ namespace ts {
|
|||
});
|
||||
|
||||
describe("tsbuild - downstream prepend projects always get rebuilt", () => {
|
||||
const fs = outFileFs.shadow();
|
||||
const host = new fakes.CompilerHost(fs);
|
||||
const builder = createSolutionBuilder(host, buildHost, ["/src/third"], { dry: false, force: false, verbose: false });
|
||||
clearDiagnostics();
|
||||
builder.buildAllProjects();
|
||||
assertDiagnosticMessages(/*none*/);
|
||||
assert.equal(fs.statSync("src/third/thirdjs/output/third-output.js").mtimeMs, time(), "First build timestamp is correct");
|
||||
tick();
|
||||
replaceText(fs, "src/first/first_PART1.ts", "Hello", "Hola");
|
||||
tick();
|
||||
builder.resetBuildContext();
|
||||
builder.buildAllProjects();
|
||||
assertDiagnosticMessages(/*none*/);
|
||||
assert.equal(fs.statSync("src/third/thirdjs/output/third-output.js").mtimeMs, time(), "Second build timestamp is correct");
|
||||
it("", () => {
|
||||
const fs = outFileFs.shadow();
|
||||
const host = new fakes.CompilerHost(fs);
|
||||
const builder = createSolutionBuilder(host, buildHost, ["/src/third"], { dry: false, force: false, verbose: false });
|
||||
clearDiagnostics();
|
||||
builder.buildAllProjects();
|
||||
assertDiagnosticMessages(/*none*/);
|
||||
assert.equal(fs.statSync("src/third/thirdjs/output/third-output.js").mtimeMs, time(), "First build timestamp is correct");
|
||||
tick();
|
||||
replaceText(fs, "src/first/first_PART1.ts", "Hello", "Hola");
|
||||
tick();
|
||||
builder.resetBuildContext();
|
||||
builder.buildAllProjects();
|
||||
assertDiagnosticMessages(/*none*/);
|
||||
assert.equal(fs.statSync("src/third/thirdjs/output/third-output.js").mtimeMs, time(), "Second build timestamp is correct");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -10743,7 +10743,7 @@ declare namespace ts {
|
|||
*/
|
||||
function getTouchingToken(sourceFile: SourceFile, position: number, includeJsDocComment: boolean, includePrecedingTokenAtEndPosition?: (n: Node) => boolean): Node;
|
||||
/** Returns a token if position is in [start-of-leading-trivia, end) */
|
||||
function getTokenAtPosition(sourceFile: SourceFile, position: number, includeJsDocComment: boolean, includeEndPosition?: boolean): Node;
|
||||
function getTokenAtPosition(sourceFile: SourceFile, position: number): Node;
|
||||
/**
|
||||
* The token on the left of the position is the token that strictly includes the position
|
||||
* or sits to the left of the cursor if it is on a boundary. For example
|
||||
|
@ -10778,7 +10778,7 @@ declare namespace ts {
|
|||
* @param predicate Additional predicate to test on the comment range.
|
||||
*/
|
||||
function isInComment(sourceFile: SourceFile, position: number, tokenAtPosition?: Node, predicate?: (c: CommentRange) => boolean): boolean;
|
||||
function hasDocComment(sourceFile: SourceFile, position: number): boolean | undefined;
|
||||
function hasDocComment(sourceFile: SourceFile, position: number): boolean;
|
||||
function getNodeModifiers(node: Node): string;
|
||||
function getTypeArgumentOrTypeParameterList(node: Node): NodeArray<Node> | undefined;
|
||||
function isComment(kind: SyntaxKind): boolean;
|
||||
|
|
|
@ -19,7 +19,7 @@ var sid = s => s + "!";
|
|||
|
||||
/** @type {NoReturn} */
|
||||
var noreturn = obj => void obj.title
|
||||
>noreturn : (s: { e: number; m: number; title: string; }) => any
|
||||
>noreturn : NoReturn
|
||||
>obj => void obj.title : (obj: { e: number; m: number; title: string; }) => any
|
||||
>obj : { e: number; m: number; title: string; }
|
||||
>void obj.title : undefined
|
||||
|
|
|
@ -42,7 +42,7 @@ var outside = n => n + 1;
|
|||
|
||||
/** @type {Final<{ fantasy }, { heroes }>} */
|
||||
var noreturn = (barts, tidus, noctis) => "cecil"
|
||||
>noreturn : (barts: { fantasy: any; }, tidus: { heroes: any; }, noctis: { heroes: any; } & { fantasy: any; }) => "cecil" | "zidane"
|
||||
>noreturn : Final<{ fantasy: any; }, { heroes: any; }>
|
||||
>(barts, tidus, noctis) => "cecil" : (barts: { fantasy: any; }, tidus: { heroes: any; }, noctis: { heroes: any; } & { fantasy: any; }) => "cecil"
|
||||
>barts : { fantasy: any; }
|
||||
>tidus : { heroes: any; }
|
||||
|
|
Loading…
Reference in a new issue