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:
Andy 2018-06-26 16:20:44 -07:00 committed by GitHub
parent f4a2ee456d
commit 13bc46d970
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
44 changed files with 84 additions and 115 deletions

View file

@ -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;
}

View file

@ -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

View file

@ -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);

View file

@ -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);
}

View file

@ -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

View file

@ -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);

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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)

View file

@ -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);
}

View file

@ -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) {

View file

@ -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!);

View file

@ -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;
}

View file

@ -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;

View file

@ -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 };
}

View file

@ -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 [];
}

View file

@ -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) };
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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));

View file

@ -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 });
}

View file

@ -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);

View file

@ -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

View file

@ -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);
});
},
});

View file

@ -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] };

View file

@ -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)) {

View file

@ -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);
}
/**

View file

@ -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;

View file

@ -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;

View file

@ -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) {

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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 {

View file

@ -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

View file

@ -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 {

View file

@ -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");
});
});
}

View file

@ -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;

View file

@ -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

View file

@ -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; }