mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-15 21:36:50 -05:00
Fix name resolution in typedef and allow defaults for template tags (#45483)
* Fix name resolution in typedef and allow defaults for template tags * Inline parseBracketNameInTemplateTag * Update baselines * Add js declaration emit tests
This commit is contained in:
@@ -3388,7 +3388,7 @@ namespace ts {
|
||||
|
||||
function bindTypeParameter(node: TypeParameterDeclaration) {
|
||||
if (isJSDocTemplateTag(node.parent)) {
|
||||
const container = find((node.parent.parent as JSDoc).tags!, isJSDocTypeAlias) || getHostSignatureFromJSDoc(node.parent); // TODO: GH#18217
|
||||
const container = getEffectiveContainerForJSDocTemplateTag(node.parent);
|
||||
if (container) {
|
||||
if (!container.locals) {
|
||||
container.locals = createSymbolTable();
|
||||
|
||||
@@ -2052,7 +2052,9 @@ namespace ts {
|
||||
lastSelfReferenceLocation = location;
|
||||
}
|
||||
lastLocation = location;
|
||||
location = location.parent;
|
||||
location = isJSDocTemplateTag(location) ?
|
||||
getEffectiveContainerForJSDocTemplateTag(location) || location.parent :
|
||||
location.parent;
|
||||
}
|
||||
|
||||
// We just climbed up parents looking for the name, meaning that we started in a descendant node of `lastLocation`.
|
||||
@@ -12901,7 +12903,7 @@ namespace ts {
|
||||
|
||||
function getParentSymbolOfTypeParameter(typeParameter: TypeParameter): Symbol | undefined {
|
||||
const tp = getDeclarationOfKind<TypeParameterDeclaration>(typeParameter.symbol, SyntaxKind.TypeParameter)!;
|
||||
const host = isJSDocTemplateTag(tp.parent) ? getHostSignatureFromJSDoc(tp.parent) : tp.parent;
|
||||
const host = isJSDocTemplateTag(tp.parent) ? getEffectiveContainerForJSDocTemplateTag(tp.parent) : tp.parent;
|
||||
return host && getSymbolOfNode(host);
|
||||
}
|
||||
|
||||
@@ -33673,7 +33675,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
checkTypeParameters(node.typeParameters);
|
||||
checkTypeParameters(getEffectiveTypeParameterDeclarations(node));
|
||||
|
||||
forEach(node.parameters, checkParameter);
|
||||
|
||||
@@ -35306,6 +35308,7 @@ namespace ts {
|
||||
checkTypeNameIsReserved(node.name, Diagnostics.Type_alias_name_cannot_be_0);
|
||||
}
|
||||
checkSourceElement(node.typeExpression);
|
||||
checkTypeParameters(getEffectiveTypeParameterDeclarations(node));
|
||||
}
|
||||
|
||||
function checkJSDocTemplateTag(node: JSDocTemplateTag): void {
|
||||
|
||||
@@ -8441,11 +8441,24 @@ namespace ts {
|
||||
|
||||
function parseTemplateTagTypeParameter() {
|
||||
const typeParameterPos = getNodePos();
|
||||
const isBracketed = parseOptionalJsdoc(SyntaxKind.OpenBracketToken);
|
||||
if (isBracketed) {
|
||||
skipWhitespace();
|
||||
}
|
||||
const name = parseJSDocIdentifierName(Diagnostics.Unexpected_token_A_type_parameter_name_was_expected_without_curly_braces);
|
||||
|
||||
let defaultType: TypeNode | undefined;
|
||||
if (isBracketed) {
|
||||
skipWhitespace();
|
||||
parseExpected(SyntaxKind.EqualsToken);
|
||||
defaultType = doInsideOfContext(NodeFlags.JSDoc, parseJSDocType);
|
||||
parseExpected(SyntaxKind.CloseBracketToken);
|
||||
}
|
||||
|
||||
if (nodeIsMissing(name)) {
|
||||
return undefined;
|
||||
}
|
||||
return finishNode(factory.createTypeParameterDeclaration(name, /*constraint*/ undefined, /*defaultType*/ undefined), typeParameterPos);
|
||||
return finishNode(factory.createTypeParameterDeclaration(name, /*constraint*/ undefined, defaultType), typeParameterPos);
|
||||
}
|
||||
|
||||
function parseTemplateTagTypeParameters() {
|
||||
|
||||
@@ -2723,6 +2723,18 @@ namespace ts {
|
||||
return parameter && parameter.symbol;
|
||||
}
|
||||
|
||||
export function getEffectiveContainerForJSDocTemplateTag(node: JSDocTemplateTag) {
|
||||
if (isJSDoc(node.parent) && node.parent.tags) {
|
||||
// A @template tag belongs to any @typedef, @callback, or @enum tags in the same comment block, if they exist.
|
||||
const typeAlias = find(node.parent.tags, isJSDocTypeAlias);
|
||||
if (typeAlias) {
|
||||
return typeAlias;
|
||||
}
|
||||
}
|
||||
// otherwise it belongs to the host it annotates
|
||||
return getHostSignatureFromJSDoc(node);
|
||||
}
|
||||
|
||||
export function getHostSignatureFromJSDoc(node: Node): SignatureDeclaration | undefined {
|
||||
const host = getEffectiveJSDocHost(node);
|
||||
return host && isFunctionLike(host) ? host : undefined;
|
||||
|
||||
Reference in New Issue
Block a user