Skip to content

Commit 01c5e4b

Browse files
committed
optimize eclipse importer
1 parent a3f4e58 commit 01c5e4b

1 file changed

Lines changed: 92 additions & 25 deletions

File tree

src/EclipseProjectParser.ts

Lines changed: 92 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
127127
if (!node) throw new Error(`not found: '<storageModule moduleId="org.eclipse.cdt.core.settings">'`);
128128
cprjDom = node;
129129

130+
const root_virtualsrcs: string[] = [];
131+
const root_srcdirs: string[] = [];
132+
const eclipseTargetList: string[] = [];
133+
130134
// parse all project targets
131135
for (const ccfg of toArray(cprjDom['cconfiguration'])) {
132136

@@ -152,6 +156,8 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
152156

153157
cTarget = cTarget['configuration'][0];
154158

159+
eclipseTargetList.push(cTarget.$['name']);
160+
155161
const tInfo: EclipseProjectTarget = {
156162
name: cTarget.$['name'].replace(/\s+/g, '_'),
157163
excList: [],
@@ -257,6 +263,7 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
257263
}
258264

259265
if (cTarget.sourceEntries) {
266+
260267
toArray(cTarget.sourceEntries[0].entry).forEach(e => {
261268

262269
//<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="src" />
@@ -266,13 +273,13 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
266273
const srcs = cprojectDir.GetList(SRC_FILE_FILTER, [/^[^\.].+/]);
267274
srcs.forEach(src => {
268275
if (src.IsFile()) {
269-
PROJ_INFO.virtualSource.files.push({ path: src.name });
276+
root_virtualsrcs.push(src.name);
270277
} else {
271-
PROJ_INFO.sourceEntries.push(src.name);
278+
root_srcdirs.push(src.name);
272279
}
273280
});
274281
} else {
275-
PROJ_INFO.sourceEntries.push(srcdir);
282+
root_srcdirs.push(srcdir);
276283
}
277284
}
278285

@@ -285,6 +292,15 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
285292
}
286293
}
287294

295+
// setup root sources
296+
ArrayDelRepetition(root_virtualsrcs).forEach(srcpath => {
297+
PROJ_INFO.virtualSource.files.push({ path: srcpath });
298+
});
299+
ArrayDelRepetition(root_srcdirs).forEach(srcdir => {
300+
if (eclipseTargetList.includes(srcdir)) return; // skip eclipse build dir
301+
PROJ_INFO.sourceEntries.push(srcdir);
302+
});
303+
288304
const getVirtualFolder = (rePath: string) => {
289305

290306
rePath = rePath.trim()
@@ -319,6 +335,7 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
319335
};
320336

321337
const virtualRootList: string[] = [];
338+
const virtualRootMap: { [vpath: string]: string } = {};
322339

323340
// parse external source
324341
if (_prjDom.linkedResources) {
@@ -337,12 +354,14 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
337354
const location: string = locations[0];
338355
if (typeof location != 'string') return;
339356
virtualRootList.push(vpath);
340-
let rootdirpath = formatFilePath(location);
341-
if (!File.isAbsolute(rootdirpath)) rootdirpath = `${cprojectDir.path}/${rootdirpath}`;
357+
const rootdirpath_ = formatFilePath(location);
358+
let rootdirfullpath = rootdirpath_;
359+
if (!File.isAbsolute(rootdirpath_)) rootdirfullpath = `${cprojectDir.path}/${rootdirpath_}`;
342360
let vFolder = getVirtualFolder(vpath); // add this folder
343-
if (File.IsDir(rootdirpath)) {
344-
const files = new File(rootdirpath).GetAll(SRC_FILE_FILTER, File.EXCLUDE_ALL_FILTER);
345-
const srcRootDir = new File(rootdirpath);
361+
if (File.IsDir(rootdirfullpath)) {
362+
virtualRootMap[vpath] = File.ToUnixPath(rootdirpath_);
363+
const files = new File(rootdirfullpath).GetAll(SRC_FILE_FILTER, File.EXCLUDE_ALL_FILTER);
364+
const srcRootDir = new File(rootdirfullpath);
346365
files.forEach(f => {
347366
let subvpath = vpath;
348367
const dirname = srcRootDir.ToRelativePath(f.dir);
@@ -355,22 +374,36 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
355374
});
356375
}
357376

358-
// del repeat args for every targets
359-
for (const target of PROJ_INFO.targets) {
360-
361-
target.excList = ArrayDelRepetition(target.excList);
362-
363-
// rename virtual exclude paths
364-
const excli: string[] = [];
365-
target.excList.forEach(p => {
377+
const completeVirtualPaths = (pathlist: string[]): string[] => {
378+
return pathlist.map(p => {
366379
if (virtualRootList.includes(p) || virtualRootList.some(e => p.startsWith(e + '/'))) {
367-
excli.push(`${VirtualSource.rootName}/${p}`);
380+
return `${VirtualSource.rootName}/${p}`;
368381
} else {
369-
excli.push(p);
382+
return p;
383+
}
384+
});
385+
};
386+
387+
const resolveVirtualPaths = (pathlist: string[]): string[] => {
388+
return pathlist.map(p => {
389+
for (const rootpath of virtualRootList) {
390+
if ((rootpath == p || p.startsWith(rootpath + '/')) && virtualRootMap[rootpath]) {
391+
return p.replace(rootpath, virtualRootMap[rootpath]);
392+
}
370393
}
394+
return p;
371395
});
396+
};
397+
398+
// del repeat args for every targets
399+
for (const target of PROJ_INFO.targets) {
400+
401+
// add prefix for virtual exclude paths
402+
target.excList = completeVirtualPaths(ArrayDelRepetition(target.excList));
372403

373-
target.excList = excli;
404+
// resolve virtual include paths
405+
target.globalArgs.cIncDirs = resolveVirtualPaths(target.globalArgs.cIncDirs);
406+
target.globalArgs.sIncDirs = resolveVirtualPaths(target.globalArgs.sIncDirs);
374407

375408
for (const key in target.globalArgs) {
376409
const obj: any = target.globalArgs;
@@ -394,9 +427,6 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
394427

395428
function parseToolOption(optionObj: any): { type: string, val: string[] } | undefined {
396429

397-
if (optionObj.$['valueType'] == undefined)
398-
return;
399-
400430
if (optionObj.$['id']) {
401431
// skip output args
402432
if (['.converthex', '.convertbin', '.convert']
@@ -409,13 +439,13 @@ function parseToolOption(optionObj: any): { type: string, val: string[] } | unde
409439

410440
const VALUE_NAME: string = optionObj.$['name'] || '';
411441
const VALUE_VAL: string = optionObj.$['value'] || '';
412-
const VALUE_TYPE: string = optionObj.$['valueType'];
442+
const VALUE_TYPE: string | undefined = optionObj.$['valueType'];
413443

414-
let makeResult = (value: string | string[]): { type: string, val: string[] } | undefined => {
444+
let makeResult = (value: string | string[], typ?: string): { type: string, val: string[] } | undefined => {
415445
if (value == '') return undefined;
416446
if (isArray(value) && value.length == 0) return undefined;
417447
return {
418-
type: VALUE_TYPE,
448+
type: typ || VALUE_TYPE || '',
419449
val: isArray(value) ? value : [value]
420450
};
421451
};
@@ -429,6 +459,43 @@ function parseToolOption(optionObj: any): { type: string, val: string[] } | unde
429459
return fmt + arg;
430460
}
431461

462+
//
463+
// match by name
464+
//
465+
466+
// <Language Standard> = option.std.gnu99
467+
if (/Language Standard/i.test(VALUE_NAME)) {
468+
const m = /std\.(\w+)/.exec(VALUE_VAL);
469+
if (m && m.length > 1) {
470+
const langStd = m[1];
471+
return makeResult(`-std=${langStd}`, 'string');
472+
}
473+
}
474+
475+
if (VALUE_NAME.includes('(-D)')) {
476+
const li: string[] = [];
477+
toArray(optionObj.listOptionValue).forEach(item => li.push(item.$['value']));
478+
return makeResult(li, 'definedSymbols');
479+
}
480+
481+
if (VALUE_NAME.includes('(-I)')) {
482+
const li: string[] = [];
483+
toArray(optionObj.listOptionValue).forEach(item => {
484+
let p = formatFilePath(item.$['value']);
485+
if (p == '..') p = '.';
486+
if (p.startsWith('../')) p = p.substr(3); // for eclipse, include path is base 'Debug' folder
487+
li.push(p);
488+
});
489+
return makeResult(li, 'includePath');
490+
}
491+
492+
//
493+
// match by type
494+
//
495+
496+
if (VALUE_TYPE == undefined)
497+
return;
498+
432499
if (VALUE_TYPE == 'boolean') {
433500
if (VALUE_VAL == 'true') {
434501
const mRes = /\((\-.+)\)/.exec(VALUE_NAME);

0 commit comments

Comments
 (0)