mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Add typedef declaration space, unify typedef name gathering (#18172)
* Add typedef declaration space, unify typedef name gathering, strengthen errorUnusedLocal * Bonus round: make jsdoc presence way mroe typesafe * Be exhaustive in nameForNamelessJSDocTypedef * Remove nonrequired casts * Replace more casts with guards * Cannot be internal * Debug.fail returns never, assert never no longer needs unreachable throw to satisfy checker * Rename type * Add replacement message as in 18287
This commit is contained in:
+4
-13
@@ -282,17 +282,8 @@ namespace ts {
|
||||
const index = indexOf(functionType.parameters, node);
|
||||
return "arg" + index as __String;
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
const parentNode = node.parent && node.parent.parent;
|
||||
let nameFromParentNode: __String;
|
||||
if (parentNode && parentNode.kind === SyntaxKind.VariableStatement) {
|
||||
if ((<VariableStatement>parentNode).declarationList.declarations.length > 0) {
|
||||
const nameIdentifier = (<VariableStatement>parentNode).declarationList.declarations[0].name;
|
||||
if (isIdentifier(nameIdentifier)) {
|
||||
nameFromParentNode = nameIdentifier.escapedText;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nameFromParentNode;
|
||||
const name = getNameOfJSDocTypedef(node as JSDocTypedefTag);
|
||||
return typeof name !== "undefined" ? name.escapedText : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -598,7 +589,7 @@ namespace ts {
|
||||
// Binding of JsDocComment should be done before the current block scope container changes.
|
||||
// because the scope of JsDocComment should not be affected by whether the current node is a
|
||||
// container or not.
|
||||
if (node.jsDoc) {
|
||||
if (hasJSDocNodes(node)) {
|
||||
if (isInJavaScriptFile(node)) {
|
||||
for (const j of node.jsDoc) {
|
||||
bind(j);
|
||||
@@ -1931,7 +1922,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function bindJSDocTypedefTagIfAny(node: Node) {
|
||||
if (!node.jsDoc) {
|
||||
if (!hasJSDocNodes(node)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -19158,6 +19158,8 @@ namespace ts {
|
||||
switch (d.kind) {
|
||||
case SyntaxKind.InterfaceDeclaration:
|
||||
case SyntaxKind.TypeAliasDeclaration:
|
||||
// A jsdoc typedef is, by definition, a type alias
|
||||
case SyntaxKind.JSDocTypedefTag:
|
||||
return DeclarationSpaces.ExportType;
|
||||
case SyntaxKind.ModuleDeclaration:
|
||||
return isAmbientModule(d) || getModuleInstanceState(d) !== ModuleInstanceState.NonInstantiated
|
||||
@@ -19827,7 +19829,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
else if (compilerOptions.noUnusedLocals) {
|
||||
forEach(local.declarations, d => errorUnusedLocal(getNameOfDeclaration(d) || d, unescapeLeadingUnderscores(local.escapedName)));
|
||||
forEach(local.declarations, d => errorUnusedLocal(d, unescapeLeadingUnderscores(local.escapedName)));
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -19842,7 +19844,8 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function errorUnusedLocal(node: Node, name: string) {
|
||||
function errorUnusedLocal(declaration: Declaration, name: string) {
|
||||
const node = getNameOfDeclaration(declaration) || declaration;
|
||||
if (isIdentifierThatStartsWithUnderScore(node)) {
|
||||
const declaration = getRootDeclaration(node.parent);
|
||||
if (declaration.kind === SyntaxKind.VariableDeclaration && isForInOrOfStatement(declaration.parent.parent)) {
|
||||
@@ -19909,7 +19912,7 @@ namespace ts {
|
||||
if (!local.isReferenced && !local.exportSymbol) {
|
||||
for (const declaration of local.declarations) {
|
||||
if (!isAmbientModule(declaration)) {
|
||||
errorUnusedLocal(getNameOfDeclaration(declaration), unescapeLeadingUnderscores(local.escapedName));
|
||||
errorUnusedLocal(declaration, unescapeLeadingUnderscores(local.escapedName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2441,7 +2441,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
export function fail(message?: string, stackCrawlMark?: Function): void {
|
||||
export function fail(message?: string, stackCrawlMark?: Function): never {
|
||||
debugger;
|
||||
const e = new Error(message ? `Debug Failure. ${message}` : "Debug Failure.");
|
||||
if ((<any>Error).captureStackTrace) {
|
||||
@@ -2450,6 +2450,10 @@ namespace ts {
|
||||
throw e;
|
||||
}
|
||||
|
||||
export function assertNever(member: never, message?: string, stackCrawlMark?: Function): never {
|
||||
return fail(message || `Illegal value: ${member}`, stackCrawlMark || assertNever);
|
||||
}
|
||||
|
||||
export function getFunctionName(func: Function) {
|
||||
if (typeof func !== "function") {
|
||||
return "";
|
||||
|
||||
@@ -729,7 +729,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
|
||||
function addJSDocComment<T extends Node>(node: T): T {
|
||||
function addJSDocComment<T extends HasJSDoc>(node: T): T {
|
||||
const comments = getJSDocCommentRanges(node, sourceFile.text);
|
||||
if (comments) {
|
||||
for (const comment of comments) {
|
||||
@@ -768,7 +768,7 @@ namespace ts {
|
||||
const saveParent = parent;
|
||||
parent = n;
|
||||
forEachChild(n, visitNode);
|
||||
if (n.jsDoc) {
|
||||
if (hasJSDocNodes(n)) {
|
||||
for (const jsDoc of n.jsDoc) {
|
||||
jsDoc.parent = n;
|
||||
parent = jsDoc;
|
||||
@@ -2158,7 +2158,7 @@ namespace ts {
|
||||
const result = <JSDocFunctionType>createNode(SyntaxKind.JSDocFunctionType);
|
||||
nextToken();
|
||||
fillSignature(SyntaxKind.ColonToken, SignatureFlags.Type | SignatureFlags.JSDoc, result);
|
||||
return finishNode(result);
|
||||
return addJSDocComment(finishNode(result));
|
||||
}
|
||||
const node = <TypeReferenceNode>createNode(SyntaxKind.TypeReference);
|
||||
node.typeName = parseIdentifierName();
|
||||
@@ -2365,7 +2365,7 @@ namespace ts {
|
||||
parseSemicolon();
|
||||
}
|
||||
|
||||
function parseSignatureMember(kind: SyntaxKind): CallSignatureDeclaration | ConstructSignatureDeclaration {
|
||||
function parseSignatureMember(kind: SyntaxKind.CallSignature | SyntaxKind.ConstructSignature): CallSignatureDeclaration | ConstructSignatureDeclaration {
|
||||
const node = <CallSignatureDeclaration | ConstructSignatureDeclaration>createNode(kind);
|
||||
if (kind === SyntaxKind.ConstructSignature) {
|
||||
parseExpected(SyntaxKind.NewKeyword);
|
||||
@@ -2445,7 +2445,7 @@ namespace ts {
|
||||
node.parameters = parseBracketedList(ParsingContext.Parameters, parseParameter, SyntaxKind.OpenBracketToken, SyntaxKind.CloseBracketToken);
|
||||
node.type = parseTypeAnnotation();
|
||||
parseTypeMemberSemicolon();
|
||||
return finishNode(node);
|
||||
return addJSDocComment(finishNode(node));
|
||||
}
|
||||
|
||||
function parsePropertyOrMethodSignature(fullStart: number, modifiers: NodeArray<Modifier>): PropertySignature | MethodSignature {
|
||||
@@ -2605,7 +2605,7 @@ namespace ts {
|
||||
parseExpected(SyntaxKind.NewKeyword);
|
||||
}
|
||||
fillSignature(SyntaxKind.EqualsGreaterThanToken, SignatureFlags.Type, node);
|
||||
return finishNode(node);
|
||||
return addJSDocComment(finishNode(node));
|
||||
}
|
||||
|
||||
function parseKeywordAndNoDot(): TypeNode | undefined {
|
||||
@@ -6182,7 +6182,7 @@ namespace ts {
|
||||
return jsDoc ? { jsDoc, diagnostics } : undefined;
|
||||
}
|
||||
|
||||
export function parseJSDocComment(parent: Node, start: number, length: number): JSDoc {
|
||||
export function parseJSDocComment(parent: HasJSDoc, start: number, length: number): JSDoc {
|
||||
const saveToken = currentToken;
|
||||
const saveParseDiagnosticsLength = parseDiagnostics.length;
|
||||
const saveParseErrorBeforeNextFinishedNode = parseErrorBeforeNextFinishedNode;
|
||||
@@ -6997,7 +6997,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
forEachChild(node, visitNode, visitArray);
|
||||
if (node.jsDoc) {
|
||||
if (hasJSDocNodes(node)) {
|
||||
for (const jsDocComment of node.jsDoc) {
|
||||
forEachChild(jsDocComment, visitNode, visitArray);
|
||||
}
|
||||
|
||||
+92
-51
@@ -516,8 +516,6 @@ namespace ts {
|
||||
parent?: Node; // Parent node (initialized by binding)
|
||||
/* @internal */ original?: Node; // The original node if this is an updated node.
|
||||
/* @internal */ startsOnNewLine?: boolean; // Whether a synthesized node should start on a new line (used by transforms).
|
||||
/* @internal */ jsDoc?: JSDoc[]; // JSDoc that directly precedes this node
|
||||
/* @internal */ jsDocCache?: ReadonlyArray<JSDocTag>; // Cache for getJSDocTags
|
||||
/* @internal */ symbol?: Symbol; // Symbol declared by node (initialized by binding)
|
||||
/* @internal */ locals?: SymbolTable; // Locals associated with node (initialized by binding)
|
||||
/* @internal */ nextContainer?: Node; // Next container in declaration order (initialized by binding)
|
||||
@@ -528,6 +526,44 @@ namespace ts {
|
||||
/* @internal */ contextualMapper?: TypeMapper; // Mapper for contextual type
|
||||
}
|
||||
|
||||
export interface JSDocContainer {
|
||||
/* @internal */ jsDoc?: JSDoc[]; // JSDoc that directly precedes this node
|
||||
/* @internal */ jsDocCache?: ReadonlyArray<JSDocTag>; // Cache for getJSDocTags
|
||||
}
|
||||
|
||||
export type HasJSDoc =
|
||||
| ParameterDeclaration
|
||||
| CallSignatureDeclaration
|
||||
| ConstructSignatureDeclaration
|
||||
| MethodSignature
|
||||
| PropertySignature
|
||||
| ArrowFunction
|
||||
| ParenthesizedExpression
|
||||
| SpreadAssignment
|
||||
| ShorthandPropertyAssignment
|
||||
| PropertyAssignment
|
||||
| FunctionExpression
|
||||
| LabeledStatement
|
||||
| ExpressionStatement
|
||||
| VariableStatement
|
||||
| FunctionDeclaration
|
||||
| ConstructorDeclaration
|
||||
| MethodDeclaration
|
||||
| PropertyDeclaration
|
||||
| AccessorDeclaration
|
||||
| ClassLikeDeclaration
|
||||
| InterfaceDeclaration
|
||||
| TypeAliasDeclaration
|
||||
| EnumMember
|
||||
| EnumDeclaration
|
||||
| ModuleDeclaration
|
||||
| ImportEqualsDeclaration
|
||||
| IndexSignatureDeclaration
|
||||
| FunctionTypeNode
|
||||
| ConstructorTypeNode
|
||||
| JSDocFunctionType
|
||||
| EndOfFileToken;
|
||||
|
||||
/* @internal */
|
||||
export type MutableNodeArray<T extends Node> = NodeArray<T> & T[];
|
||||
|
||||
@@ -546,7 +582,7 @@ namespace ts {
|
||||
export type EqualsToken = Token<SyntaxKind.EqualsToken>;
|
||||
export type AsteriskToken = Token<SyntaxKind.AsteriskToken>;
|
||||
export type EqualsGreaterThanToken = Token<SyntaxKind.EqualsGreaterThanToken>;
|
||||
export type EndOfFileToken = Token<SyntaxKind.EndOfFileToken>;
|
||||
export type EndOfFileToken = Token<SyntaxKind.EndOfFileToken> & JSDocContainer;
|
||||
export type AtToken = Token<SyntaxKind.AtToken>;
|
||||
export type ReadonlyToken = Token<SyntaxKind.ReadonlyKeyword>;
|
||||
export type AwaitKeywordToken = Token<SyntaxKind.AwaitKeyword>;
|
||||
@@ -651,32 +687,34 @@ namespace ts {
|
||||
expression?: Expression;
|
||||
}
|
||||
|
||||
export interface SignatureDeclaration extends NamedDeclaration {
|
||||
kind: SyntaxKind.CallSignature
|
||||
| SyntaxKind.ConstructSignature
|
||||
| SyntaxKind.MethodSignature
|
||||
| SyntaxKind.IndexSignature
|
||||
| SyntaxKind.FunctionType
|
||||
| SyntaxKind.ConstructorType
|
||||
| SyntaxKind.JSDocFunctionType
|
||||
| SyntaxKind.FunctionDeclaration
|
||||
| SyntaxKind.MethodDeclaration
|
||||
| SyntaxKind.Constructor
|
||||
| SyntaxKind.GetAccessor
|
||||
| SyntaxKind.SetAccessor
|
||||
| SyntaxKind.FunctionExpression
|
||||
| SyntaxKind.ArrowFunction;
|
||||
export interface SignatureDeclarationBase extends NamedDeclaration, JSDocContainer {
|
||||
kind: SignatureDeclaration["kind"];
|
||||
name?: PropertyName;
|
||||
typeParameters?: NodeArray<TypeParameterDeclaration>;
|
||||
parameters: NodeArray<ParameterDeclaration>;
|
||||
type: TypeNode | undefined;
|
||||
}
|
||||
|
||||
export interface CallSignatureDeclaration extends SignatureDeclaration, TypeElement {
|
||||
export type SignatureDeclaration =
|
||||
| CallSignatureDeclaration
|
||||
| ConstructSignatureDeclaration
|
||||
| MethodSignature
|
||||
| IndexSignatureDeclaration
|
||||
| FunctionTypeNode
|
||||
| ConstructorTypeNode
|
||||
| JSDocFunctionType
|
||||
| FunctionDeclaration
|
||||
| MethodDeclaration
|
||||
| ConstructorDeclaration
|
||||
| AccessorDeclaration
|
||||
| FunctionExpression
|
||||
| ArrowFunction;
|
||||
|
||||
export interface CallSignatureDeclaration extends SignatureDeclarationBase, TypeElement {
|
||||
kind: SyntaxKind.CallSignature;
|
||||
}
|
||||
|
||||
export interface ConstructSignatureDeclaration extends SignatureDeclaration, TypeElement {
|
||||
export interface ConstructSignatureDeclaration extends SignatureDeclarationBase, TypeElement {
|
||||
kind: SyntaxKind.ConstructSignature;
|
||||
}
|
||||
|
||||
@@ -696,7 +734,7 @@ namespace ts {
|
||||
declarations: NodeArray<VariableDeclaration>;
|
||||
}
|
||||
|
||||
export interface ParameterDeclaration extends NamedDeclaration {
|
||||
export interface ParameterDeclaration extends NamedDeclaration, JSDocContainer {
|
||||
kind: SyntaxKind.Parameter;
|
||||
parent?: SignatureDeclaration;
|
||||
dotDotDotToken?: DotDotDotToken; // Present on rest parameter
|
||||
@@ -715,7 +753,7 @@ namespace ts {
|
||||
initializer?: Expression; // Optional initializer
|
||||
}
|
||||
|
||||
export interface PropertySignature extends TypeElement {
|
||||
export interface PropertySignature extends TypeElement, JSDocContainer {
|
||||
kind: SyntaxKind.PropertySignature;
|
||||
name: PropertyName; // Declared property name
|
||||
questionToken?: QuestionToken; // Present on optional property
|
||||
@@ -723,7 +761,7 @@ namespace ts {
|
||||
initializer?: Expression; // Optional initializer
|
||||
}
|
||||
|
||||
export interface PropertyDeclaration extends ClassElement {
|
||||
export interface PropertyDeclaration extends ClassElement, JSDocContainer {
|
||||
kind: SyntaxKind.PropertyDeclaration;
|
||||
questionToken?: QuestionToken; // Present for use with reporting a grammar error
|
||||
name: PropertyName;
|
||||
@@ -744,7 +782,7 @@ namespace ts {
|
||||
| AccessorDeclaration
|
||||
;
|
||||
|
||||
export interface PropertyAssignment extends ObjectLiteralElement {
|
||||
export interface PropertyAssignment extends ObjectLiteralElement, JSDocContainer {
|
||||
parent: ObjectLiteralExpression;
|
||||
kind: SyntaxKind.PropertyAssignment;
|
||||
name: PropertyName;
|
||||
@@ -752,7 +790,7 @@ namespace ts {
|
||||
initializer: Expression;
|
||||
}
|
||||
|
||||
export interface ShorthandPropertyAssignment extends ObjectLiteralElement {
|
||||
export interface ShorthandPropertyAssignment extends ObjectLiteralElement, JSDocContainer {
|
||||
parent: ObjectLiteralExpression;
|
||||
kind: SyntaxKind.ShorthandPropertyAssignment;
|
||||
name: Identifier;
|
||||
@@ -763,7 +801,7 @@ namespace ts {
|
||||
objectAssignmentInitializer?: Expression;
|
||||
}
|
||||
|
||||
export interface SpreadAssignment extends ObjectLiteralElement {
|
||||
export interface SpreadAssignment extends ObjectLiteralElement, JSDocContainer {
|
||||
parent: ObjectLiteralExpression;
|
||||
kind: SyntaxKind.SpreadAssignment;
|
||||
expression: Expression;
|
||||
@@ -816,7 +854,7 @@ namespace ts {
|
||||
* - MethodDeclaration
|
||||
* - AccessorDeclaration
|
||||
*/
|
||||
export interface FunctionLikeDeclarationBase extends SignatureDeclaration {
|
||||
export interface FunctionLikeDeclarationBase extends SignatureDeclarationBase {
|
||||
_functionLikeDeclarationBrand: any;
|
||||
|
||||
asteriskToken?: AsteriskToken;
|
||||
@@ -847,7 +885,7 @@ namespace ts {
|
||||
body?: FunctionBody;
|
||||
}
|
||||
|
||||
export interface MethodSignature extends SignatureDeclaration, TypeElement {
|
||||
export interface MethodSignature extends SignatureDeclarationBase, TypeElement {
|
||||
kind: SyntaxKind.MethodSignature;
|
||||
name: PropertyName;
|
||||
}
|
||||
@@ -861,13 +899,13 @@ namespace ts {
|
||||
// Because of this, it may be necessary to determine what sort of MethodDeclaration you have
|
||||
// at later stages of the compiler pipeline. In that case, you can either check the parent kind
|
||||
// of the method, or use helpers like isObjectLiteralMethodDeclaration
|
||||
export interface MethodDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement {
|
||||
export interface MethodDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer {
|
||||
kind: SyntaxKind.MethodDeclaration;
|
||||
name: PropertyName;
|
||||
body?: FunctionBody;
|
||||
}
|
||||
|
||||
export interface ConstructorDeclaration extends FunctionLikeDeclarationBase, ClassElement {
|
||||
export interface ConstructorDeclaration extends FunctionLikeDeclarationBase, ClassElement, JSDocContainer {
|
||||
kind: SyntaxKind.Constructor;
|
||||
parent?: ClassDeclaration | ClassExpression;
|
||||
body?: FunctionBody;
|
||||
@@ -881,7 +919,7 @@ namespace ts {
|
||||
|
||||
// See the comment on MethodDeclaration for the intuition behind GetAccessorDeclaration being a
|
||||
// ClassElement and an ObjectLiteralElement.
|
||||
export interface GetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement {
|
||||
export interface GetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer {
|
||||
kind: SyntaxKind.GetAccessor;
|
||||
parent?: ClassDeclaration | ClassExpression | ObjectLiteralExpression;
|
||||
name: PropertyName;
|
||||
@@ -890,7 +928,7 @@ namespace ts {
|
||||
|
||||
// See the comment on MethodDeclaration for the intuition behind SetAccessorDeclaration being a
|
||||
// ClassElement and an ObjectLiteralElement.
|
||||
export interface SetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement {
|
||||
export interface SetAccessorDeclaration extends FunctionLikeDeclarationBase, ClassElement, ObjectLiteralElement, JSDocContainer {
|
||||
kind: SyntaxKind.SetAccessor;
|
||||
parent?: ClassDeclaration | ClassExpression | ObjectLiteralExpression;
|
||||
name: PropertyName;
|
||||
@@ -899,7 +937,7 @@ namespace ts {
|
||||
|
||||
export type AccessorDeclaration = GetAccessorDeclaration | SetAccessorDeclaration;
|
||||
|
||||
export interface IndexSignatureDeclaration extends SignatureDeclaration, ClassElement, TypeElement {
|
||||
export interface IndexSignatureDeclaration extends SignatureDeclarationBase, ClassElement, TypeElement {
|
||||
kind: SyntaxKind.IndexSignature;
|
||||
parent?: ClassDeclaration | ClassExpression | InterfaceDeclaration | TypeLiteralNode;
|
||||
}
|
||||
@@ -928,11 +966,11 @@ namespace ts {
|
||||
|
||||
export type FunctionOrConstructorTypeNode = FunctionTypeNode | ConstructorTypeNode;
|
||||
|
||||
export interface FunctionTypeNode extends TypeNode, SignatureDeclaration {
|
||||
export interface FunctionTypeNode extends TypeNode, SignatureDeclarationBase {
|
||||
kind: SyntaxKind.FunctionType;
|
||||
}
|
||||
|
||||
export interface ConstructorTypeNode extends TypeNode, SignatureDeclaration {
|
||||
export interface ConstructorTypeNode extends TypeNode, SignatureDeclarationBase {
|
||||
kind: SyntaxKind.ConstructorType;
|
||||
}
|
||||
|
||||
@@ -1355,13 +1393,13 @@ namespace ts {
|
||||
export type FunctionBody = Block;
|
||||
export type ConciseBody = FunctionBody | Expression;
|
||||
|
||||
export interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclarationBase {
|
||||
export interface FunctionExpression extends PrimaryExpression, FunctionLikeDeclarationBase, JSDocContainer {
|
||||
kind: SyntaxKind.FunctionExpression;
|
||||
name?: Identifier;
|
||||
body: FunctionBody; // Required, whereas the member inherited from FunctionDeclaration is optional
|
||||
}
|
||||
|
||||
export interface ArrowFunction extends Expression, FunctionLikeDeclarationBase {
|
||||
export interface ArrowFunction extends Expression, FunctionLikeDeclarationBase, JSDocContainer {
|
||||
kind: SyntaxKind.ArrowFunction;
|
||||
equalsGreaterThanToken: EqualsGreaterThanToken;
|
||||
body: ConciseBody;
|
||||
@@ -1440,7 +1478,7 @@ namespace ts {
|
||||
literal: TemplateMiddle | TemplateTail;
|
||||
}
|
||||
|
||||
export interface ParenthesizedExpression extends PrimaryExpression {
|
||||
export interface ParenthesizedExpression extends PrimaryExpression, JSDocContainer {
|
||||
kind: SyntaxKind.ParenthesizedExpression;
|
||||
expression: Expression;
|
||||
}
|
||||
@@ -1696,12 +1734,12 @@ namespace ts {
|
||||
/*@internal*/ multiLine?: boolean;
|
||||
}
|
||||
|
||||
export interface VariableStatement extends Statement {
|
||||
export interface VariableStatement extends Statement, JSDocContainer {
|
||||
kind: SyntaxKind.VariableStatement;
|
||||
declarationList: VariableDeclarationList;
|
||||
}
|
||||
|
||||
export interface ExpressionStatement extends Statement {
|
||||
export interface ExpressionStatement extends Statement, JSDocContainer {
|
||||
kind: SyntaxKind.ExpressionStatement;
|
||||
expression: Expression;
|
||||
}
|
||||
@@ -1807,7 +1845,7 @@ namespace ts {
|
||||
|
||||
export type CaseOrDefaultClause = CaseClause | DefaultClause;
|
||||
|
||||
export interface LabeledStatement extends Statement {
|
||||
export interface LabeledStatement extends Statement, JSDocContainer {
|
||||
kind: SyntaxKind.LabeledStatement;
|
||||
label: Identifier;
|
||||
statement: Statement;
|
||||
@@ -1834,7 +1872,7 @@ namespace ts {
|
||||
|
||||
export type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag;
|
||||
|
||||
export interface ClassLikeDeclaration extends NamedDeclaration {
|
||||
export interface ClassLikeDeclarationBase extends NamedDeclaration, JSDocContainer {
|
||||
kind: SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression;
|
||||
name?: Identifier;
|
||||
typeParameters?: NodeArray<TypeParameterDeclaration>;
|
||||
@@ -1842,15 +1880,17 @@ namespace ts {
|
||||
members: NodeArray<ClassElement>;
|
||||
}
|
||||
|
||||
export interface ClassDeclaration extends ClassLikeDeclaration, DeclarationStatement {
|
||||
export interface ClassDeclaration extends ClassLikeDeclarationBase, DeclarationStatement {
|
||||
kind: SyntaxKind.ClassDeclaration;
|
||||
name?: Identifier;
|
||||
}
|
||||
|
||||
export interface ClassExpression extends ClassLikeDeclaration, PrimaryExpression {
|
||||
export interface ClassExpression extends ClassLikeDeclarationBase, PrimaryExpression {
|
||||
kind: SyntaxKind.ClassExpression;
|
||||
}
|
||||
|
||||
export type ClassLikeDeclaration = ClassDeclaration | ClassExpression;
|
||||
|
||||
export interface ClassElement extends NamedDeclaration {
|
||||
_classElementBrand: any;
|
||||
name?: PropertyName;
|
||||
@@ -1862,7 +1902,7 @@ namespace ts {
|
||||
questionToken?: QuestionToken;
|
||||
}
|
||||
|
||||
export interface InterfaceDeclaration extends DeclarationStatement {
|
||||
export interface InterfaceDeclaration extends DeclarationStatement, JSDocContainer {
|
||||
kind: SyntaxKind.InterfaceDeclaration;
|
||||
name: Identifier;
|
||||
typeParameters?: NodeArray<TypeParameterDeclaration>;
|
||||
@@ -1877,14 +1917,14 @@ namespace ts {
|
||||
types: NodeArray<ExpressionWithTypeArguments>;
|
||||
}
|
||||
|
||||
export interface TypeAliasDeclaration extends DeclarationStatement {
|
||||
export interface TypeAliasDeclaration extends DeclarationStatement, JSDocContainer {
|
||||
kind: SyntaxKind.TypeAliasDeclaration;
|
||||
name: Identifier;
|
||||
typeParameters?: NodeArray<TypeParameterDeclaration>;
|
||||
type: TypeNode;
|
||||
}
|
||||
|
||||
export interface EnumMember extends NamedDeclaration {
|
||||
export interface EnumMember extends NamedDeclaration, JSDocContainer {
|
||||
kind: SyntaxKind.EnumMember;
|
||||
parent?: EnumDeclaration;
|
||||
// This does include ComputedPropertyName, but the parser will give an error
|
||||
@@ -1893,7 +1933,7 @@ namespace ts {
|
||||
initializer?: Expression;
|
||||
}
|
||||
|
||||
export interface EnumDeclaration extends DeclarationStatement {
|
||||
export interface EnumDeclaration extends DeclarationStatement, JSDocContainer {
|
||||
kind: SyntaxKind.EnumDeclaration;
|
||||
name: Identifier;
|
||||
members: NodeArray<EnumMember>;
|
||||
@@ -1903,7 +1943,7 @@ namespace ts {
|
||||
|
||||
export type ModuleBody = NamespaceBody | JSDocNamespaceBody;
|
||||
|
||||
export interface ModuleDeclaration extends DeclarationStatement {
|
||||
export interface ModuleDeclaration extends DeclarationStatement, JSDocContainer {
|
||||
kind: SyntaxKind.ModuleDeclaration;
|
||||
parent?: ModuleBody | SourceFile;
|
||||
name: ModuleName;
|
||||
@@ -1937,7 +1977,7 @@ namespace ts {
|
||||
* - import x = require("mod");
|
||||
* - import x = M.x;
|
||||
*/
|
||||
export interface ImportEqualsDeclaration extends DeclarationStatement {
|
||||
export interface ImportEqualsDeclaration extends DeclarationStatement, JSDocContainer {
|
||||
kind: SyntaxKind.ImportEqualsDeclaration;
|
||||
parent?: SourceFile | ModuleBlock;
|
||||
name: Identifier;
|
||||
@@ -2090,7 +2130,7 @@ namespace ts {
|
||||
type: TypeNode;
|
||||
}
|
||||
|
||||
export interface JSDocFunctionType extends JSDocType, SignatureDeclaration {
|
||||
export interface JSDocFunctionType extends JSDocType, SignatureDeclarationBase {
|
||||
kind: SyntaxKind.JSDocFunctionType;
|
||||
}
|
||||
|
||||
@@ -2103,6 +2143,7 @@ namespace ts {
|
||||
|
||||
export interface JSDoc extends Node {
|
||||
kind: SyntaxKind.JSDocComment;
|
||||
parent?: HasJSDoc;
|
||||
tags: NodeArray<JSDocTag> | undefined;
|
||||
comment: string | undefined;
|
||||
}
|
||||
|
||||
@@ -277,7 +277,7 @@ namespace ts {
|
||||
return skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos, /*stopAfterLineBreak*/ false, /*stopAtComments*/ true);
|
||||
}
|
||||
|
||||
if (includeJsDoc && node.jsDoc && node.jsDoc.length > 0) {
|
||||
if (includeJsDoc && hasJSDocNodes(node)) {
|
||||
return getTokenPosOfNode(node.jsDoc[0]);
|
||||
}
|
||||
|
||||
@@ -1510,10 +1510,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
export function getJSDocTags(node: Node): ReadonlyArray<JSDocTag> | undefined {
|
||||
let tags = node.jsDocCache;
|
||||
let tags = (node as JSDocContainer).jsDocCache;
|
||||
// If cache is 'null', that means we did the work of searching for JSDoc tags and came up with nothing.
|
||||
if (tags === undefined) {
|
||||
node.jsDocCache = tags = flatMap(getJSDocCommentsAndTags(node), j => isJSDoc(j) ? j.tags : j);
|
||||
(node as JSDocContainer).jsDocCache = tags = flatMap(getJSDocCommentsAndTags(node), j => isJSDoc(j) ? j.tags : j);
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
@@ -1567,11 +1567,13 @@ namespace ts {
|
||||
result = addRange(result, getJSDocParameterTags(node as ParameterDeclaration));
|
||||
}
|
||||
|
||||
if (isVariableLike(node) && node.initializer) {
|
||||
if (isVariableLike(node) && node.initializer && hasJSDocNodes(node.initializer)) {
|
||||
result = addRange(result, node.initializer.jsDoc);
|
||||
}
|
||||
|
||||
result = addRange(result, node.jsDoc);
|
||||
if (hasJSDocNodes(node)) {
|
||||
result = addRange(result, node.jsDoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3958,7 +3960,66 @@ namespace ts {
|
||||
return id;
|
||||
}
|
||||
|
||||
export function getNameOfDeclaration(declaration: Declaration): DeclarationName | undefined {
|
||||
/**
|
||||
* A JSDocTypedef tag has an _optional_ name field - if a name is not directly present, we should
|
||||
* attempt to draw the name from the node the declaration is on (as that declaration is what its' symbol
|
||||
* will be merged with)
|
||||
*/
|
||||
function nameForNamelessJSDocTypedef(declaration: JSDocTypedefTag): Identifier | undefined {
|
||||
const hostNode = declaration.parent.parent;
|
||||
if (!hostNode) {
|
||||
return undefined;
|
||||
}
|
||||
// Covers classes, functions - any named declaration host node
|
||||
if (isDeclaration(hostNode)) {
|
||||
return getDeclarationIdentifier(hostNode);
|
||||
}
|
||||
// Covers remaining cases
|
||||
switch (hostNode.kind) {
|
||||
case SyntaxKind.VariableStatement:
|
||||
if ((hostNode as VariableStatement).declarationList &&
|
||||
(hostNode as VariableStatement).declarationList.declarations[0]) {
|
||||
return getDeclarationIdentifier((hostNode as VariableStatement).declarationList.declarations[0]);
|
||||
}
|
||||
return undefined;
|
||||
case SyntaxKind.ExpressionStatement:
|
||||
const expr = (hostNode as ExpressionStatement).expression;
|
||||
switch (expr.kind) {
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
return (expr as PropertyAccessExpression).name;
|
||||
case SyntaxKind.ElementAccessExpression:
|
||||
const arg = (expr as ElementAccessExpression).argumentExpression;
|
||||
if (isIdentifier(arg)) {
|
||||
return arg;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
case SyntaxKind.EndOfFileToken:
|
||||
return undefined;
|
||||
case SyntaxKind.ParenthesizedExpression: {
|
||||
return getDeclarationIdentifier(hostNode.expression);
|
||||
}
|
||||
case SyntaxKind.LabeledStatement: {
|
||||
if (isDeclaration(hostNode.statement) || isExpression(hostNode.statement)) {
|
||||
return getDeclarationIdentifier(hostNode.statement);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
default:
|
||||
Debug.assertNever(hostNode, "Found typedef tag attached to node which it should not be!");
|
||||
}
|
||||
}
|
||||
|
||||
function getDeclarationIdentifier(node: Declaration | Expression) {
|
||||
const name = getNameOfDeclaration(node);
|
||||
return isIdentifier(name) ? name : undefined;
|
||||
}
|
||||
|
||||
export function getNameOfJSDocTypedef(declaration: JSDocTypedefTag): Identifier | undefined {
|
||||
return declaration.name || nameForNamelessJSDocTypedef(declaration as JSDocTypedefTag);
|
||||
}
|
||||
|
||||
export function getNameOfDeclaration(declaration: Declaration | Expression): DeclarationName | undefined {
|
||||
if (!declaration) {
|
||||
return undefined;
|
||||
}
|
||||
@@ -3977,6 +4038,9 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
else if (declaration.kind === SyntaxKind.JSDocTypedefTag) {
|
||||
return getNameOfJSDocTypedef(declaration as JSDocTypedefTag);
|
||||
}
|
||||
else {
|
||||
return (declaration as NamedDeclaration).name;
|
||||
}
|
||||
@@ -5365,4 +5429,10 @@ namespace ts {
|
||||
export function isJSDocTag(node: Node): boolean {
|
||||
return node.kind >= SyntaxKind.FirstJSDocTagNode && node.kind <= SyntaxKind.LastJSDocTagNode;
|
||||
}
|
||||
|
||||
/** True if has jsdoc nodes attached to it. */
|
||||
/* @internal */
|
||||
export function hasJSDocNodes(node: Node): node is HasJSDoc {
|
||||
return !!(node as JSDocContainer).jsDoc && (node as JSDocContainer).jsDoc.length > 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -699,7 +699,8 @@ namespace ts {
|
||||
// specially.
|
||||
const docCommentAndDiagnostics = parseIsolatedJSDocComment(sourceFile.text, start, width);
|
||||
if (docCommentAndDiagnostics && docCommentAndDiagnostics.jsDoc) {
|
||||
docCommentAndDiagnostics.jsDoc.parent = token;
|
||||
// TODO: This should be predicated on `token["kind"]` being compatible with `HasJSDoc["kind"]`
|
||||
docCommentAndDiagnostics.jsDoc.parent = token as HasJSDoc;
|
||||
classifyJSDocComment(docCommentAndDiagnostics.jsDoc);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1739,7 +1739,7 @@ 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);
|
||||
const { jsDoc } = getJsDocHavingNode(node) as JSDocContainer;
|
||||
if (!jsDoc) return undefined;
|
||||
|
||||
for (const { pos, end, tags } of jsDoc) {
|
||||
|
||||
@@ -263,13 +263,15 @@ namespace ts.NavigationBar {
|
||||
break;
|
||||
|
||||
default:
|
||||
forEach(node.jsDoc, jsDoc => {
|
||||
forEach(jsDoc.tags, tag => {
|
||||
if (tag.kind === SyntaxKind.JSDocTypedefTag) {
|
||||
addLeafNode(tag);
|
||||
}
|
||||
if (hasJSDocNodes(node)) {
|
||||
forEach(node.jsDoc, jsDoc => {
|
||||
forEach(jsDoc.tags, tag => {
|
||||
if (tag.kind === SyntaxKind.JSDocTypedefTag) {
|
||||
addLeafNode(tag);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
forEachChild(node, addChildrenRecursively);
|
||||
}
|
||||
|
||||
@@ -2111,7 +2111,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
forEachChild(node, walk);
|
||||
if (node.jsDoc) {
|
||||
if (hasJSDocNodes(node)) {
|
||||
for (const jsDoc of node.jsDoc) {
|
||||
forEachChild(jsDoc, walk);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
//// [export.js]
|
||||
/**
|
||||
* @typedef {{
|
||||
* }}
|
||||
*/
|
||||
export const foo = 5;
|
||||
|
||||
//// [export.js]
|
||||
/**
|
||||
* @typedef {{
|
||||
* }}
|
||||
*/
|
||||
export const foo = 5;
|
||||
@@ -0,0 +1,8 @@
|
||||
=== tests/cases/compiler/export.js ===
|
||||
/**
|
||||
* @typedef {{
|
||||
* }}
|
||||
*/
|
||||
export const foo = 5;
|
||||
>foo : Symbol(foo, Decl(export.js, 4, 12))
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
=== tests/cases/compiler/export.js ===
|
||||
/**
|
||||
* @typedef {{
|
||||
* }}
|
||||
*/
|
||||
export const foo = 5;
|
||||
>foo : 5
|
||||
>5 : 5
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
tests/cases/compiler/export.js(1,13): error TS8008: 'type aliases' can only be used in a .ts file.
|
||||
|
||||
|
||||
==== tests/cases/compiler/export.js (1 errors) ====
|
||||
export type foo = 5;
|
||||
~~~
|
||||
!!! error TS8008: 'type aliases' can only be used in a .ts file.
|
||||
/**
|
||||
* @typedef {{
|
||||
* }}
|
||||
*/
|
||||
export const foo = 5;
|
||||
@@ -0,0 +1,14 @@
|
||||
//// [export.js]
|
||||
export type foo = 5;
|
||||
/**
|
||||
* @typedef {{
|
||||
* }}
|
||||
*/
|
||||
export const foo = 5;
|
||||
|
||||
//// [export.js]
|
||||
/**
|
||||
* @typedef {{
|
||||
* }}
|
||||
*/
|
||||
export const foo = 5;
|
||||
@@ -0,0 +1,9 @@
|
||||
// @target: es6
|
||||
// @allowJs: true
|
||||
// @outDir: ./dist
|
||||
// @filename: export.js
|
||||
/**
|
||||
* @typedef {{
|
||||
* }}
|
||||
*/
|
||||
export const foo = 5;
|
||||
@@ -0,0 +1,11 @@
|
||||
// @target: es6
|
||||
// @allowJs: true
|
||||
// @outDir: ./dist
|
||||
// @filename: export.js
|
||||
|
||||
export type foo = 5;
|
||||
/**
|
||||
* @typedef {{
|
||||
* }}
|
||||
*/
|
||||
export const foo = 5;
|
||||
Reference in New Issue
Block a user