@@ -739,6 +739,7 @@ namespace ts {
739
739
if (jsxPragma) {
740
740
const chosenpragma: any = isArray(jsxPragma) ? jsxPragma[0] : jsxPragma; // TODO: GH#18217
741
741
file.localJsxFactory = parseIsolatedEntityName(chosenpragma.arguments.factory, languageVersion);
742
+ visitNode(file.localJsxFactory, markAsSynthetic);
742
743
if (file.localJsxFactory) {
743
744
return file.localJsxNamespace = getFirstIdentifier(file.localJsxFactory).escapedText;
744
745
}
@@ -749,6 +750,7 @@ namespace ts {
749
750
_jsxNamespace = "React" as __String;
750
751
if (compilerOptions.jsxFactory) {
751
752
_jsxFactoryEntity = parseIsolatedEntityName(compilerOptions.jsxFactory, languageVersion);
753
+ visitNode(_jsxFactoryEntity, markAsSynthetic);
752
754
if (_jsxFactoryEntity) {
753
755
_jsxNamespace = getFirstIdentifier(_jsxFactoryEntity).escapedText;
754
756
}
@@ -758,6 +760,12 @@ namespace ts {
758
760
}
759
761
}
760
762
return _jsxNamespace;
763
+
764
+ function markAsSynthetic(node: Node): VisitResult<Node> {
765
+ node.pos = -1;
766
+ node.end = -1;
767
+ return visitEachChild(node, markAsSynthetic, nullTransformationContext);
768
+ }
761
769
}
762
770
763
771
function getEmitResolver(sourceFile: SourceFile, cancellationToken: CancellationToken) {
@@ -2159,7 +2167,7 @@ namespace ts {
2159
2167
let symbol: Symbol | undefined;
2160
2168
if (name.kind === SyntaxKind.Identifier) {
2161
2169
const message = meaning === namespaceMeaning ? Diagnostics.Cannot_find_namespace_0 : getCannotFindNameDiagnosticForName(getFirstIdentifier(name).escapedText);
2162
- const symbolFromJSPrototype = isInJSFile(name) ? resolveEntityNameFromAssignmentDeclaration(name, meaning) : undefined;
2170
+ const symbolFromJSPrototype = isInJSFile(name) && !nodeIsSynthesized(name) ? resolveEntityNameFromAssignmentDeclaration(name, meaning) : undefined;
2163
2171
symbol = resolveName(location || name, name.escapedText, meaning, ignoreErrors || symbolFromJSPrototype ? undefined : message, name, /*isUse*/ true);
2164
2172
if (!symbol) {
2165
2173
return symbolFromJSPrototype;
@@ -18535,9 +18543,9 @@ namespace ts {
18535
18543
checkJsxOpeningLikeElementOrOpeningFragment(node);
18536
18544
}
18537
18545
18538
- function checkJsxSelfClosingElement(node: JsxSelfClosingElement, _checkMode: CheckMode | undefined ): Type {
18546
+ function checkJsxSelfClosingElement(node: JsxSelfClosingElement): Type {
18539
18547
checkNodeDeferred(node);
18540
- return getJsxElementTypeAt (node) || anyType ;
18548
+ return getFactoryReturnTypeForJsxOpeningLikeElement (node);
18541
18549
}
18542
18550
18543
18551
function checkJsxElementDeferred(node: JsxElement) {
@@ -18555,10 +18563,10 @@ namespace ts {
18555
18563
checkJsxChildren(node);
18556
18564
}
18557
18565
18558
- function checkJsxElement(node: JsxElement, _checkMode: CheckMode | undefined ): Type {
18566
+ function checkJsxElement(node: JsxElement): Type {
18559
18567
checkNodeDeferred(node);
18560
18568
18561
- return getJsxElementTypeAt (node) || anyType ;
18569
+ return getFactoryReturnTypeForJsxOpeningLikeElement (node.openingElement) ;
18562
18570
}
18563
18571
18564
18572
function checkJsxFragment(node: JsxFragment): Type {
@@ -18571,7 +18579,7 @@ namespace ts {
18571
18579
}
18572
18580
18573
18581
checkJsxChildren(node);
18574
- return getJsxElementTypeAt (node) || anyType ;
18582
+ return getFactoryReturnTypeForJsxOpeningLikeElement (node.openingFragment) ;
18575
18583
}
18576
18584
18577
18585
/**
@@ -18999,6 +19007,49 @@ namespace ts {
18999
19007
}
19000
19008
}
19001
19009
19010
+ function getFactoryReturnTypeForJsxOpeningLikeElement(node: JsxOpeningLikeElement | JsxOpeningFragment) {
19011
+ const reactRefErr = diagnostics && compilerOptions.jsx === JsxEmit.React ? Diagnostics.Cannot_find_name_0 : undefined;
19012
+ const reactNamespace = getJsxNamespace(node);
19013
+ const reactLocation = isJsxOpeningLikeElement(node) ? node.tagName : node;
19014
+ const reactSym = resolveName(reactLocation, reactNamespace, SymbolFlags.Value, reactRefErr, reactNamespace, /*isUse*/ true);
19015
+ const factoryEntity = getJsxFactoryEntity(reactLocation);
19016
+ if (!factoryEntity) {
19017
+ return getJsxElementTypeAt(node) || errorType;
19018
+ }
19019
+ const factorySymbol = resolveEntityName(factoryEntity, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontUseResolveAlias*/ false, reactLocation);
19020
+ if (reactSym && factorySymbol && factorySymbol !== unknownSymbol) {
19021
+ // Mark local symbol as referenced here because it might not have been marked
19022
+ // if jsx emit was not react as there wont be error being emitted
19023
+ reactSym.isReferenced = SymbolFlags.All;
19024
+
19025
+ // If react symbol is alias, mark it as referenced
19026
+ if (reactSym.flags & SymbolFlags.Alias && !isConstEnumOrConstEnumOnlyModule(resolveAlias(reactSym))) {
19027
+ markAliasSymbolAsReferenced(reactSym);
19028
+ }
19029
+ const links = getNodeLinks(node);
19030
+ if (!links.jsxFactoryCall) {
19031
+ const factoryExpression = createSyntheticExpression(node, getTypeOfSymbol(factorySymbol));
19032
+ const children = isJsxOpeningElement(node) ? node.parent.children : emptyArray;
19033
+ links.jsxFactoryCall = createCall(factoryExpression, /*typeArguments*/ undefined, [
19034
+ isJsxOpeningFragment(node)
19035
+ ? createSyntheticExpression(node, reactSym.exports ? getTypeOfSymbol(getSymbol(getExportsOfSymbol(reactSym), "Fragment" as __String, SymbolFlags.Value) || unknownSymbol) : emptyObjectType)
19036
+ : isJsxIntrinsicIdentifier(node.tagName) ? createSyntheticExpression(node.tagName, getLiteralType(idText((node.tagName as Identifier)))) : node.tagName,
19037
+ isJsxOpeningFragment(node) ? createSyntheticExpression(node, nullType) : createSyntheticExpression(node.attributes, checkMode => checkExpression(node.attributes, checkMode)),
19038
+ ...mapDefined(children, c => isJsxText(c) && c.containsOnlyWhiteSpaces ? undefined : createSyntheticExpression(c, isJsxText(c) ? stringType : (checkMode => checkExpression(c, checkMode))))
19039
+ ]);
19040
+ links.jsxFactoryCall.pos = node.pos;
19041
+ links.jsxFactoryCall.end = node.end;
19042
+ links.jsxFactoryCall.parent = node.parent;
19043
+ }
19044
+ const result = getReturnTypeOfSignature(getResolvedSignature(links.jsxFactoryCall));
19045
+ if (result === errorType) {
19046
+ return getJsxElementTypeAt(node) || errorType;
19047
+ }
19048
+ return result;
19049
+ }
19050
+ return getJsxElementTypeAt(node) || errorType;
19051
+ }
19052
+
19002
19053
function checkJsxOpeningLikeElementOrOpeningFragment(node: JsxOpeningLikeElement | JsxOpeningFragment) {
19003
19054
const isNodeOpeningLikeElement = isJsxOpeningLikeElement(node);
19004
19055
@@ -20038,7 +20089,7 @@ namespace ts {
20038
20089
// We are inferring from a spread expression in the last argument position, i.e. both the parameter
20039
20090
// and the argument are ...x forms.
20040
20091
return arg.kind === SyntaxKind.SyntheticExpression ?
20041
- createArrayType((<SyntheticExpression>arg).type ) :
20092
+ createArrayType(checkExpressionWithContextualType (<SyntheticExpression>arg, restType, context) ) :
20042
20093
getArrayifiedType(checkExpressionWithContextualType((<SpreadElement>arg).expression, restType, context));
20043
20094
}
20044
20095
}
@@ -20176,7 +20227,7 @@ namespace ts {
20176
20227
}
20177
20228
}
20178
20229
20179
- function createSyntheticExpression(parent: Node, type: Type, isSpread?: boolean) {
20230
+ function createSyntheticExpression(parent: Node, type: Type | ((mode: CheckMode | undefined) => Type) , isSpread?: boolean) {
20180
20231
const result = <SyntheticExpression>createNode(SyntaxKind.SyntheticExpression, parent.pos, parent.end);
20181
20232
result.parent = parent;
20182
20233
result.type = type;
@@ -23419,13 +23470,14 @@ namespace ts {
23419
23470
case SyntaxKind.YieldExpression:
23420
23471
return checkYieldExpression(<YieldExpression>node);
23421
23472
case SyntaxKind.SyntheticExpression:
23422
- return (<SyntheticExpression>node).type;
23473
+ const cbOrType = (<SyntheticExpression>node).type;
23474
+ return typeof cbOrType === "function" ? cbOrType(checkMode) : cbOrType;
23423
23475
case SyntaxKind.JsxExpression:
23424
23476
return checkJsxExpression(<JsxExpression>node, checkMode);
23425
23477
case SyntaxKind.JsxElement:
23426
- return checkJsxElement(<JsxElement>node, checkMode );
23478
+ return checkJsxElement(<JsxElement>node);
23427
23479
case SyntaxKind.JsxSelfClosingElement:
23428
- return checkJsxSelfClosingElement(<JsxSelfClosingElement>node, checkMode );
23480
+ return checkJsxSelfClosingElement(<JsxSelfClosingElement>node);
23429
23481
case SyntaxKind.JsxFragment:
23430
23482
return checkJsxFragment(<JsxFragment>node);
23431
23483
case SyntaxKind.JsxAttributes:
@@ -29619,6 +29671,10 @@ namespace ts {
29619
29671
return literalTypeToNode(<FreshableType>type, node, tracker);
29620
29672
}
29621
29673
29674
+ function getJsxFactoryEntity(location?: Node): EntityName | undefined {
29675
+ return location ? (getJsxNamespace(location), (getSourceFileOfNode(location).localJsxFactory || _jsxFactoryEntity)) : _jsxFactoryEntity;
29676
+ }
29677
+
29622
29678
function createResolver(): EmitResolver {
29623
29679
// this variable and functions that use it are deliberately moved here from the outer scope
29624
29680
// to avoid scope pollution
@@ -29690,7 +29746,7 @@ namespace ts {
29690
29746
const symbol = node && getSymbolOfNode(node);
29691
29747
return !!(symbol && getCheckFlags(symbol) & CheckFlags.Late);
29692
29748
},
29693
- getJsxFactoryEntity: location => location ? (getJsxNamespace(location), (getSourceFileOfNode(location).localJsxFactory || _jsxFactoryEntity)) : _jsxFactoryEntity ,
29749
+ getJsxFactoryEntity,
29694
29750
getAllAccessorDeclarations(accessor: AccessorDeclaration): AllAccessorDeclarations {
29695
29751
accessor = getParseTreeNode(accessor, isGetOrSetAccessorDeclaration)!; // TODO: GH#18217
29696
29752
const otherKind = accessor.kind === SyntaxKind.SetAccessor ? SyntaxKind.GetAccessor : SyntaxKind.SetAccessor;
0 commit comments