3434import java .io .FileFilter ;
3535import java .io .FilenameFilter ;
3636import java .io .IOException ;
37+ import java .util .ArrayDeque ;
3738import java .util .ArrayList ;
3839import java .util .Arrays ;
3940import java .util .Collection ;
40- import java .util .HashSet ;
41+ import java .util .LinkedHashSet ;
4142import java .util .List ;
4243import java .util .Set ;
4344import java .util .UUID ;
@@ -141,13 +142,13 @@ public CDTParser() {
141142 mCdtPProjectHierachyFlag = "FLAG" + UUID .randomUUID ().toString ().substring (0 , 10 ).replace ("-" , "" );
142143 mIncludeFilesFilter = new FilenameFilter () {
143144 @ Override
144- public boolean accept (File directory , String name ) {
145+ public boolean accept (final File directory , final String name ) {
145146 return name .toLowerCase ().endsWith (mIncludeFileType );
146147 }
147148 };
148149 mIncludeDirectoriesFilter = new FileFilter () {
149150 @ Override
150- public boolean accept (File pathname ) {
151+ public boolean accept (final File pathname ) {
151152 return pathname .isDirectory ();
152153 }
153154 };
@@ -264,50 +265,70 @@ private ICProject createCompleteCdtProject(final File[] files) throws CoreExcept
264265 final ICProject cProject = CoreModel .getDefault ().create (mProject );
265266 cProject .setRawPathEntries (new IPathEntry [] { sourceEntry }, NULL_MONITOR );
266267
267- final String includes =
268+ addIncludeFiles (sourceFolder , computeIncludePaths (files ));
269+
270+ // TODO: The indexer is empty and I dont know why -- reindexing does not help
271+ // CCorePlugin.getIndexManager().reindex(cProject);
272+
273+ if (mLogger .isDebugEnabled ()) {
274+ // if you want to provide other compiler settings, you might want to experiment with different providers
275+ // during createCDTProjectFromFiles(...), e.g., org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector,
276+ // and then copy the values (or automate the process somehow, or even add a mode that relies on an existing
277+ // GCC)
278+ printLanguageSettingsEntries (cProject );
279+ }
280+ return cProject ;
281+ }
282+
283+ private Collection <File > computeIncludePaths (final File [] files ) {
284+ // Include all parent dirs of the source files and all dirs from the settings afterwards
285+ final List <File > rawPaths = Arrays .stream (files ).map (File ::getParentFile ).collect (Collectors .toList ());
286+ final String includesFromSettings =
268287 mServices .getPreferenceProvider (Activator .PLUGIN_ID ).getString (PreferenceInitializer .INCLUDE_PATHS );
269- final boolean recursive =
270- mServices .getPreferenceProvider (Activator .PLUGIN_ID ).getBoolean (PreferenceInitializer .RECURSIVE );
271- final Set <File > includePaths = new HashSet <>();
272- for (final String include : includes .split (";" )) {
288+ for (final String include : includesFromSettings .split (";" )) {
273289 final File includeDir = new File (include );
274290 if (includeDir .isAbsolute ()) {
275- includePaths .add (includeDir );
291+ rawPaths .add (includeDir );
276292 continue ;
277293 }
278294 for (final File f : files ) {
279295 try {
280- includePaths .add (new File (f .getParentFile (), include ).getCanonicalFile ());
296+ rawPaths .add (new File (f .getParentFile (), include ).getCanonicalFile ());
281297 } catch (final IOException e ) {
282298 // Invalid path, do nothing
283299 continue ;
284300 }
285301 }
286302 }
287- addIncludeFiles (sourceFolder , includePaths , recursive );
288-
289- // TODO: The indexer is empty and I dont know why -- reindexing does not help
290- // CCorePlugin.getIndexManager().reindex(cProject);
291-
292- if (mLogger .isDebugEnabled ()) {
293- // if you want to provide other compiler settings, you might want to experiment with different providers
294- // during createCDTProjectFromFiles(...), e.g., org.eclipse.cdt.managedbuilder.core.GCCBuiltinSpecsDetector,
295- // and then copy the values (or automate the process somehow, or even add a mode that relies on an existing
296- // GCC)
297- printLanguageSettingsEntries (cProject );
303+ // Exclude all duplicate and invalid paths, but keep their order.
304+ final Collection <File > validPaths =
305+ rawPaths .stream ().filter (File ::isDirectory ).collect (Collectors .toCollection (LinkedHashSet ::new ));
306+ final boolean recursive =
307+ mServices .getPreferenceProvider (Activator .PLUGIN_ID ).getBoolean (PreferenceInitializer .RECURSIVE );
308+ if (!recursive ) {
309+ return validPaths ;
298310 }
299- return cProject ;
311+ // Add the paths recursively
312+ final ArrayDeque <File > queue = new ArrayDeque <>(validPaths );
313+ final Set <File > result = new LinkedHashSet <>();
314+ while (!queue .isEmpty ()) {
315+ final File f = queue .pop ();
316+ if (result .add (f )) {
317+ queue .addAll (Arrays .asList (f .listFiles (mIncludeDirectoriesFilter )));
318+ }
319+ }
320+ return result ;
300321 }
301322
302323 /**
303324 * Add files from specified include paths to the project source folder.
304325 *
305- * @param sourceFolder project source folder
306- * @param includePaths absolute path names where include files are located
307- * @param recursive determines whether include files in sub directories of each include path should be added
326+ * @param sourceFolder
327+ * project source folder
328+ * @param includePaths
329+ * absolute path names where include files are located
308330 */
309- private void addIncludeFiles (final IFolder sourceFolder , final Collection <File > includePaths ,
310- final boolean recursive ) throws CoreException {
331+ private void addIncludeFiles (final IFolder sourceFolder , final Collection <File > includePaths ) throws CoreException {
311332 for (final File includePath : includePaths ) {
312333 // check if current include path is valid
313334 final boolean includePathValid = includePath .exists () && includePath .isDirectory ();
@@ -324,12 +345,6 @@ private void addIncludeFiles(final IFolder sourceFolder, final Collection<File>
324345 mLogger .info ("Adding include file " + includeFile );
325346 addLinkToFolder (sourceFolder , includeFile );
326347 }
327-
328- // recursively add include files from all subdirectories as well
329- if (recursive ) {
330- final File [] includeSubPaths = includePath .listFiles (mIncludeDirectoriesFilter );
331- addIncludeFiles (sourceFolder , Arrays .asList (includeSubPaths ), recursive );
332- }
333348 }
334349 }
335350
0 commit comments