@@ -3,9 +3,10 @@ import * as NodePath from 'path';
33import * as os from 'os' ;
44import * as xml2js from 'xml2js' ;
55import { VirtualFolder } from './EIDETypeDefine' ;
6- import { VirtualSource } from './EIDEProject' ;
6+ import { VirtualSource , AbstractProject } from './EIDEProject' ;
77import { isArray } from 'util' ;
88import { ArrayDelRepetition } from '../lib/node-utility/Utility' ;
9+ import { File } from '../lib/node-utility/File' ;
910
1011export type EclipseProjectType = 'arm' | 'sdcc' | 'riscv' | 'gcc' ;
1112
@@ -104,6 +105,10 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
104105 let cprjDom = ( await xml2js . parseStringPromise (
105106 fs . readFileSync ( cprojectPath ) . toString ( ) ) ) [ 'cproject' ] ;
106107
108+ const cprojectDir = new File ( NodePath . dirname ( cprojectPath ) ) ;
109+
110+ const SRC_FILE_FILTER = AbstractProject . getSourceFileFilterWithoutObj ( ) . concat ( AbstractProject . headerFilter ) ;
111+
107112 const PROJ_INFO : EclipseProjectInfo = {
108113 name : _prjDom . name [ 0 ] . replace ( / \s + / g, '_' ) ,
109114 type : 'gcc' ,
@@ -256,7 +261,19 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
256261
257262 //<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="src" />
258263 if ( < string > e . $ [ 'kind' ] == 'sourcePath' ) {
259- PROJ_INFO . sourceEntries . push ( formatFilePath ( e . $ [ 'name' ] ) ) ;
264+ const srcdir = formatFilePath ( e . $ [ 'name' ] ) ;
265+ if ( srcdir == '.' || srcdir == '' ) {
266+ const srcs = cprojectDir . GetList ( SRC_FILE_FILTER , [ / ^ [ ^ \. ] .+ / ] ) ;
267+ srcs . forEach ( src => {
268+ if ( src . IsFile ( ) ) {
269+ PROJ_INFO . virtualSource . files . push ( { path : src . name } ) ;
270+ } else {
271+ PROJ_INFO . sourceEntries . push ( src . name ) ;
272+ }
273+ } ) ;
274+ } else {
275+ PROJ_INFO . sourceEntries . push ( srcdir ) ;
276+ }
260277 }
261278
262279 ( < string > e . $ [ 'excluding' ] || '' )
@@ -270,8 +287,13 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
270287
271288 const getVirtualFolder = ( rePath : string ) => {
272289
273- rePath = rePath . trim ( ) . replace ( / ^ \/ / , '' ) . replace ( / ^ \. \/ ? / , '' ) ;
274- if ( rePath == '' ) return PROJ_INFO . virtualSource ;
290+ rePath = rePath . trim ( )
291+ . replace ( / ^ \/ / , '' )
292+ . replace ( / \/ + $ / , '' )
293+ . replace ( / ^ \. \/ ? / , '' ) ;
294+
295+ if ( rePath == '' || rePath == '.' )
296+ return PROJ_INFO . virtualSource ;
275297
276298 let curFolder = PROJ_INFO . virtualSource ;
277299 let pathList = rePath . split ( / \\ | \/ / ) . reverse ( ) ;
@@ -296,16 +318,40 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
296318 return curFolder ;
297319 } ;
298320
321+ const virtualRootList : string [ ] = [ ] ;
322+
299323 // parse external source
300324 if ( _prjDom . linkedResources ) {
301325 toArray ( _prjDom . linkedResources [ 0 ] . link ) . forEach ( link => {
302- if ( link . type [ 0 ] != '1' ) return ; // skip folder
303- const vPath = link . name [ 0 ] . trim ( ) ;
304- if ( vPath == '' ) return ;
305- const vFolder = getVirtualFolder ( NodePath . dirname ( vPath ) ) ;
306- const locations = link . locationURI || link . location ;
307- if ( ! Array . isArray ( locations ) ) return ;
308- vFolder . files . push ( { path : formatFilePath ( locations [ 0 ] ) } ) ;
326+ if ( link . type [ 0 ] == '1' ) { // virtual file
327+ const vPath = link . name [ 0 ] . trim ( ) ;
328+ if ( vPath == '' ) return ;
329+ const vFolder = getVirtualFolder ( NodePath . dirname ( vPath ) ) ;
330+ const locations = link . locationURI || link . location ;
331+ if ( ! Array . isArray ( locations ) ) return ;
332+ vFolder . files . push ( { path : formatFilePath ( locations [ 0 ] ) } ) ;
333+ } else if ( link . type [ 0 ] == '2' ) { // virtual folder
334+ const vpath = link . name [ 0 ] . trim ( ) ;
335+ const locations : string = link . locationURI || link . location ;
336+ if ( ! Array . isArray ( locations ) ) return ;
337+ const location : string = locations [ 0 ] ;
338+ if ( typeof location != 'string' ) return ;
339+ virtualRootList . push ( vpath ) ;
340+ let rootdirpath = formatFilePath ( location ) ;
341+ if ( ! File . isAbsolute ( rootdirpath ) ) rootdirpath = `${ cprojectDir . path } /${ rootdirpath } ` ;
342+ 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 ) ;
346+ files . forEach ( f => {
347+ let subvpath = vpath ;
348+ const dirname = srcRootDir . ToRelativePath ( f . dir ) ;
349+ if ( dirname && dirname != '.' ) subvpath += '/' + dirname ;
350+ vFolder = getVirtualFolder ( subvpath ) ;
351+ vFolder . files . push ( { path : cprojectDir . ToRelativePath ( f . path ) || f . path } ) ;
352+ } ) ;
353+ }
354+ }
309355 } ) ;
310356 }
311357
@@ -314,6 +360,18 @@ export async function parseEclipseProject(cprojectPath: string): Promise<Eclipse
314360
315361 target . excList = ArrayDelRepetition ( target . excList ) ;
316362
363+ // rename virtual exclude paths
364+ const excli : string [ ] = [ ] ;
365+ target . excList . forEach ( p => {
366+ if ( virtualRootList . includes ( p ) || virtualRootList . some ( e => p . startsWith ( e + '/' ) ) ) {
367+ excli . push ( `${ VirtualSource . rootName } /${ p } ` ) ;
368+ } else {
369+ excli . push ( p ) ;
370+ }
371+ } ) ;
372+
373+ target . excList = excli ;
374+
317375 for ( const key in target . globalArgs ) {
318376 const obj : any = target . globalArgs ;
319377 if ( isArray ( obj [ key ] ) ) {
0 commit comments