@@ -3489,16 +3489,17 @@ namespace ts {
3489
3489
* Attempts to find the symbol corresponding to the container a symbol is in - usually this
3490
3490
* is just its' `.parent`, but for locals, this value is `undefined`
3491
3491
*/
3492
- function getContainersOfSymbol(symbol: Symbol, enclosingDeclaration: Node | undefined): Symbol[] | undefined {
3492
+ function getContainersOfSymbol(symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags ): Symbol[] | undefined {
3493
3493
const container = getParentOfSymbol(symbol);
3494
3494
// Type parameters end up in the `members` lists but are not externally visible
3495
3495
if (container && !(symbol.flags & SymbolFlags.TypeParameter)) {
3496
3496
const additionalContainers = mapDefined(container.declarations, fileSymbolIfFileSymbolExportEqualsContainer);
3497
3497
const reexportContainers = enclosingDeclaration && getAlternativeContainingModules(symbol, enclosingDeclaration);
3498
+ const objectLiteralContainer = getVariableDeclarationOfObjectLiteral(container, meaning);
3498
3499
if (enclosingDeclaration && getAccessibleSymbolChain(container, enclosingDeclaration, SymbolFlags.Namespace, /*externalOnly*/ false)) {
3499
- return concatenate(concatenate([container], additionalContainers), reexportContainers); // This order expresses a preference for the real container if it is in scope
3500
+ return append( concatenate(concatenate([container], additionalContainers), reexportContainers), objectLiteralContainer ); // This order expresses a preference for the real container if it is in scope
3500
3501
}
3501
- const res = append(additionalContainers, container);
3502
+ const res = append(append( additionalContainers, container), objectLiteralContainer );
3502
3503
return concatenate(res, reexportContainers);
3503
3504
}
3504
3505
const candidates = mapDefined(symbol.declarations, d => {
@@ -3523,6 +3524,18 @@ namespace ts {
3523
3524
}
3524
3525
}
3525
3526
3527
+ function getVariableDeclarationOfObjectLiteral(symbol: Symbol, meaning: SymbolFlags) {
3528
+ // If we're trying to reference some object literal in, eg `var a = { x: 1 }`, the symbol for the literal, `__object`, is distinct
3529
+ // from the symbol of the declaration it is being assigned to. Since we can use the declaration to refer to the literal, however,
3530
+ // we'd like to make that connection here - potentially causing us to paint the declaration's visibility, and therefore the literal.
3531
+ const firstDecl: Node | false = !!length(symbol.declarations) && first(symbol.declarations);
3532
+ if (meaning & SymbolFlags.Value && firstDecl && firstDecl.parent && isVariableDeclaration(firstDecl.parent)) {
3533
+ if (isObjectLiteralExpression(firstDecl) && firstDecl === firstDecl.parent.initializer || isTypeLiteralNode(firstDecl) && firstDecl === firstDecl.parent.type) {
3534
+ return getSymbolOfNode(firstDecl.parent);
3535
+ }
3536
+ }
3537
+ }
3538
+
3526
3539
function getFileSymbolIfFileSymbolExportEqualsContainer(d: Declaration, container: Symbol) {
3527
3540
const fileSymbol = getExternalModuleContainer(d);
3528
3541
const exported = fileSymbol && fileSymbol.exports && fileSymbol.exports.get(InternalSymbolName.ExportEquals);
@@ -3916,16 +3929,7 @@ namespace ts {
3916
3929
// But it can't, hence the accessible is going to be undefined, but that doesn't mean m.c is inaccessible
3917
3930
// It is accessible if the parent m is accessible because then m.c can be accessed through qualification
3918
3931
3919
- let containers = getContainersOfSymbol(symbol, enclosingDeclaration);
3920
- // If we're trying to reference some object literal in, eg `var a = { x: 1 }`, the symbol for the literal, `__object`, is distinct
3921
- // from the symbol of the declaration it is being assigned to. Since we can use the declaration to refer to the literal, however,
3922
- // we'd like to make that connection here - potentially causing us to paint the declaration's visibility, and therefore the literal.
3923
- const firstDecl: Node | false = !!length(symbol.declarations) && first(symbol.declarations);
3924
- if (!length(containers) && meaning & SymbolFlags.Value && firstDecl && isObjectLiteralExpression(firstDecl)) {
3925
- if (firstDecl.parent && isVariableDeclaration(firstDecl.parent) && firstDecl === firstDecl.parent.initializer) {
3926
- containers = [getSymbolOfNode(firstDecl.parent)];
3927
- }
3928
- }
3932
+ const containers = getContainersOfSymbol(symbol, enclosingDeclaration, meaning);
3929
3933
const parentResult = isAnySymbolAccessible(containers, enclosingDeclaration, initialSymbol, initialSymbol === symbol ? getQualifiedLeftMeaning(meaning) : meaning, shouldComputeAliasesToMakeVisible, allowModules);
3930
3934
if (parentResult) {
3931
3935
return parentResult;
@@ -4417,8 +4421,8 @@ namespace ts {
4417
4421
context.inferTypeParameters = (<ConditionalType>type).root.inferTypeParameters;
4418
4422
const extendsTypeNode = typeToTypeNodeHelper((<ConditionalType>type).extendsType, context);
4419
4423
context.inferTypeParameters = saveInferTypeParameters;
4420
- const trueTypeNode = typeToTypeNodeHelper (getTrueTypeFromConditionalType(<ConditionalType>type), context );
4421
- const falseTypeNode = typeToTypeNodeHelper (getFalseTypeFromConditionalType(<ConditionalType>type), context );
4424
+ const trueTypeNode = typeToTypeNodeOrCircularityElision (getTrueTypeFromConditionalType(<ConditionalType>type));
4425
+ const falseTypeNode = typeToTypeNodeOrCircularityElision (getFalseTypeFromConditionalType(<ConditionalType>type));
4422
4426
context.approximateLength += 15;
4423
4427
return factory.createConditionalTypeNode(checkTypeNode, extendsTypeNode, trueTypeNode, falseTypeNode);
4424
4428
}
@@ -4428,6 +4432,21 @@ namespace ts {
4428
4432
4429
4433
return Debug.fail("Should be unreachable.");
4430
4434
4435
+
4436
+ function typeToTypeNodeOrCircularityElision(type: Type) {
4437
+ if (type.flags & TypeFlags.Union) {
4438
+ if (context.visitedTypes && context.visitedTypes.has("" + getTypeId(type))) {
4439
+ if (!(context.flags & NodeBuilderFlags.AllowAnonymousIdentifier)) {
4440
+ context.encounteredError = true;
4441
+ context.tracker?.reportCyclicStructureError?.();
4442
+ }
4443
+ return createElidedInformationPlaceholder(context);
4444
+ }
4445
+ return visitAndTransformType(type, type => typeToTypeNodeHelper(type, context));
4446
+ }
4447
+ return typeToTypeNodeHelper(type, context);
4448
+ }
4449
+
4431
4450
function createMappedTypeNodeFromType(type: MappedType) {
4432
4451
Debug.assert(!!(type.flags & TypeFlags.Object));
4433
4452
const readonlyToken = type.declaration.readonlyToken ? <ReadonlyToken | PlusToken | MinusToken>factory.createToken(type.declaration.readonlyToken.kind) : undefined;
@@ -5135,7 +5154,7 @@ namespace ts {
5135
5154
needsQualification(accessibleSymbolChain[0], context.enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) {
5136
5155
5137
5156
// Go up and add our parent.
5138
- const parents = getContainersOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol, context.enclosingDeclaration);
5157
+ const parents = getContainersOfSymbol(accessibleSymbolChain ? accessibleSymbolChain[0] : symbol, context.enclosingDeclaration, meaning );
5139
5158
if (length(parents)) {
5140
5159
parentSpecifiers = parents!.map(symbol =>
5141
5160
some(symbol.declarations, hasNonGlobalAugmentationExternalModuleSymbol)
@@ -13072,10 +13091,12 @@ namespace ts {
13072
13091
return links.resolvedType;
13073
13092
}
13074
13093
13075
- function createIndexedAccessType(objectType: Type, indexType: Type) {
13094
+ function createIndexedAccessType(objectType: Type, indexType: Type, aliasSymbol: Symbol | undefined, aliasTypeArguments: readonly Type[] | undefined ) {
13076
13095
const type = <IndexedAccessType>createType(TypeFlags.IndexedAccess);
13077
13096
type.objectType = objectType;
13078
13097
type.indexType = indexType;
13098
+ type.aliasSymbol = aliasSymbol;
13099
+ type.aliasTypeArguments = aliasTypeArguments;
13079
13100
return type;
13080
13101
}
13081
13102
@@ -13410,11 +13431,11 @@ namespace ts {
13410
13431
return instantiateType(getTemplateTypeFromMappedType(objectType), templateMapper);
13411
13432
}
13412
13433
13413
- function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression): Type {
13414
- return getIndexedAccessTypeOrUndefined(objectType, indexType, accessNode, AccessFlags.None) || (accessNode ? errorType : unknownType);
13434
+ function getIndexedAccessType(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[] ): Type {
13435
+ return getIndexedAccessTypeOrUndefined(objectType, indexType, accessNode, AccessFlags.None, aliasSymbol, aliasTypeArguments ) || (accessNode ? errorType : unknownType);
13415
13436
}
13416
13437
13417
- function getIndexedAccessTypeOrUndefined(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression, accessFlags = AccessFlags.None): Type | undefined {
13438
+ function getIndexedAccessTypeOrUndefined(objectType: Type, indexType: Type, accessNode?: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression, accessFlags = AccessFlags.None, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[] ): Type | undefined {
13418
13439
if (objectType === wildcardType || indexType === wildcardType) {
13419
13440
return wildcardType;
13420
13441
}
@@ -13436,7 +13457,7 @@ namespace ts {
13436
13457
const id = objectType.id + "," + indexType.id;
13437
13458
let type = indexedAccessTypes.get(id);
13438
13459
if (!type) {
13439
- indexedAccessTypes.set(id, type = createIndexedAccessType(objectType, indexType));
13460
+ indexedAccessTypes.set(id, type = createIndexedAccessType(objectType, indexType, aliasSymbol, aliasTypeArguments ));
13440
13461
}
13441
13462
return type;
13442
13463
}
@@ -13464,7 +13485,7 @@ namespace ts {
13464
13485
if (wasMissingProp) {
13465
13486
return undefined;
13466
13487
}
13467
- return accessFlags & AccessFlags.Writing ? getIntersectionType(propTypes) : getUnionType(propTypes);
13488
+ return accessFlags & AccessFlags.Writing ? getIntersectionType(propTypes, aliasSymbol, aliasTypeArguments ) : getUnionType(propTypes, UnionReduction.Literal, aliasSymbol, aliasTypeArguments );
13468
13489
}
13469
13490
return getPropertyTypeForIndexType(objectType, apparentObjectType, indexType, indexType, /* supressNoImplicitAnyError */ false, accessNode, accessFlags | AccessFlags.CacheSymbol);
13470
13491
}
@@ -13474,7 +13495,8 @@ namespace ts {
13474
13495
if (!links.resolvedType) {
13475
13496
const objectType = getTypeFromTypeNode(node.objectType);
13476
13497
const indexType = getTypeFromTypeNode(node.indexType);
13477
- const resolved = getIndexedAccessType(objectType, indexType, node);
13498
+ const potentialAlias = getAliasSymbolForTypeNode(node);
13499
+ const resolved = getIndexedAccessType(objectType, indexType, node, potentialAlias, getTypeArgumentsForAliasSymbol(potentialAlias));
13478
13500
links.resolvedType = resolved.flags & TypeFlags.IndexedAccess &&
13479
13501
(<IndexedAccessType>resolved).objectType === objectType &&
13480
13502
(<IndexedAccessType>resolved).indexType === indexType ?
@@ -14631,7 +14653,7 @@ namespace ts {
14631
14653
return getIndexType(instantiateType((<IndexType>type).type, mapper));
14632
14654
}
14633
14655
if (flags & TypeFlags.IndexedAccess) {
14634
- return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper));
14656
+ return getIndexedAccessType(instantiateType((<IndexedAccessType>type).objectType, mapper), instantiateType((<IndexedAccessType>type).indexType, mapper), /*accessNode*/ undefined, type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper) );
14635
14657
}
14636
14658
if (flags & TypeFlags.Conditional) {
14637
14659
return getConditionalTypeInstantiation(<ConditionalType>type, combineTypeMappers((<ConditionalType>type).mapper, mapper));
@@ -22689,7 +22711,7 @@ namespace ts {
22689
22711
const id = lhs.expression;
22690
22712
const parentSymbol = resolveName(id, id.escapedText, SymbolFlags.Value, undefined, id.escapedText, /*isUse*/ true);
22691
22713
if (parentSymbol) {
22692
- const annotated = getEffectiveTypeAnnotationNode(parentSymbol.valueDeclaration);
22714
+ const annotated = parentSymbol.valueDeclaration && getEffectiveTypeAnnotationNode(parentSymbol.valueDeclaration);
22693
22715
if (annotated) {
22694
22716
const nameStr = getElementOrPropertyAccessName(lhs);
22695
22717
if (nameStr !== undefined) {
@@ -36194,15 +36216,16 @@ namespace ts {
36194
36216
// Emitter support
36195
36217
36196
36218
function isArgumentsLocalBinding(nodeIn: Identifier): boolean {
36197
- if (!isGeneratedIdentifier(nodeIn)) {
36198
- const node = getParseTreeNode(nodeIn, isIdentifier);
36199
- if (node) {
36200
- const isPropertyName = node.parent.kind === SyntaxKind.PropertyAccessExpression && (<PropertyAccessExpression>node.parent).name === node;
36201
- return !isPropertyName && getReferencedValueSymbol(node) === argumentsSymbol;
36202
- }
36203
- }
36204
-
36205
- return false;
36219
+ // Note: does not handle isShorthandPropertyAssignment (and probably a few more)
36220
+ if (isGeneratedIdentifier(nodeIn)) return false;
36221
+ const node = getParseTreeNode(nodeIn, isIdentifier);
36222
+ if (!node) return false;
36223
+ const parent = node.parent;
36224
+ if (!parent) return false;
36225
+ const isPropertyName = ((isPropertyAccessExpression(parent)
36226
+ || isPropertyAssignment(parent))
36227
+ && parent.name === node);
36228
+ return !isPropertyName && getReferencedValueSymbol(node) === argumentsSymbol;
36206
36229
}
36207
36230
36208
36231
function moduleExportsSomeValue(moduleReferenceExpression: Expression): boolean {
0 commit comments