Skip to content

Commit e179c58

Browse files
Ayaz HafizAndrewKushnir
Ayaz Hafiz
authored andcommitted
fix(compiler): do not recurse to find static symbols of same module (angular#35262)
To create the symbols of a module, the static symbol resolver first gets all the symbols loaded in the module by an export statement. For `export * from './module'`-like statements, all symbols from `./module` must be loaded. In cases where the exporting module is actually the same module that the export statement is in, this causes an unbounded recursive resolution of the same module. Exports of the same module are not needed, as their symbols will be resolved when the symbols in the module metadata's `metadata` key is explored. This commit resolves the unbounded recursion by loading exporting modules only if they differ from the module currently being resolved. Closes angular/vscode-ng-language-service#593 PR Close angular#35262
1 parent 79659ee commit e179c58

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

packages/compiler/src/aot/static_symbol_resolver.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,9 +313,9 @@ export class StaticSymbolResolver {
313313
}
314314
});
315315
} else {
316-
// handle the symbols via export * directives.
316+
// Handle the symbols loaded by 'export *' directives.
317317
const resolvedModule = this.resolveModule(moduleExport.from, filePath);
318-
if (resolvedModule) {
318+
if (resolvedModule && resolvedModule !== filePath) {
319319
const nestedExports = this.getSymbolsOf(resolvedModule);
320320
nestedExports.forEach((targetSymbol) => {
321321
const sourceSymbol = this.getStaticSymbol(filePath, targetSymbol.name);

packages/compiler/test/aot/static_symbol_resolver_spec.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ import * as ts from 'typescript';
1515
const TS_EXT = /(^.|(?!\.d)..)\.ts$/;
1616

1717
describe('StaticSymbolResolver', () => {
18-
const noContext = new StaticSymbol('', '', []);
1918
let host: StaticSymbolResolverHost;
2019
let symbolResolver: StaticSymbolResolver;
2120
let symbolCache: StaticSymbolCache;
@@ -103,6 +102,19 @@ describe('StaticSymbolResolver', () => {
103102
.toBe(symbolResolver.getStaticSymbol('/tmp/src/export.ts', 'exportedObj', ['someMember']));
104103
});
105104

105+
it('should not explore re-exports of the same module', () => {
106+
init({
107+
'/tmp/src/test.ts': `
108+
export * from './test';
109+
110+
export const testValue = 10;
111+
`,
112+
});
113+
114+
const symbols = symbolResolver.getSymbolsOf('/tmp/src/test.ts');
115+
expect(symbols).toEqual([symbolResolver.getStaticSymbol('/tmp/src/test.ts', 'testValue')]);
116+
});
117+
106118
it('should use summaries in resolveSymbol and prefer them over regular metadata', () => {
107119
const symbolA = symbolCache.get('/test.ts', 'a');
108120
const symbolB = symbolCache.get('/test.ts', 'b');
@@ -140,7 +152,6 @@ describe('StaticSymbolResolver', () => {
140152

141153
it('should read the exported symbols of a file from the summary and ignore exports in the source',
142154
() => {
143-
const someSymbol = symbolCache.get('/test.ts', 'a');
144155
init(
145156
{'/test.ts': 'export var b = 2'},
146157
[{symbol: symbolCache.get('/test.ts', 'a'), metadata: 1}]);

0 commit comments

Comments
 (0)