Skip to content

Commit b692609

Browse files
committed
Add support for the browsing path
1 parent f7913aa commit b692609

File tree

8 files changed

+119
-31
lines changed

8 files changed

+119
-31
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Changed
1111

12+
- Include the global browsing path in unit import resolution.
1213
- Reprioritize the analysis search path in the following order (highest to lowest):
1314
- Analysis source files (`sonar.sources`)
1415
- Referenced project files (`DCCReference`)
1516
- Search path (`DCC_UnitSearchPath`)
1617
- Debugger source path (`Debugger_DebugSourcePath`)
1718
- Library path (`DelphiLibraryPath`/`DelphiTranslatedLibraryPath`)
19+
- Browsing path (`DelphiBrowsingPath`)
1820
- Standard library
1921

20-
2122
## [1.12.2] - 2025-01-06
2223

2324
### Fixed

delphi-frontend/src/main/java/au/com/integradev/delphi/msbuild/DelphiProject.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,9 @@ public interface DelphiProject {
3838

3939
List<Path> getDebugSourceDirectories();
4040

41+
List<Path> getLibraryPathDirectories();
42+
43+
List<Path> getBrowsingPathDirectories();
44+
4145
Map<String, String> getUnitAliases();
4246
}

delphi-frontend/src/main/java/au/com/integradev/delphi/msbuild/DelphiProjectHelper.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ public class DelphiProjectHelper {
6969
private final CompilerVersion compilerVersion;
7070
private final List<Path> searchDirectories;
7171
private final List<Path> debugSourceDirectories;
72+
private final List<Path> libraryPathDirectories;
73+
private final List<Path> browsingPathDirectories;
7274
private final List<Path> referencedFiles;
7375
private final Set<String> conditionalDefines;
7476
private final Set<String> unitScopeNames;
@@ -93,6 +95,8 @@ public DelphiProjectHelper(
9395
this.compilerVersion = getCompilerVersionFromSettings();
9496
this.searchDirectories = getSearchDirectoriesFromSettings();
9597
this.debugSourceDirectories = new ArrayList<>();
98+
this.libraryPathDirectories = new ArrayList<>();
99+
this.browsingPathDirectories = new ArrayList<>();
96100
this.referencedFiles = new ArrayList<>();
97101
this.conditionalDefines = getPredefinedConditionalDefines();
98102
this.unitScopeNames = getSetFromSettings(DelphiProperties.UNIT_SCOPE_NAMES_KEY);
@@ -201,6 +205,8 @@ private void indexProjects() {
201205
for (DelphiProject project : projects) {
202206
searchDirectories.addAll(project.getSearchDirectories());
203207
debugSourceDirectories.addAll(project.getDebugSourceDirectories());
208+
libraryPathDirectories.addAll(project.getLibraryPathDirectories());
209+
browsingPathDirectories.addAll(project.getBrowsingPathDirectories());
204210
conditionalDefines.addAll(project.getConditionalDefines());
205211
referencedFiles.addAll(project.getSourceFiles());
206212
unitScopeNames.addAll(project.getUnitScopeNames());
@@ -310,13 +316,33 @@ public List<Path> getSearchDirectories() {
310316
/**
311317
* Gets the debug source directories specified in project files
312318
*
313-
* @return List of debug source directorie
319+
* @return List of debug source directories
314320
*/
315321
public List<Path> getDebugSourceDirectories() {
316322
indexProjects();
317323
return debugSourceDirectories;
318324
}
319325

326+
/**
327+
* Gets the library path directories specified in project files
328+
*
329+
* @return List of library path directories
330+
*/
331+
public List<Path> getLibraryPathDirectories() {
332+
indexProjects();
333+
return libraryPathDirectories;
334+
}
335+
336+
/**
337+
* Gets the browsing path directories specified in project files
338+
*
339+
* @return List of browsing path directories
340+
*/
341+
public List<Path> getBrowsingPathDirectories() {
342+
indexProjects();
343+
return browsingPathDirectories;
344+
}
345+
320346
/**
321347
* Gets the set of conditional defines specified in settings and project files
322348
*

delphi-frontend/src/main/java/au/com/integradev/delphi/msbuild/DelphiProjectParser.java

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ public DelphiProject parse() {
6666
project.setUnitScopeNames(createUnitScopeNames(result.getProperties()));
6767
project.setSearchDirectories(createSearchDirectories(dprojDirectory, result.getProperties()));
6868
project.setDebugSourceDirectories(createDebugSourceDirectories(result.getProperties()));
69+
project.setLibraryPath(createLibraryPathDirectories(result.getProperties()));
70+
project.setBrowsingPath(createBrowsingPathDirectories(result.getProperties()));
6971
project.setUnitAliases(createUnitAliases(result.getProperties()));
7072
project.setSourceFiles(result.getSourceFiles());
7173

@@ -81,31 +83,29 @@ private static Set<String> createUnitScopeNames(ProjectProperties properties) {
8183
}
8284

8385
private List<Path> createSearchDirectories(Path dprojDirectory, ProjectProperties properties) {
84-
/*
85-
We manually append the library paths here, even though it's not strictly correct to do so.
86+
List<Path> result = new ArrayList<>();
8687

87-
CodeGear.Delphi.Targets appends the library paths to DCC_UnitSearchPath to create a new
88-
property called UnitSearchPath, which then gets passed through to the compiler.
88+
result.add(dprojDirectory);
89+
result.addAll(createPathList(properties, "DCC_UnitSearchPath"));
8990

90-
However, there are some good reasons not to just read the UnitSearchPath property:
91+
return Collections.unmodifiableList(result);
92+
}
9193

92-
- It would tie us to an implementation detail of the MSBuild glue in CodeGear.Delphi.Targets.
93-
- If the UnitSearchPath property were ever renamed, we'd fall out of compatibility.
94-
- Relying on CodeGear.Delphi.Targets details would require us to mock it up in testing.
95-
*/
94+
private List<Path> createDebugSourceDirectories(ProjectProperties properties) {
95+
return createPathList(properties, "Debugger_DebugSourcePath");
96+
}
9697

97-
List<Path> allPaths = new ArrayList<>();
98+
private List<Path> createLibraryPathDirectories(ProjectProperties properties) {
99+
List<Path> result = new ArrayList<>();
98100

99-
allPaths.add(dprojDirectory);
100-
allPaths.addAll(createPathList(properties, "DCC_UnitSearchPath"));
101-
allPaths.addAll(createPathList(properties, "DelphiLibraryPath", false));
102-
allPaths.addAll(createPathList(properties, "DelphiTranslatedLibraryPath", false));
101+
result.addAll(createPathList(properties, "DelphiLibraryPath", false));
102+
result.addAll(createPathList(properties, "DelphiTranslatedLibraryPath", false));
103103

104-
return Collections.unmodifiableList(allPaths);
104+
return Collections.unmodifiableList(result);
105105
}
106106

107-
private List<Path> createDebugSourceDirectories(ProjectProperties properties) {
108-
return createPathList(properties, "Debugger_DebugSourcePath");
107+
private List<Path> createBrowsingPathDirectories(ProjectProperties properties) {
108+
return createPathList(properties, "DelphiBrowsingPath", false);
109109
}
110110

111111
private List<Path> createPathList(ProjectProperties properties, String propertyName) {
@@ -176,6 +176,8 @@ private static class DelphiProjectImpl implements DelphiProject {
176176
private List<Path> sourceFiles = Collections.emptyList();
177177
private List<Path> searchDirectories = Collections.emptyList();
178178
private List<Path> debugSourceDirectories = Collections.emptyList();
179+
private List<Path> libraryPathDirectories = Collections.emptyList();
180+
private List<Path> browsingPathDirectories = Collections.emptyList();
179181
private Map<String, String> unitAliases = Collections.emptyMap();
180182

181183
private void setDefinitions(Set<String> definitions) {
@@ -199,6 +201,14 @@ private void setDebugSourceDirectories(List<Path> debugSourceDirectories) {
199201
this.debugSourceDirectories = List.copyOf(debugSourceDirectories);
200202
}
201203

204+
private void setLibraryPath(List<Path> libraryPathDirectories) {
205+
this.libraryPathDirectories = List.copyOf(libraryPathDirectories);
206+
}
207+
208+
private void setBrowsingPath(List<Path> browsingPathDirectories) {
209+
this.browsingPathDirectories = List.copyOf(browsingPathDirectories);
210+
}
211+
202212
private void setUnitAliases(Map<String, String> unitAliases) {
203213
this.unitAliases = ImmutableSortedMap.copyOf(unitAliases, String.CASE_INSENSITIVE_ORDER);
204214
}
@@ -228,6 +238,16 @@ public List<Path> getDebugSourceDirectories() {
228238
return debugSourceDirectories;
229239
}
230240

241+
@Override
242+
public List<Path> getLibraryPathDirectories() {
243+
return libraryPathDirectories;
244+
}
245+
246+
@Override
247+
public List<Path> getBrowsingPathDirectories() {
248+
return browsingPathDirectories;
249+
}
250+
231251
@Override
232252
public Map<String, String> getUnitAliases() {
233253
return unitAliases;

delphi-frontend/src/test/java/au/com/integradev/delphi/msbuild/DelphiProjectParserTest.java

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ class DelphiProjectParserTest {
5757
private static final String LIBRARY_PATH_PROJECT =
5858
"/au/com/integradev/delphi/msbuild/LibraryPath.dproj";
5959

60+
private static final String BROWSING_PATH_PROJECT =
61+
"/au/com/integradev/delphi/msbuild/BrowsingPath.dproj";
62+
6063
private EnvironmentVariableProvider environmentVariableProvider;
6164
private Path environmentProj;
6265

@@ -158,14 +161,20 @@ void testBadSourceFileProjectShouldContainValidSourceFiles() {
158161
}
159162

160163
@Test
161-
void testLibraryPathShouldBeAppendedToSearchDirectories() {
164+
void testLibraryPathProject() {
162165
DelphiProject project = parse(LIBRARY_PATH_PROJECT);
163166

164-
assertThat(project.getSearchDirectories())
167+
assertThat(project.getLibraryPathDirectories())
165168
.containsExactly(
166-
DelphiUtils.getResource("/au/com/integradev/delphi/msbuild").toPath(),
167169
DelphiUtils.getResource("/au/com/integradev/delphi").toPath(),
168-
DelphiUtils.getResource("/au/com/integradev").toPath(),
169-
DelphiUtils.getResource("/au/com").toPath());
170+
DelphiUtils.getResource("/au/com/integradev").toPath());
171+
}
172+
173+
@Test
174+
void testBrowsingPathProject() {
175+
DelphiProject project = parse(BROWSING_PATH_PROJECT);
176+
177+
assertThat(project.getBrowsingPathDirectories())
178+
.containsExactly(DelphiUtils.getResource("/au/com/integradev/delphi").toPath());
170179
}
171180
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2+
<PropertyGroup>
3+
<DelphiBrowsingPath>../</DelphiBrowsingPath>
4+
</PropertyGroup>
5+
</Project>
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
22
<PropertyGroup>
3-
<DelphiLibraryPath>../../</DelphiLibraryPath>
4-
<DelphiTranslatedLibraryPath>../../../</DelphiTranslatedLibraryPath>
5-
<DCC_UnitSearchPath>../</DCC_UnitSearchPath>
3+
<DelphiLibraryPath>../</DelphiLibraryPath>
4+
<DelphiTranslatedLibraryPath>../../</DelphiTranslatedLibraryPath>
65
</PropertyGroup>
76
</Project>

sonar-delphi-plugin/src/main/java/au/com/integradev/delphi/DelphiSensor.java

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,7 @@ private void executeOnFiles(SensorContext sensorContext) {
9999
Iterable<InputFile> inputFiles = delphiProjectHelper.inputFiles();
100100
List<Path> sourceFiles = inputFilesToPaths(inputFiles);
101101
List<Path> referencedFiles = delphiProjectHelper.getReferencedFiles();
102-
List<Path> searchPathDirectories = new ArrayList<>();
103-
searchPathDirectories.addAll(delphiProjectHelper.getSearchDirectories());
104-
searchPathDirectories.addAll(delphiProjectHelper.getDebugSourceDirectories());
105-
SearchPath searchPath = SearchPath.create(searchPathDirectories);
102+
SearchPath searchPath = createSearchPath();
106103

107104
SymbolTable symbolTable =
108105
SymbolTable.builder()
@@ -153,6 +150,33 @@ private void executeOnFiles(SensorContext sensorContext) {
153150
}
154151
}
155152

153+
private SearchPath createSearchPath() {
154+
/*
155+
CodeGear.Delphi.Targets appends the library paths to DCC_UnitSearchPath to create a new
156+
property called UnitSearchPath, which then gets passed through to the compiler.
157+
If we were reading UnitSearchPath directly instead of DCC_UnitSearchPath, we could avoid
158+
manually appending the library path here.
159+
160+
There's a major benefit though, as the current approach allows us to prioritize the debug
161+
source paths in between DCC_UnitSearchPath and DelphiLibraryPath in the search path.
162+
From the perspective of a static analysis tool, this is the more correct ordering since it's
163+
common for the debug source path to contain corresponding source files for DCUs in the search
164+
path. These debug sources are more local to the project than the library path and should be
165+
prioritized higher.
166+
167+
Some more reasons not to just read the UnitSearchPath property...
168+
- It would tie us to an implementation detail of the MSBuild glue in CodeGear.Delphi.Targets.
169+
- If the UnitSearchPath property were ever renamed, we'd fall out of compatibility.
170+
- Relying on CodeGear.Delphi.Targets details would require us to mock it up in testing.
171+
*/
172+
List<Path> searchPathDirectories = new ArrayList<>();
173+
searchPathDirectories.addAll(delphiProjectHelper.getSearchDirectories());
174+
searchPathDirectories.addAll(delphiProjectHelper.getDebugSourceDirectories());
175+
searchPathDirectories.addAll(delphiProjectHelper.getLibraryPathDirectories());
176+
searchPathDirectories.addAll(delphiProjectHelper.getBrowsingPathDirectories());
177+
return SearchPath.create(searchPathDirectories);
178+
}
179+
156180
private boolean shouldExecuteOnProject() {
157181
return delphiProjectHelper.shouldExecuteOnProject();
158182
}

0 commit comments

Comments
 (0)