Skip to content

Commit bab287d

Browse files
author
Andy
authored
Simplify getAccessibleSymbolChain (#18053)
1 parent 117ef21 commit bab287d

File tree

1 file changed

+44
-52
lines changed

1 file changed

+44
-52
lines changed

src/compiler/checker.ts

+44-52
Original file line numberDiff line numberDiff line change
@@ -2056,75 +2056,67 @@ namespace ts {
20562056
return rightMeaning === SymbolFlags.Value ? SymbolFlags.Value : SymbolFlags.Namespace;
20572057
}
20582058

2059-
function getAccessibleSymbolChain(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags, useOnlyExternalAliasing: boolean): Symbol[] {
2060-
function getAccessibleSymbolChainFromSymbolTable(symbols: SymbolTable) {
2061-
return getAccessibleSymbolChainFromSymbolTableWorker(symbols, []);
2059+
function getAccessibleSymbolChain(symbol: Symbol, enclosingDeclaration: Node, meaning: SymbolFlags, useOnlyExternalAliasing: boolean): Symbol[] | undefined {
2060+
if (!(symbol && !isPropertyOrMethodDeclarationSymbol(symbol))) {
2061+
return undefined;
20622062
}
20632063

2064-
function getAccessibleSymbolChainFromSymbolTableWorker(symbols: SymbolTable, visitedSymbolTables: SymbolTable[]): Symbol[] {
2064+
const visitedSymbolTables: SymbolTable[] = [];
2065+
return forEachSymbolTableInScope(enclosingDeclaration, getAccessibleSymbolChainFromSymbolTable);
2066+
2067+
function getAccessibleSymbolChainFromSymbolTable(symbols: SymbolTable): Symbol[] | undefined {
20652068
if (!pushIfUnique(visitedSymbolTables, symbols)) {
20662069
return undefined;
20672070
}
20682071

20692072
const result = trySymbolTable(symbols);
20702073
visitedSymbolTables.pop();
20712074
return result;
2075+
}
20722076

2073-
function canQualifySymbol(symbolFromSymbolTable: Symbol, meaning: SymbolFlags) {
2074-
// If the symbol is equivalent and doesn't need further qualification, this symbol is accessible
2075-
if (!needsQualification(symbolFromSymbolTable, enclosingDeclaration, meaning)) {
2076-
return true;
2077-
}
2078-
2077+
function canQualifySymbol(symbolFromSymbolTable: Symbol, meaning: SymbolFlags) {
2078+
// If the symbol is equivalent and doesn't need further qualification, this symbol is accessible
2079+
return !needsQualification(symbolFromSymbolTable, enclosingDeclaration, meaning) ||
20792080
// If symbol needs qualification, make sure that parent is accessible, if it is then this symbol is accessible too
2080-
const accessibleParent = getAccessibleSymbolChain(symbolFromSymbolTable.parent, enclosingDeclaration, getQualifiedLeftMeaning(meaning), useOnlyExternalAliasing);
2081-
return !!accessibleParent;
2082-
}
2083-
2084-
function isAccessible(symbolFromSymbolTable: Symbol, resolvedAliasSymbol?: Symbol) {
2085-
if (symbol === (resolvedAliasSymbol || symbolFromSymbolTable)) {
2086-
// if the symbolFromSymbolTable is not external module (it could be if it was determined as ambient external module and would be in globals table)
2087-
// and if symbolFromSymbolTable or alias resolution matches the symbol,
2088-
// check the symbol can be qualified, it is only then this symbol is accessible
2089-
return !forEach(symbolFromSymbolTable.declarations, hasExternalModuleSymbol) &&
2090-
canQualifySymbol(symbolFromSymbolTable, meaning);
2091-
}
2092-
}
2081+
!!getAccessibleSymbolChain(symbolFromSymbolTable.parent, enclosingDeclaration, getQualifiedLeftMeaning(meaning), useOnlyExternalAliasing);
2082+
}
20932083

2094-
function trySymbolTable(symbols: SymbolTable) {
2095-
// If symbol is directly available by its name in the symbol table
2096-
if (isAccessible(symbols.get(symbol.escapedName))) {
2097-
return [symbol];
2098-
}
2084+
function isAccessible(symbolFromSymbolTable: Symbol, resolvedAliasSymbol?: Symbol) {
2085+
return symbol === (resolvedAliasSymbol || symbolFromSymbolTable) &&
2086+
// if the symbolFromSymbolTable is not external module (it could be if it was determined as ambient external module and would be in globals table)
2087+
// and if symbolFromSymbolTable or alias resolution matches the symbol,
2088+
// check the symbol can be qualified, it is only then this symbol is accessible
2089+
!some(symbolFromSymbolTable.declarations, hasExternalModuleSymbol) &&
2090+
canQualifySymbol(symbolFromSymbolTable, meaning);
2091+
}
20992092

2100-
// Check if symbol is any of the alias
2101-
return forEachEntry(symbols, symbolFromSymbolTable => {
2102-
if (symbolFromSymbolTable.flags & SymbolFlags.Alias
2103-
&& symbolFromSymbolTable.escapedName !== "export="
2104-
&& !getDeclarationOfKind(symbolFromSymbolTable, SyntaxKind.ExportSpecifier)) {
2105-
if (!useOnlyExternalAliasing || // We can use any type of alias to get the name
2106-
// Is this external alias, then use it to name
2107-
ts.forEach(symbolFromSymbolTable.declarations, isExternalModuleImportEqualsDeclaration)) {
2093+
function trySymbolTable(symbols: SymbolTable) {
2094+
// If symbol is directly available by its name in the symbol table
2095+
if (isAccessible(symbols.get(symbol.escapedName))) {
2096+
return [symbol];
2097+
}
21082098

2109-
const resolvedImportedSymbol = resolveAlias(symbolFromSymbolTable);
2110-
if (isAccessible(symbolFromSymbolTable, resolvedImportedSymbol)) {
2111-
return [symbolFromSymbolTable];
2112-
}
2099+
// Check if symbol is any of the alias
2100+
return forEachEntry(symbols, symbolFromSymbolTable => {
2101+
if (symbolFromSymbolTable.flags & SymbolFlags.Alias
2102+
&& symbolFromSymbolTable.escapedName !== "export="
2103+
&& !getDeclarationOfKind(symbolFromSymbolTable, SyntaxKind.ExportSpecifier)
2104+
// If `!useOnlyExternalAliasing`, we can use any type of alias to get the name
2105+
&& (!useOnlyExternalAliasing || some(symbolFromSymbolTable.declarations, isExternalModuleImportEqualsDeclaration))) {
21132106

2114-
// Look in the exported members, if we can find accessibleSymbolChain, symbol is accessible using this chain
2115-
// but only if the symbolFromSymbolTable can be qualified
2116-
const accessibleSymbolsFromExports = resolvedImportedSymbol.exports ? getAccessibleSymbolChainFromSymbolTableWorker(resolvedImportedSymbol.exports, visitedSymbolTables) : undefined;
2117-
if (accessibleSymbolsFromExports && canQualifySymbol(symbolFromSymbolTable, getQualifiedLeftMeaning(meaning))) {
2118-
return [symbolFromSymbolTable].concat(accessibleSymbolsFromExports);
2119-
}
2120-
}
2107+
const resolvedImportedSymbol = resolveAlias(symbolFromSymbolTable);
2108+
if (isAccessible(symbolFromSymbolTable, resolvedImportedSymbol)) {
2109+
return [symbolFromSymbolTable];
21212110
}
2122-
});
2123-
}
2124-
}
21252111

2126-
if (symbol && !isPropertyOrMethodDeclarationSymbol(symbol)) {
2127-
return forEachSymbolTableInScope(enclosingDeclaration, getAccessibleSymbolChainFromSymbolTable);
2112+
// Look in the exported members, if we can find accessibleSymbolChain, symbol is accessible using this chain
2113+
// but only if the symbolFromSymbolTable can be qualified
2114+
const accessibleSymbolsFromExports = resolvedImportedSymbol.exports ? getAccessibleSymbolChainFromSymbolTable(resolvedImportedSymbol.exports) : undefined;
2115+
if (accessibleSymbolsFromExports && canQualifySymbol(symbolFromSymbolTable, getQualifiedLeftMeaning(meaning))) {
2116+
return [symbolFromSymbolTable].concat(accessibleSymbolsFromExports);
2117+
}
2118+
}
2119+
});
21282120
}
21292121
}
21302122

0 commit comments

Comments
 (0)