mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-30 01:04:49 -05:00
Fix #7637: treat jsx tag names as expressions
This commit is contained in:
@@ -9033,7 +9033,12 @@ namespace ts {
|
||||
checkJsxOpeningLikeElement(node.openingElement);
|
||||
|
||||
// Perform resolution on the closing tag so that rename/go to definition/etc work
|
||||
getJsxTagSymbol(node.closingElement);
|
||||
if (isJsxIntrinsicIdentifier(node.closingElement.tagName)) {
|
||||
getIntrinsicTagSymbol(node.closingElement);
|
||||
}
|
||||
else {
|
||||
checkExpression(node.closingElement.tagName);
|
||||
}
|
||||
|
||||
// Check children
|
||||
for (const child of node.children) {
|
||||
@@ -9143,18 +9148,6 @@ namespace ts {
|
||||
return jsxTypes[name];
|
||||
}
|
||||
|
||||
function getJsxTagSymbol(node: JsxOpeningLikeElement | JsxClosingElement): Symbol {
|
||||
if (isJsxIntrinsicIdentifier(node.tagName)) {
|
||||
return getIntrinsicTagSymbol(node);
|
||||
}
|
||||
else if (node.tagName.kind === SyntaxKind.Identifier) {
|
||||
return resolveEntityName(node.tagName, SymbolFlags.Value | SymbolFlags.Alias);
|
||||
}
|
||||
else {
|
||||
return checkExpression(node.tagName).symbol;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up an intrinsic tag name and returns a symbol that either points to an intrinsic
|
||||
* property (in which case nodeLinks.jsxFlags will be IntrinsicNamedElement) or an intrinsic
|
||||
@@ -16211,12 +16204,6 @@ namespace ts {
|
||||
meaning |= SymbolFlags.Alias;
|
||||
return resolveEntityName(<EntityName>entityName, meaning);
|
||||
}
|
||||
else if ((entityName.parent.kind === SyntaxKind.JsxOpeningElement) ||
|
||||
(entityName.parent.kind === SyntaxKind.JsxSelfClosingElement) ||
|
||||
(entityName.parent.kind === SyntaxKind.JsxClosingElement)) {
|
||||
|
||||
return getJsxTagSymbol(<JsxOpeningLikeElement>entityName.parent);
|
||||
}
|
||||
else if (isExpression(entityName)) {
|
||||
if (nodeIsMissing(entityName)) {
|
||||
// Missing entity name.
|
||||
@@ -16224,6 +16211,10 @@ namespace ts {
|
||||
}
|
||||
|
||||
if (entityName.kind === SyntaxKind.Identifier) {
|
||||
if (isJSXTagName(entityName) && isJsxIntrinsicIdentifier(<Identifier>entityName)) {
|
||||
return getIntrinsicTagSymbol(<JsxOpeningLikeElement>entityName.parent);
|
||||
}
|
||||
|
||||
// Include aliases in the meaning, this ensures that we do not follow aliases to where they point and instead
|
||||
// return the alias symbol.
|
||||
const meaning: SymbolFlags = SymbolFlags.Value | SymbolFlags.Alias;
|
||||
|
||||
@@ -953,6 +953,16 @@ namespace ts {
|
||||
return node.kind === SyntaxKind.ElementAccessExpression;
|
||||
}
|
||||
|
||||
export function isJSXTagName(node: Node) {
|
||||
const parent = node.parent;
|
||||
if (parent.kind === SyntaxKind.JsxOpeningElement ||
|
||||
parent.kind === SyntaxKind.JsxSelfClosingElement ||
|
||||
parent.kind === SyntaxKind.JsxClosingElement) {
|
||||
return (<JsxOpeningLikeElement>parent).tagName === node;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isExpression(node: Node): boolean {
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.SuperKeyword:
|
||||
@@ -994,9 +1004,9 @@ namespace ts {
|
||||
while (node.parent.kind === SyntaxKind.QualifiedName) {
|
||||
node = node.parent;
|
||||
}
|
||||
return node.parent.kind === SyntaxKind.TypeQuery;
|
||||
return node.parent.kind === SyntaxKind.TypeQuery || isJSXTagName(node);
|
||||
case SyntaxKind.Identifier:
|
||||
if (node.parent.kind === SyntaxKind.TypeQuery) {
|
||||
if (node.parent.kind === SyntaxKind.TypeQuery || isJSXTagName(node)) {
|
||||
return true;
|
||||
}
|
||||
// fall through
|
||||
|
||||
Reference in New Issue
Block a user