Skip to content

Commit d60990d

Browse files
Ayaz Hafizayazhafiz
Ayaz Hafiz
authored andcommitted
fix(compiler): do not recurse to find static symbols of same module
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
1 parent 13495c6 commit d60990d

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)