-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Fixes to @augments handling #18775
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixes to @augments handling #18775
Conversation
f0bedf7
to
e056e83
Compare
src/compiler/checker.ts
Outdated
return; | ||
} | ||
|
||
const name: Identifier = node.class.expression.kind === SyntaxKind.PropertyAccessExpression ? (node.class.expression as PropertyAccessExpression).name : (node.class.expression as Identifier); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Waiting on #18774 to get rid of these casts
e056e83
to
41e239d
Compare
src/compiler/checker.ts
Outdated
} | ||
} | ||
|
||
function getClassName(node: Expression): Identifier | undefined { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels like it already exists. Either way, getClassName
is too vague+specific a name for something that treats an Expression like a QualifiedName
and then gets the identifier at the bottom. getIdentifierFromExpressionAsQualifiedName
? That's horrible in a different way. I'm not sure what the best name is.
src/compiler/utilities.ts
Outdated
@@ -1591,6 +1590,11 @@ namespace ts { | |||
return parameter && parameter.symbol; | |||
} | |||
|
|||
export function getNodeCommentedByJSDocTag(node: JSDocTag): Node { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should really make up a name for "the node that this jsdoc is attached to". Commentee? Given that the parameter name and type could be tag: JSDocTag
, I think getCommentee
would be a fine name, given a good word for "Commentee".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been calling it the "host" node in my internal monologue.
src/compiler/diagnosticMessages.json
Outdated
"category": "Error", | ||
"code": 8022 | ||
}, | ||
"JSDoc '@augments' tag declares to extend '{0}', but actual class augments '{1}'.": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JSDoc '@Augments {0}' does not match the 'extends {1}' clause.
src/compiler/diagnosticMessages.json
Outdated
@@ -3511,6 +3511,14 @@ | |||
"category": "Error", | |||
"code": 8021 | |||
}, | |||
"JSDoc '@augments' tag will be ignored if not attached to a class declaration.": { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
JSDoc '@Augments' tag is not attached to a class declaration.
src/compiler/checker.ts
Outdated
return; | ||
} | ||
|
||
const name = node.class.expression.kind === SyntaxKind.PropertyAccessExpression ? node.class.expression.name : node.class.expression; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why isn't this a call to getClassName
too?
@@ -1856,6 +1856,12 @@ namespace ts { | |||
case CharacterCodes.closeBracket: | |||
pos++; | |||
return token = SyntaxKind.CloseBracketToken; | |||
case CharacterCodes.lessThan: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you make sure that we have some tests that use < and > inside jsdoc comments in various places? it should be allowed everywhere in comment text, especially in misaligned cases like
/**
* @param x hi
< > still part of the previous comment
*/
And of course it should cause error in places like the tag name, etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a test.
@@ -2161,7 +2161,7 @@ namespace ts { | |||
|
|||
export interface JSDocAugmentsTag extends JSDocTag { | |||
kind: SyntaxKind.JSDocAugmentsTag; | |||
typeExpression: JSDocTypeExpression; | |||
class: ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
don't you want a subclass of ExpressionWithTypeArguments that has the override expression: Identifier | PropertyAccessEntityNameExpression
? Seems like intersection would be too permissive.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How is intersection permissive where extends
isn't? Could you give an example?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I forgot that Identifier
is assignable to Expression & Identifier
but (for example) BinaryExpression
isn't. Never mind.
src/compiler/parser.ts
Outdated
return finishNode(result); | ||
} | ||
|
||
function parseValidExpressionWithTypeArguments(): ExpressionWithTypeArguments & { expression: Identifier | PropertyAccessEntityNameExpression } { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this doesn't parse all valid expressions, only PropertyAccessEntityNameExpressions, right? This name is confusing.
ca1bfda
to
171c054
Compare
src/compiler/utilities.ts
Outdated
@@ -1591,6 +1590,11 @@ namespace ts { | |||
return parameter && parameter.symbol; | |||
} | |||
|
|||
export function getJSDocHost(node: JSDocTag): Node { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can have a return type of HasJSDoc
instead of Node
. 😉
@Andy-MS
|
function checkJSDocAugmentsTag(node: JSDocAugmentsTag): void { | ||
const cls = getJSDocHost(node); | ||
if (!isClassDeclaration(cls) && !isClassExpression(cls)) { | ||
error(cls, Diagnostics.JSDoc_augments_is_not_attached_to_a_class_declaration); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this message mention class expressions?
Fixes #18740
We will now get a superclass from
@augments
even if there is noextends
.Allows us to parse
/** @augments A */
without the curly braces, because that seems to be the style.We will no longer parse arbitrary types, only a class (qualified) name followed by type arguments. So you can't declare to inherit from
() => void
without parse errors.Adds errors for:
@augments
tag not on a class@augments A
butextends B