@@ -2837,6 +2837,11 @@ namespace ts {
28372837 isDeclarationVisible(declaration.parent.parent.parent)) {
28382838 return addVisibleAlias(declaration, declaration.parent.parent);
28392839 }
2840+ else if (isLateVisibilityPaintedStatement(declaration) // unexported top-level statement
2841+ && !hasModifier(declaration, ModifierFlags.Export)
2842+ && isDeclarationVisible(declaration.parent)) {
2843+ return addVisibleAlias(declaration, declaration);
2844+ }
28402845
28412846 // Declaration is not visible
28422847 return false;
@@ -3694,7 +3699,17 @@ namespace ts {
36943699 return typeParameterNodes;
36953700 }
36963701
3697- function symbolToTypeNode(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags): TypeQueryNode | TypeReferenceNode | ImportTypeNode {
3702+ /**
3703+ * Given A[B][C][D], finds A[B]
3704+ */
3705+ function getTopmostIndexedAccessType(top: IndexedAccessTypeNode): IndexedAccessTypeNode {
3706+ if (isIndexedAccessTypeNode(top.objectType)) {
3707+ return getTopmostIndexedAccessType(top.objectType);
3708+ }
3709+ return top;
3710+ }
3711+
3712+ function symbolToTypeNode(symbol: Symbol, context: NodeBuilderContext, meaning: SymbolFlags): TypeNode {
36983713 const chain = lookupSymbolChain(symbol, context, meaning);
36993714
37003715 context.flags |= NodeBuilderFlags.InInitialEntityName;
@@ -3704,15 +3719,26 @@ namespace ts {
37043719 const isTypeOf = meaning === SymbolFlags.Value;
37053720 if (ambientModuleSymbolRegex.test(rootName)) {
37063721 // module is root, must use `ImportTypeNode`
3707- const nonRootParts = chain.length > 1 ? createEntityNameFromSymbolChain (chain, chain.length - 1, 1) : undefined;
3722+ const nonRootParts = chain.length > 1 ? createAccessFromSymbolChain (chain, chain.length - 1, 1) : undefined;
37083723 const typeParameterNodes = lookupTypeParameterNodes(chain, 0, context);
3709- return createImportTypeNode(createLiteralTypeNode(createLiteral(rootName.substring(1, rootName.length - 1))), nonRootParts, typeParameterNodes as ReadonlyArray<TypeNode>, isTypeOf);
3724+ const lit = createLiteralTypeNode(createLiteral(rootName.substring(1, rootName.length - 1)));
3725+ if (!nonRootParts || isEntityName(nonRootParts)) {
3726+ return createImportTypeNode(lit, nonRootParts as EntityName, typeParameterNodes as ReadonlyArray<TypeNode>, isTypeOf);
3727+ }
3728+ else {
3729+ const splitNode = getTopmostIndexedAccessType(nonRootParts);
3730+ const qualifier = (splitNode.objectType as TypeReferenceNode).typeName;
3731+ return createIndexedAccessTypeNode(createImportTypeNode(lit, qualifier, typeParameterNodes as ReadonlyArray<TypeNode>, isTypeOf), splitNode.indexType);
3732+ }
37103733 }
37113734
3712- const entityName = createEntityNameFromSymbolChain(chain, chain.length - 1, 0);
3735+ const entityName = createAccessFromSymbolChain(chain, chain.length - 1, 0);
3736+ if (isIndexedAccessTypeNode(entityName)) {
3737+ return entityName; // Indexed accesses can never be `typeof`
3738+ }
37133739 return isTypeOf ? createTypeQueryNode(entityName) : createTypeReferenceNode(entityName, /*typeArguments*/ undefined);
37143740
3715- function createEntityNameFromSymbolChain (chain: Symbol[], index: number, stopper: number): EntityName {
3741+ function createAccessFromSymbolChain (chain: Symbol[], index: number, stopper: number): EntityName | IndexedAccessTypeNode {
37163742 const typeParameterNodes = lookupTypeParameterNodes(chain, index, context);
37173743 const symbol = chain[index];
37183744
@@ -3723,10 +3749,30 @@ namespace ts {
37233749 if (index === 0) {
37243750 context.flags ^= NodeBuilderFlags.InInitialEntityName;
37253751 }
3752+
3753+ const parent = chain[index - 1];
3754+ if (parent && getMembersOfSymbol(parent) && getMembersOfSymbol(parent).get(symbol.escapedName) === symbol) {
3755+ // Should use an indexed access
3756+ const LHS = createAccessFromSymbolChain(chain, index - 1, stopper);
3757+ if (isIndexedAccessTypeNode(LHS)) {
3758+ return createIndexedAccessTypeNode(LHS, createLiteralTypeNode(createLiteral(symbolName)));
3759+ }
3760+ else {
3761+ return createIndexedAccessTypeNode(createTypeReferenceNode(LHS, typeParameterNodes as ReadonlyArray<TypeNode>), createLiteralTypeNode(createLiteral(symbolName)));
3762+ }
3763+ }
3764+
37263765 const identifier = setEmitFlags(createIdentifier(symbolName, typeParameterNodes), EmitFlags.NoAsciiEscaping);
37273766 identifier.symbol = symbol;
37283767
3729- return index > stopper ? createQualifiedName(createEntityNameFromSymbolChain(chain, index - 1, stopper), identifier) : identifier;
3768+ if (index > stopper) {
3769+ const LHS = createAccessFromSymbolChain(chain, index - 1, stopper);
3770+ if (!isEntityName(LHS)) {
3771+ return Debug.fail("Impossible construct - an export of an indexed access cannot be reachable");
3772+ }
3773+ return createQualifiedName(LHS, identifier);
3774+ }
3775+ return identifier;
37303776 }
37313777 }
37323778
@@ -26598,7 +26644,22 @@ namespace ts {
2659826644 const symbol = node && getSymbolOfNode(node);
2659926645 return !!(symbol && getCheckFlags(symbol) & CheckFlags.Late);
2660026646 },
26601- getJsxFactoryEntity: location => location ? (getJsxNamespace(location), (getSourceFileOfNode(location).localJsxFactory || _jsxFactoryEntity)) : _jsxFactoryEntity
26647+ getJsxFactoryEntity: location => location ? (getJsxNamespace(location), (getSourceFileOfNode(location).localJsxFactory || _jsxFactoryEntity)) : _jsxFactoryEntity,
26648+ getAllAccessorDeclarations(accessor: AccessorDeclaration): AllAccessorDeclarations {
26649+ accessor = getParseTreeNode(accessor, isGetOrSetAccessorDeclaration);
26650+ const otherKind = accessor.kind === SyntaxKind.SetAccessor ? SyntaxKind.GetAccessor : SyntaxKind.SetAccessor;
26651+ const otherAccessor = getDeclarationOfKind<AccessorDeclaration>(getSymbolOfNode(accessor), otherKind);
26652+ const firstAccessor = otherAccessor && (otherAccessor.pos < accessor.pos) ? otherAccessor : accessor;
26653+ const secondAccessor = otherAccessor && (otherAccessor.pos < accessor.pos) ? accessor : otherAccessor;
26654+ const setAccessor = accessor.kind === SyntaxKind.SetAccessor ? accessor : otherAccessor;
26655+ const getAccessor = accessor.kind === SyntaxKind.GetAccessor ? accessor : otherAccessor;
26656+ return {
26657+ firstAccessor,
26658+ secondAccessor,
26659+ setAccessor,
26660+ getAccessor
26661+ };
26662+ }
2660226663 };
2660326664
2660426665 function isInHeritageClause(node: PropertyAccessEntityNameExpression) {
0 commit comments