@@ -8365,7 +8365,7 @@ namespace ts {
8365
8365
checkJsxOpeningLikeElement(node.openingElement);
8366
8366
8367
8367
// Perform resolution on the closing tag so that rename/go to definition/etc work
8368
- getJsxElementTagSymbol (node.closingElement);
8368
+ getJsxTagSymbol (node.closingElement);
8369
8369
8370
8370
// Check children
8371
8371
for (const child of node.children) {
@@ -8475,77 +8475,53 @@ namespace ts {
8475
8475
return jsxTypes[name];
8476
8476
}
8477
8477
8478
- /// Given a JSX opening element or self-closing element, return the symbol of the property that the tag name points to if
8479
- /// this is an intrinsic tag. This might be a named
8480
- /// property of the IntrinsicElements interface, or its string indexer.
8481
- /// If this is a class-based tag (otherwise returns undefined), returns the symbol of the class
8482
- /// type or factory function.
8483
- /// Otherwise, returns unknownSymbol.
8484
- function getJsxElementTagSymbol(node: JsxOpeningLikeElement | JsxClosingElement): Symbol {
8478
+ function getJsxTagSymbol(node: JsxOpeningLikeElement | JsxClosingElement): Symbol {
8485
8479
const links = getNodeLinks(node);
8486
- if (!links.resolvedSymbol) {
8487
- if (isJsxIntrinsicIdentifier(node.tagName)) {
8488
- links.resolvedSymbol = lookupIntrinsicTag(node);
8489
- }
8490
- else {
8491
- links.resolvedSymbol = lookupClassTag(node);
8492
- }
8480
+ if (isJsxIntrinsicIdentifier(node.tagName)) {
8481
+ return getIntrinsicTagSymbol(node);
8493
8482
}
8494
- return links.resolvedSymbol;
8483
+ else {
8484
+ return resolveEntityName(node.tagName, SymbolFlags.Value);
8485
+ }
8486
+ }
8495
8487
8496
- function lookupIntrinsicTag(node: JsxOpeningLikeElement | JsxClosingElement): Symbol {
8488
+ /**
8489
+ * Looks up an intrinsic tag name and returns a symbol that either points to an intrinsic
8490
+ * property (in which case nodeLinks.jsxFlags will be IntrinsicNamedElement) or an intrinsic
8491
+ * string index signature (in which case nodeLinks.jsxFlags will be IntrinsicIndexedElement).
8492
+ * May also return unknownSymbol if both of these lookups fail.
8493
+ */
8494
+ function getIntrinsicTagSymbol(node: JsxOpeningLikeElement | JsxClosingElement): Symbol {
8495
+ const links = getNodeLinks(node);
8496
+ if (!links.resolvedSymbol) {
8497
8497
const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements);
8498
8498
if (intrinsicElementsType !== unknownType) {
8499
8499
// Property case
8500
8500
const intrinsicProp = getPropertyOfType(intrinsicElementsType, (<Identifier>node.tagName).text);
8501
8501
if (intrinsicProp) {
8502
8502
links.jsxFlags |= JsxFlags.IntrinsicNamedElement;
8503
- return intrinsicProp;
8503
+ return links.resolvedSymbol = intrinsicProp;
8504
8504
}
8505
8505
8506
8506
// Intrinsic string indexer case
8507
8507
const indexSignatureType = getIndexTypeOfType(intrinsicElementsType, IndexKind.String);
8508
8508
if (indexSignatureType) {
8509
8509
links.jsxFlags |= JsxFlags.IntrinsicIndexedElement;
8510
- return intrinsicElementsType.symbol;
8510
+ return links.resolvedSymbol = intrinsicElementsType.symbol;
8511
8511
}
8512
8512
8513
8513
// Wasn't found
8514
8514
error(node, Diagnostics.Property_0_does_not_exist_on_type_1, (<Identifier>node.tagName).text, "JSX." + JsxNames.IntrinsicElements);
8515
- return unknownSymbol;
8515
+ return links.resolvedSymbol = unknownSymbol;
8516
8516
}
8517
8517
else {
8518
8518
if (compilerOptions.noImplicitAny) {
8519
8519
error(node, Diagnostics.JSX_element_implicitly_has_type_any_because_no_interface_JSX_0_exists, JsxNames.IntrinsicElements);
8520
8520
}
8521
- return unknownSymbol;
8522
- }
8523
- }
8524
-
8525
- function lookupClassTag(node: JsxOpeningLikeElement | JsxClosingElement): Symbol {
8526
- const valueSymbol: Symbol = resolveJsxTagName(node);
8527
-
8528
- // Look up the value in the current scope
8529
- if (valueSymbol && valueSymbol !== unknownSymbol) {
8530
- links.jsxFlags |= JsxFlags.ValueElement;
8531
- if (valueSymbol.flags & SymbolFlags.Alias) {
8532
- markAliasSymbolAsReferenced(valueSymbol);
8533
- }
8534
- }
8535
-
8536
- return valueSymbol || unknownSymbol;
8537
- }
8538
-
8539
- function resolveJsxTagName(node: JsxOpeningLikeElement | JsxClosingElement): Symbol {
8540
- if (node.tagName.kind === SyntaxKind.Identifier) {
8541
- const tag = <Identifier>node.tagName;
8542
- const sym = getResolvedSymbol(tag);
8543
- return sym.exportSymbol || sym;
8544
- }
8545
- else {
8546
- return checkQualifiedName(<QualifiedName>node.tagName).symbol;
8521
+ return links.resolvedSymbol = unknownSymbol;
8547
8522
}
8548
8523
}
8524
+ return links.resolvedSymbol;
8549
8525
}
8550
8526
8551
8527
/**
@@ -8554,17 +8530,8 @@ namespace ts {
8554
8530
* For example, in the element <MyClass>, the element instance type is `MyClass` (not `typeof MyClass`).
8555
8531
*/
8556
8532
function getJsxElementInstanceType(node: JsxOpeningLikeElement) {
8557
- // There is no such thing as an instance type for a non-class element. This
8558
- // line shouldn't be hit.
8559
- Debug.assert(!!(getNodeLinks(node).jsxFlags & JsxFlags.ValueElement), "Should not call getJsxElementInstanceType on non-class Element");
8533
+ const valueType = checkExpression(node.tagName);
8560
8534
8561
- const classSymbol = getJsxElementTagSymbol(node);
8562
- if (classSymbol === unknownSymbol) {
8563
- // Couldn't find the class instance type. Error has already been issued
8564
- return anyType;
8565
- }
8566
-
8567
- const valueType = getTypeOfSymbol(classSymbol);
8568
8535
if (isTypeAny(valueType)) {
8569
8536
// Short-circuit if the class tag is using an element type 'any'
8570
8537
return anyType;
@@ -8630,9 +8597,16 @@ namespace ts {
8630
8597
function getJsxElementAttributesType(node: JsxOpeningLikeElement): Type {
8631
8598
const links = getNodeLinks(node);
8632
8599
if (!links.resolvedJsxType) {
8633
- const sym = getJsxElementTagSymbol(node);
8634
-
8635
- if (links.jsxFlags & JsxFlags.ValueElement) {
8600
+ if (isJsxIntrinsicIdentifier(node.tagName)) {
8601
+ const symbol = getIntrinsicTagSymbol(node);
8602
+ if (links.jsxFlags & JsxFlags.IntrinsicNamedElement) {
8603
+ return links.resolvedJsxType = getTypeOfSymbol(symbol);
8604
+ }
8605
+ else if (links.jsxFlags & JsxFlags.IntrinsicIndexedElement) {
8606
+ return links.resolvedJsxType = getIndexInfoOfSymbol(symbol, IndexKind.String).type;
8607
+ }
8608
+ }
8609
+ else {
8636
8610
// Get the element instance type (the result of newing or invoking this tag)
8637
8611
const elemInstanceType = getJsxElementInstanceType(node);
8638
8612
@@ -8641,7 +8615,7 @@ namespace ts {
8641
8615
if (!elemClassType || !isTypeAssignableTo(elemInstanceType, elemClassType)) {
8642
8616
// Is this is a stateless function component? See if its single signature's return type is
8643
8617
// assignable to the JSX Element Type
8644
- const elemType = getTypeOfSymbol(sym );
8618
+ const elemType = checkExpression(node.tagName );
8645
8619
const callSignatures = elemType && getSignaturesOfType(elemType, SignatureKind.Call);
8646
8620
const callSignature = callSignatures && callSignatures.length > 0 && callSignatures[0];
8647
8621
const callReturnType = callSignature && getReturnTypeOfSignature(callSignature);
@@ -8715,16 +8689,8 @@ namespace ts {
8715
8689
}
8716
8690
}
8717
8691
}
8718
- else if (links.jsxFlags & JsxFlags.IntrinsicNamedElement) {
8719
- return links.resolvedJsxType = getTypeOfSymbol(sym);
8720
- }
8721
- else if (links.jsxFlags & JsxFlags.IntrinsicIndexedElement) {
8722
- return links.resolvedJsxType = getIndexInfoOfSymbol(sym, IndexKind.String).type;
8723
- }
8724
- else {
8725
- // Resolution failed, so we don't know
8726
- return links.resolvedJsxType = anyType;
8727
- }
8692
+
8693
+ return links.resolvedJsxType = unknownType;
8728
8694
}
8729
8695
8730
8696
return links.resolvedJsxType;
@@ -15431,7 +15397,8 @@ namespace ts {
15431
15397
else if ((entityName.parent.kind === SyntaxKind.JsxOpeningElement) ||
15432
15398
(entityName.parent.kind === SyntaxKind.JsxSelfClosingElement) ||
15433
15399
(entityName.parent.kind === SyntaxKind.JsxClosingElement)) {
15434
- return getJsxElementTagSymbol(<JsxOpeningLikeElement>entityName.parent);
15400
+
15401
+ return getJsxTagSymbol(<JsxOpeningLikeElement>entityName.parent);
15435
15402
}
15436
15403
else if (isExpression(entityName)) {
15437
15404
if (nodeIsMissing(entityName)) {
0 commit comments