Skip to content

Commit 1c7250e

Browse files
committed
feat: namespace files support for export patterns and imports
1 parent 1da83dc commit 1c7250e

File tree

2 files changed

+58
-3
lines changed

2 files changed

+58
-3
lines changed

src/project/plugins/file-plugins/files/flowr-namespace-file.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import type { FileRole, FlowrFileProvider } from '../../../context/flowr-file';
22
import { FlowrFile } from '../../../context/flowr-file';
3+
import { unquoteArgument } from '../../../../abstract-interpretation/data-frame/resolve-args';
34

45
export interface NamespaceInfo {
56
exportedSymbols: string[];
67
exportedFunctions: string[];
78
exportS3Generics: Map<string, string[]>;
9+
exportedPatterns?: string[];
10+
importedPackages?: Map<string, string[] | 'all'>;
811
loadsWithSideEffects: boolean;
912
}
1013

@@ -59,6 +62,8 @@ function parseNamespace(file: FlowrFileProvider): NamespaceFormat {
5962
exportedSymbols: [] as string[],
6063
exportedFunctions: [] as string[],
6164
exportS3Generics: new Map<string, string[]>(),
65+
exportedPatterns: [] as string[],
66+
importedPackages: new Map<string, string[] | 'all'>(),
6267
loadsWithSideEffects: false,
6368
},
6469
} as NamespaceFormat;
@@ -107,12 +112,37 @@ function parseNamespace(file: FlowrFileProvider): NamespaceFormat {
107112
exportedSymbols: [],
108113
exportedFunctions: [],
109114
exportS3Generics: new Map<string, string[]>(),
115+
exportedPatterns: [],
116+
importedPackages: new Map<string, string[] | 'all'>(),
110117
loadsWithSideEffects: false,
111118
};
112119
}
113120
result[pkg].loadsWithSideEffects = true;
114121
break;
115122
}
123+
case 'import': {
124+
const pkg = args.trim();
125+
result.current.importedPackages?.set(pkg, 'all');
126+
break;
127+
}
128+
case 'importFrom': {
129+
const parts = args.split(',').map(s => s.trim());
130+
if(parts.length < 2) {
131+
continue;
132+
}
133+
const [pkg, ...symbols] = parts;
134+
let arr = result.current.importedPackages?.get(pkg);
135+
if(!arr || arr === 'all') {
136+
arr = [];
137+
result.current.importedPackages?.set(pkg, arr);
138+
}
139+
arr.push(...symbols);
140+
break;
141+
}
142+
case 'exportPattern': {
143+
result.current.exportedPatterns?.push(unquoteArgument(args.trim()));
144+
break;
145+
}
116146
}
117147
}
118148

test/functionality/project/plugin/namespace-file.test.ts

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export(coord_cartesian)
4343
export(ggsave)
4444
export(fortify)
4545
export(scale_type)
46+
exportPattern("^[^\\.].*")
4647
import(grid)
4748
import(rlang)
4849
importFrom(scales,alpha)
@@ -52,7 +53,7 @@ importFrom(stats,setNames)`));
5253
ctx.addRequests([{ request: 'file', content: 'test.R' }]);
5354
ctx.resolvePreAnalysis();
5455

55-
describe.sequential('Basic exports', function() {
56+
describe('Basic exports', function() {
5657
test('Functions are exported', () => {
5758
const deps = ctx.deps.getDependency('current');
5859
assert.isDefined(deps);
@@ -74,9 +75,16 @@ importFrom(stats,setNames)`));
7475
assert.isTrue(deps.namespaceInfo?.exportedSymbols.includes('coord_cartesian'));
7576
assert.isTrue(deps.namespaceInfo?.exportedSymbols.includes('ggsave'));
7677
});
78+
79+
test('Export pattern registered', () => {
80+
const deps = ctx.deps.getDependency('current');
81+
assert.isDefined(deps);
82+
assert.strictEqual(deps.namespaceInfo?.exportedPatterns?.length, 1);
83+
assert.strictEqual(deps.namespaceInfo?.exportedPatterns?.[0], '^[^\\.].*');
84+
});
7785
});
7886

79-
describe.sequential('S3 methods - fortify', function() {
87+
describe('S3 methods - fortify', function() {
8088
test('All fortify methods registered in namespaceInfo', () => {
8189
const deps = ctx.deps.getDependency('current');
8290
assert.isDefined(deps);
@@ -100,7 +108,24 @@ importFrom(stats,setNames)`));
100108
});
101109
});
102110

103-
describe.sequential('Mixed exports and S3', function() {
111+
describe('Correct Imports', function() {
112+
test('Imports are registered correctly', () => {
113+
const deps = ctx.deps.getDependency('current');
114+
assert.isDefined(deps);
115+
116+
assert.isTrue(deps.namespaceInfo?.importedPackages?.has('grid'));
117+
assert.isTrue(deps.namespaceInfo?.importedPackages?.has('rlang'));
118+
assert.isTrue(deps.namespaceInfo?.importedPackages?.has('scales'));
119+
assert.isTrue(deps.namespaceInfo?.importedPackages?.has('stats'));
120+
121+
assert.strictEqual(deps.namespaceInfo?.importedPackages?.get('grid'), 'all');
122+
assert.strictEqual(deps.namespaceInfo?.importedPackages?.get('rlang'), 'all');
123+
assert.deepEqual(deps.namespaceInfo?.importedPackages?.get('scales'), ['alpha']);
124+
assert.deepEqual(deps.namespaceInfo?.importedPackages?.get('stats'), ['setNames']);
125+
});
126+
});
127+
128+
describe('Mixed exports and S3', function() {
104129
test('ggplot has export and S3 method', () => {
105130
const deps = ctx.deps.getDependency('current');
106131
assert.isDefined(deps);

0 commit comments

Comments
 (0)