Skip to content

Commit 1484c0a

Browse files
author
Andy Hanson
committed
Merge branch 'master' into undefinedzilla
2 parents 8deee11 + 32c63a2 commit 1484c0a

File tree

1,017 files changed

+5295
-748
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,017 files changed

+5295
-748
lines changed

src/compiler/checker.ts

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ namespace ts {
299299
resolveName(name, location, meaning, excludeGlobals) {
300300
return resolveName(location, escapeLeadingUnderscores(name), meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false, excludeGlobals);
301301
},
302-
getJsxNamespace: () => unescapeLeadingUnderscores(getJsxNamespace()),
302+
getJsxNamespace: n => unescapeLeadingUnderscores(getJsxNamespace(n)),
303303
getAccessibleSymbolChain,
304304
getTypePredicateOfSignature: getTypePredicateOfSignature as (signature: Signature) => TypePredicate, // TODO: GH#18217
305305
resolveExternalModuleSymbol,
@@ -766,7 +766,23 @@ namespace ts {
766766
}
767767
}
768768

769-
function getJsxNamespace(): __String {
769+
function getJsxNamespace(location: Node | undefined): __String {
770+
if (location) {
771+
const file = getSourceFileOfNode(location);
772+
if (file) {
773+
if (file.localJsxNamespace) {
774+
return file.localJsxNamespace;
775+
}
776+
const jsxPragma = file.pragmas.get("jsx");
777+
if (jsxPragma) {
778+
const chosenpragma: any = isArray(jsxPragma) ? jsxPragma[0] : jsxPragma; // TODO: GH#18217
779+
file.localJsxFactory = parseIsolatedEntityName(chosenpragma.arguments.factory, languageVersion);
780+
if (file.localJsxFactory) {
781+
return file.localJsxNamespace = getFirstIdentifier(file.localJsxFactory).escapedText;
782+
}
783+
}
784+
}
785+
}
770786
if (!_jsxNamespace) {
771787
_jsxNamespace = "React" as __String;
772788
if (compilerOptions.jsxFactory) {
@@ -2099,7 +2115,7 @@ namespace ts {
20992115
else if (noImplicitAny && moduleNotFoundError) {
21002116
let errorInfo = resolvedModule!.packageId && chainDiagnosticMessages(/*details*/ undefined,
21012117
Diagnostics.Try_npm_install_types_Slash_0_if_it_exists_or_add_a_new_declaration_d_ts_file_containing_declare_module_0,
2102-
resolvedModule!.packageId!.name); // TODO: GH#18217
2118+
getMangledNameForScopedPackage(resolvedModule!.packageId!.name)); // TODO: GH#18217
21032119
errorInfo = chainDiagnosticMessages(errorInfo,
21042120
Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type,
21052121
moduleReference,
@@ -4031,7 +4047,7 @@ namespace ts {
40314047
parentType = getNonNullableType(parentType);
40324048
}
40334049
const propType = getTypeOfPropertyOfType(parentType, text);
4034-
const declaredType = propType && getApparentTypeForLocation(propType, declaration.name);
4050+
const declaredType = propType && getConstraintForLocation(propType, declaration.name);
40354051
type = declaredType && getFlowTypeOfReference(declaration, declaredType) ||
40364052
isNumericLiteralName(text) && getIndexTypeOfType(parentType, IndexKind.Number) ||
40374053
getIndexTypeOfType(parentType, IndexKind.String);
@@ -6159,17 +6175,29 @@ namespace ts {
61596175
return getConstraintOfDistributiveConditionalType(type) || getDefaultConstraintOfConditionalType(type);
61606176
}
61616177

6162-
function getBaseConstraintOfType(type: Type): Type | undefined {
6178+
function getBaseConstraintOfInstantiableNonPrimitiveUnionOrIntersection(type: Type) {
61636179
if (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.UnionOrIntersection)) {
61646180
const constraint = getResolvedBaseConstraint(<InstantiableType | UnionOrIntersectionType>type);
61656181
if (constraint !== noConstraintType && constraint !== circularConstraintType) {
61666182
return constraint;
61676183
}
61686184
}
6169-
else if (type.flags & TypeFlags.Index) {
6185+
}
6186+
6187+
function getBaseConstraintOfType(type: Type): Type | undefined {
6188+
const constraint = getBaseConstraintOfInstantiableNonPrimitiveUnionOrIntersection(type);
6189+
if (!constraint && type.flags & TypeFlags.Index) {
61706190
return stringType;
61716191
}
6172-
return undefined;
6192+
return constraint;
6193+
}
6194+
6195+
/**
6196+
* This is similar to `getBaseConstraintOfType` except it returns the input type if there's no base constraint, instead of `undefined`
6197+
* It also doesn't map indexes to `string`, as where this is used this would be unneeded (and likely undesirable)
6198+
*/
6199+
function getBaseConstraintOrType(type: Type) {
6200+
return getBaseConstraintOfType(type) || type;
61736201
}
61746202

61756203
function hasNonCircularBaseConstraint(type: InstantiableType): boolean {
@@ -11971,7 +11999,7 @@ namespace ts {
1197111999
function getFlowCacheKey(node: Node): string | undefined {
1197212000
if (node.kind === SyntaxKind.Identifier) {
1197312001
const symbol = getResolvedSymbol(<Identifier>node);
11974-
return symbol !== unknownSymbol ? (isApparentTypePosition(node) ? "@" : "") + getSymbolId(symbol) : undefined;
12002+
return symbol !== unknownSymbol ? (isConstraintPosition(node) ? "@" : "") + getSymbolId(symbol) : undefined;
1197512003
}
1197612004
if (node.kind === SyntaxKind.ThisKeyword) {
1197712005
return "0";
@@ -13336,8 +13364,8 @@ namespace ts {
1333613364
return annotationIncludesUndefined ? getTypeWithFacts(declaredType, TypeFacts.NEUndefined) : declaredType;
1333713365
}
1333813366

13339-
function isApparentTypePosition(node: Node) {
13340-
const { parent } = node;
13367+
function isConstraintPosition(node: Node) {
13368+
const parent = node.parent;
1334113369
return parent.kind === SyntaxKind.PropertyAccessExpression ||
1334213370
parent.kind === SyntaxKind.CallExpression && (<CallExpression>parent).expression === node ||
1334313371
parent.kind === SyntaxKind.ElementAccessExpression && (<ElementAccessExpression>parent).expression === node ||
@@ -13349,13 +13377,13 @@ namespace ts {
1334913377
return type.flags & TypeFlags.InstantiableNonPrimitive && maybeTypeOfKind(getBaseConstraintOfType(type) || emptyObjectType, TypeFlags.Nullable);
1335013378
}
1335113379

13352-
function getApparentTypeForLocation(type: Type, node: Node) {
13380+
function getConstraintForLocation(type: Type, node: Node) {
1335313381
// When a node is the left hand expression of a property access, element access, or call expression,
1335413382
// and the type of the node includes type variables with constraints that are nullable, we fetch the
1335513383
// apparent type of the node *before* performing control flow analysis such that narrowings apply to
1335613384
// the constraint type.
13357-
if (isApparentTypePosition(node) && forEachType(type, typeHasNullableConstraint)) {
13358-
return mapType(getWidenedType(type), getApparentType);
13385+
if (isConstraintPosition(node) && forEachType(type, typeHasNullableConstraint)) {
13386+
return mapType(getWidenedType(type), getBaseConstraintOrType);
1335913387
}
1336013388
return type;
1336113389
}
@@ -13443,7 +13471,7 @@ namespace ts {
1344313471
checkCollisionWithCapturedNewTargetVariable(node, node);
1344413472
checkNestedBlockScopedBinding(node, symbol);
1344513473

13446-
const type = getApparentTypeForLocation(getTypeOfSymbol(localOrExportSymbol), node);
13474+
const type = getConstraintForLocation(getTypeOfSymbol(localOrExportSymbol), node);
1344713475
const assignmentKind = getAssignmentTargetKind(node);
1344813476

1344913477
if (assignmentKind) {
@@ -15109,8 +15137,10 @@ namespace ts {
1510915137
function checkJsxFragment(node: JsxFragment, checkMode: CheckMode | undefined): Type {
1511015138
checkJsxOpeningLikeElementOrOpeningFragment(node.openingFragment, checkMode);
1511115139

15112-
if (compilerOptions.jsx === JsxEmit.React && compilerOptions.jsxFactory) {
15113-
error(node, Diagnostics.JSX_fragment_is_not_supported_when_using_jsxFactory);
15140+
if (compilerOptions.jsx === JsxEmit.React && (compilerOptions.jsxFactory || getSourceFileOfNode(node).pragmas.has("jsx"))) {
15141+
error(node, compilerOptions.jsxFactory
15142+
? Diagnostics.JSX_fragment_is_not_supported_when_using_jsxFactory
15143+
: Diagnostics.JSX_fragment_is_not_supported_when_using_an_inline_JSX_factory_pragma);
1511415144
}
1511515145

1511615146
return getJsxGlobalElementType() || anyType;
@@ -15737,7 +15767,7 @@ namespace ts {
1573715767
// The reactNamespace/jsxFactory's root symbol should be marked as 'used' so we don't incorrectly elide its import.
1573815768
// And if there is no reactNamespace/jsxFactory's symbol in scope when targeting React emit, we should issue an error.
1573915769
const reactRefErr = diagnostics && compilerOptions.jsx === JsxEmit.React ? Diagnostics.Cannot_find_name_0 : undefined;
15740-
const reactNamespace = getJsxNamespace();
15770+
const reactNamespace = getJsxNamespace(node);
1574115771
const reactLocation = isNodeOpeningLikeElement ? (<JsxOpeningLikeElement>node).tagName : node;
1574215772
const reactSym = resolveName(reactLocation, reactNamespace, SymbolFlags.Value, reactRefErr, reactNamespace, /*isUse*/ true);
1574315773
if (reactSym) {
@@ -15917,7 +15947,7 @@ namespace ts {
1591715947

1591815948
// Referencing abstract properties within their own constructors is not allowed
1591915949
if ((flags & ModifierFlags.Abstract) && isThisProperty(node) && symbolHasNonMethodDeclaration(prop)) {
15920-
const declaringClassDeclaration = <ClassLikeDeclaration>getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)!);
15950+
const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)!);
1592115951
if (declaringClassDeclaration && isNodeWithinConstructorOfClass(node, declaringClassDeclaration)) {
1592215952
error(errorNode, Diagnostics.Abstract_property_0_in_class_1_cannot_be_accessed_in_the_constructor, symbolToString(prop), getTextOfIdentifierOrLiteral(declaringClassDeclaration.name!)); // TODO: GH#18217
1592315953
return false;
@@ -15933,7 +15963,7 @@ namespace ts {
1593315963

1593415964
// Private property is accessible if the property is within the declaring class
1593515965
if (flags & ModifierFlags.Private) {
15936-
const declaringClassDeclaration = <ClassLikeDeclaration>getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)!);
15966+
const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(getParentOfSymbol(prop)!)!;
1593715967
if (!isNodeWithinClass(node, declaringClassDeclaration)) {
1593815968
error(errorNode, Diagnostics.Property_0_is_private_and_only_accessible_within_class_1, symbolToString(prop), typeToString(getDeclaringClass(prop)!));
1593915969
return false;
@@ -16064,7 +16094,7 @@ namespace ts {
1606416094
return unknownType;
1606516095
}
1606616096
}
16067-
propType = getApparentTypeForLocation(getTypeOfSymbol(prop), node);
16097+
propType = getConstraintForLocation(getTypeOfSymbol(prop), node);
1606816098
}
1606916099
// Only compute control flow type if this is a property access expression that isn't an
1607016100
// assignment target, and the referenced property was declared as a variable, property,
@@ -17657,7 +17687,7 @@ namespace ts {
1765717687
return true;
1765817688
}
1765917689

17660-
const declaringClassDeclaration = <ClassLikeDeclaration>getClassLikeDeclarationOfSymbol(declaration.parent.symbol!);
17690+
const declaringClassDeclaration = getClassLikeDeclarationOfSymbol(declaration.parent.symbol!)!;
1766117691
const declaringClass = <InterfaceType>getDeclaredTypeOfSymbol(declaration.parent.symbol!);
1766217692

1766317693
// A private or protected constructor can only be instantiated within its own class (or a subclass, for protected)
@@ -23138,7 +23168,7 @@ namespace ts {
2313823168
const rootChain = () => chainDiagnosticMessages(
2313923169
/*details*/ undefined,
2314023170
Diagnostics.Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2,
23141-
unescapeLeadingUnderscores(declaredProp.escapedName),
23171+
symbolToString(declaredProp),
2314223172
typeToString(typeWithThis),
2314323173
typeToString(baseWithThis)
2314423174
);
@@ -23159,7 +23189,7 @@ namespace ts {
2315923189
if (signatures.length) {
2316023190
const declaration = signatures[0].declaration;
2316123191
if (declaration && hasModifier(declaration, ModifierFlags.Private)) {
23162-
const typeClassDeclaration = <ClassLikeDeclaration>getClassLikeDeclarationOfSymbol(type.symbol!);
23192+
const typeClassDeclaration = getClassLikeDeclarationOfSymbol(type.symbol!)!;
2316323193
if (!isNodeWithinClass(node, typeClassDeclaration)) {
2316423194
error(node, Diagnostics.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private, getFullyQualifiedName(type.symbol!));
2316523195
}
@@ -25597,7 +25627,7 @@ namespace ts {
2559725627
return !!(symbol && getCheckFlags(symbol) & CheckFlags.Late);
2559825628
},
2559925629
writeLiteralConstValue,
25600-
getJsxFactoryEntity: () => _jsxFactoryEntity!, // TODO: GH#18217
25630+
getJsxFactoryEntity: location => location ? (getJsxNamespace(location), (getSourceFileOfNode(location).localJsxFactory || _jsxFactoryEntity!)) : _jsxFactoryEntity!, // TODO: GH#18217
2560125631
};
2560225632

2560325633
// defined here to avoid outer scope pollution

src/compiler/diagnosticMessages.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3788,6 +3788,10 @@
37883788
"category": "Error",
37893789
"code": 17016
37903790
},
3791+
"JSX fragment is not supported when using an inline JSX factory pragma": {
3792+
"category": "Error",
3793+
"code": 17017
3794+
},
37913795

37923796
"Circularity detected while resolving configuration: {0}": {
37933797
"category": "Error",
@@ -3965,5 +3969,17 @@
39653969
"Convert to ES6 module": {
39663970
"category": "Message",
39673971
"code": 95017
3972+
},
3973+
"Add 'undefined' type to property '{0}'": {
3974+
"category": "Message",
3975+
"code": 95018
3976+
},
3977+
"Add initializer to property '{0}'": {
3978+
"category": "Message",
3979+
"code": 95019
3980+
},
3981+
"Add definite assignment assertion to property '{0}'": {
3982+
"category": "Message",
3983+
"code": 95020
39683984
}
39693985
}

src/compiler/emitter.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,6 +1024,7 @@ namespace ts {
10241024
emitModifiers(node, node.modifiers);
10251025
emit(node.name);
10261026
emitIfPresent(node.questionToken);
1027+
emitIfPresent(node.exclamationToken);
10271028
emitTypeAnnotation(node.type);
10281029
emitInitializer(node.initializer);
10291030
writeSemicolon();

src/compiler/factory.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2375,6 +2375,9 @@ namespace ts {
23752375
if (node.resolvedTypeReferenceDirectiveNames !== undefined) updated.resolvedTypeReferenceDirectiveNames = node.resolvedTypeReferenceDirectiveNames;
23762376
if (node.imports !== undefined) updated.imports = node.imports;
23772377
if (node.moduleAugmentations !== undefined) updated.moduleAugmentations = node.moduleAugmentations;
2378+
if (node.pragmas !== undefined) updated.pragmas = node.pragmas;
2379+
if (node.localJsxFactory !== undefined) updated.localJsxFactory = node.localJsxFactory;
2380+
if (node.localJsxNamespace !== undefined) updated.localJsxNamespace = node.localJsxNamespace;
23782381
return updateNode(updated, node);
23792382
}
23802383

src/compiler/moduleNameResolver.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1156,7 +1156,8 @@ namespace ts {
11561156
return `@types/${getMangledNameForScopedPackage(packageName)}`;
11571157
}
11581158

1159-
function getMangledNameForScopedPackage(packageName: string): string {
1159+
/* @internal */
1160+
export function getMangledNameForScopedPackage(packageName: string): string {
11601161
if (startsWith(packageName, "@")) {
11611162
const replaceSlash = packageName.replace(ts.directorySeparator, mangledScopedPackageSeparator);
11621163
if (replaceSlash !== packageName) {

0 commit comments

Comments
 (0)