mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-10 01:35:39 +02:00
Added feature to generate compile_commands.json file (#692)
Includes: - Created a new extension point to provide the opportunity to incorporate additional information into the file - New tests for the generator - Preference page to enable/disable generator Fixes https://github.com/eclipse-cdt/cdt/issues/689
This commit is contained in:
parent
237c326a58
commit
5ca51073c9
44 changed files with 2141 additions and 5 deletions
|
@ -3,5 +3,9 @@ helloworldC.zip:
|
||||||
Basic standard Linux GCC C HelloWorld ManagedBuild Project template.
|
Basic standard Linux GCC C HelloWorld ManagedBuild Project template.
|
||||||
Contains Debug + Release configurations.
|
Contains Debug + Release configurations.
|
||||||
|
|
||||||
|
helloworldCPP.zip:
|
||||||
|
Minimal standard Linux GCC C++ HelloWorld ManagedBuild Project template
|
||||||
|
Contains Debug + Release configurations.
|
||||||
|
|
||||||
bug_335476.zip:
|
bug_335476.zip:
|
||||||
Test for noticing environment variable changes.
|
Test for noticing environment variable changes.
|
Binary file not shown.
|
@ -0,0 +1,170 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2019, 2020 Marc-Andre Laperle.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.managedbuilder.core.tests;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import java.io.FileReader;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.jsoncdb.CompilationDatabaseInformation;
|
||||||
|
import org.eclipse.cdt.managedbuilder.internal.core.CommonBuilder;
|
||||||
|
import org.eclipse.cdt.managedbuilder.testplugin.AbstractBuilderTest;
|
||||||
|
import org.eclipse.cdt.managedbuilder.testplugin.ManagedBuildTestHelper;
|
||||||
|
import org.eclipse.core.resources.IFile;
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.resources.IncrementalProjectBuilder;
|
||||||
|
import org.eclipse.core.runtime.preferences.InstanceScope;
|
||||||
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
|
import org.eclipse.ui.preferences.ScopedPreferenceStore;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonElement;
|
||||||
|
|
||||||
|
public class CompilationDatabaseGenerationTest extends AbstractBuilderTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests generation of compile_commands.json in "build" folder
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testCompilationDatabaseGeneration() throws Exception {
|
||||||
|
setWorkspace("regressions");
|
||||||
|
final IProject app = loadProject("helloworldC");
|
||||||
|
setGenerateFileOptionEnabled(true);
|
||||||
|
app.build(IncrementalProjectBuilder.FULL_BUILD, null);
|
||||||
|
IFile compilationDatabase = app.getFile("Debug/compile_commands.json");
|
||||||
|
assertTrue(compilationDatabase.exists());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests format for compile_commands.json. JSON array is expected, containing an element for the c file
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testJsonFormat() throws Exception {
|
||||||
|
setWorkspace("regressions");
|
||||||
|
final IProject app = loadProject("helloworldC");
|
||||||
|
setGenerateFileOptionEnabled(true);
|
||||||
|
app.build(IncrementalProjectBuilder.FULL_BUILD, null);
|
||||||
|
IFile commandsFile = app.getFile("Debug/compile_commands.json");
|
||||||
|
if (commandsFile.exists()) {
|
||||||
|
|
||||||
|
try (FileReader reader = new FileReader(commandsFile.getLocation().toFile())) {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
JsonArray jsonArray = gson.fromJson(reader, JsonArray.class);
|
||||||
|
for (JsonElement element : jsonArray) {
|
||||||
|
CompilationDatabaseInformation compileCommand = gson.fromJson(element,
|
||||||
|
CompilationDatabaseInformation.class);
|
||||||
|
|
||||||
|
assertTrue(compileCommand.directory() != null && !compileCommand.directory().isEmpty());
|
||||||
|
assertTrue(compileCommand.command() != null && !compileCommand.command().isEmpty());
|
||||||
|
assertTrue(compileCommand.file() != null && !compileCommand.file().isEmpty());
|
||||||
|
assertTrue(compileCommand.file().endsWith("src/helloworldC.c"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that compile_commands.json is correctly generated when more than one .c file is present as a source file
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testMultipleFiles() throws Exception {
|
||||||
|
setWorkspace("regressions");
|
||||||
|
final IProject app = loadProject("helloworldC");
|
||||||
|
IFile aFile = ManagedBuildTestHelper.createFile(app, "src/newFile.c");
|
||||||
|
setGenerateFileOptionEnabled(true);
|
||||||
|
app.build(IncrementalProjectBuilder.FULL_BUILD, null);
|
||||||
|
IFile commandsFile = app.getFile("Debug/compile_commands.json");
|
||||||
|
int numberOfElementsFound = 0;
|
||||||
|
boolean helloworldCIsPresent = false;
|
||||||
|
boolean newFileIsPresent = false;
|
||||||
|
try (FileReader reader = new FileReader(commandsFile.getLocation().toFile())) {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
JsonArray jsonArray = gson.fromJson(reader, JsonArray.class);
|
||||||
|
System.out.println(jsonArray);
|
||||||
|
for (JsonElement element : jsonArray) {
|
||||||
|
CompilationDatabaseInformation compileCommand = gson.fromJson(element,
|
||||||
|
CompilationDatabaseInformation.class);
|
||||||
|
numberOfElementsFound++;
|
||||||
|
if (compileCommand.file().endsWith("helloworldC.c")) {
|
||||||
|
helloworldCIsPresent = true;
|
||||||
|
}
|
||||||
|
if (compileCommand.file().endsWith("newFile.c")) {
|
||||||
|
newFileIsPresent = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertEquals(2, numberOfElementsFound);
|
||||||
|
assertTrue(helloworldCIsPresent);
|
||||||
|
assertTrue(newFileIsPresent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that cpp files are handled by compile_commands.json file generator
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void isCPPFileAllowed() throws Exception {
|
||||||
|
setWorkspace("regressions");
|
||||||
|
final IProject app = loadProject("helloworldCPP");
|
||||||
|
setGenerateFileOptionEnabled(true);
|
||||||
|
app.build(IncrementalProjectBuilder.FULL_BUILD, null);
|
||||||
|
IFile commandsFile = app.getFile("Debug/compile_commands.json");
|
||||||
|
if (commandsFile.exists()) {
|
||||||
|
|
||||||
|
try (FileReader reader = new FileReader(commandsFile.getLocation().toFile())) {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
JsonArray jsonArray = gson.fromJson(reader, JsonArray.class);
|
||||||
|
for (JsonElement element : jsonArray) {
|
||||||
|
CompilationDatabaseInformation compileCommand = gson.fromJson(element,
|
||||||
|
CompilationDatabaseInformation.class);
|
||||||
|
|
||||||
|
assertTrue(compileCommand.directory() != null && !compileCommand.directory().isEmpty());
|
||||||
|
assertTrue(compileCommand.command() != null && !compileCommand.command().isEmpty());
|
||||||
|
assertTrue(compileCommand.file() != null && !compileCommand.file().isEmpty());
|
||||||
|
assertTrue(compileCommand.file().endsWith("src/helloworldCPP.cpp"));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that compilation database is not generated when feature is disabled
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testCompilationDatabaseGenerationNotEnabled() throws Exception {
|
||||||
|
setWorkspace("regressions");
|
||||||
|
final IProject app = loadProject("helloworldC");
|
||||||
|
setGenerateFileOptionEnabled(false);
|
||||||
|
app.build(IncrementalProjectBuilder.FULL_BUILD, null);
|
||||||
|
IFile compilationDatabase = app.getFile("Debug/compile_commands.json");
|
||||||
|
assertFalse(compilationDatabase.exists());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setGenerateFileOptionEnabled(boolean value) {
|
||||||
|
IPreferenceStore preferenceStore = new ScopedPreferenceStore(InstanceScope.INSTANCE,
|
||||||
|
"org.eclipse.cdt.managedbuilder.ui");
|
||||||
|
preferenceStore.setValue(CommonBuilder.COMPILATION_DATABASE_ENABLEMENT, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
public void restoreDefaultForGenerateFile() {
|
||||||
|
IPreferenceStore preferenceStore = new ScopedPreferenceStore(InstanceScope.INSTANCE,
|
||||||
|
"org.eclipse.cdt.managedbuilder.ui");
|
||||||
|
preferenceStore.setToDefault(CommonBuilder.COMPILATION_DATABASE_ENABLEMENT);
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,6 +25,11 @@
|
||||||
<arguments>
|
<arguments>
|
||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.pde.ds.core.builder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
</buildSpec>
|
</buildSpec>
|
||||||
<natures>
|
<natures>
|
||||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
|
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
||||||
Bundle-ManifestVersion: 2
|
Bundle-ManifestVersion: 2
|
||||||
Bundle-Name: %pluginName
|
Bundle-Name: %pluginName
|
||||||
Bundle-SymbolicName: org.eclipse.cdt.managedbuilder.core; singleton:=true
|
Bundle-SymbolicName: org.eclipse.cdt.managedbuilder.core; singleton:=true
|
||||||
Bundle-Version: 9.6.300.qualifier
|
Bundle-Version: 9.7.0.qualifier
|
||||||
Bundle-Activator: org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin
|
Bundle-Activator: org.eclipse.cdt.managedbuilder.core.ManagedBuilderCorePlugin
|
||||||
Bundle-Vendor: %providerName
|
Bundle-Vendor: %providerName
|
||||||
Bundle-Localization: plugin
|
Bundle-Localization: plugin
|
||||||
|
@ -12,9 +12,11 @@ Export-Package: org.eclipse.cdt.build.core.scannerconfig,
|
||||||
org.eclipse.cdt.managedbuilder.buildmodel,
|
org.eclipse.cdt.managedbuilder.buildmodel,
|
||||||
org.eclipse.cdt.managedbuilder.buildproperties,
|
org.eclipse.cdt.managedbuilder.buildproperties,
|
||||||
org.eclipse.cdt.managedbuilder.core,
|
org.eclipse.cdt.managedbuilder.core,
|
||||||
|
org.eclipse.cdt.managedbuilder.core.jsoncdb,
|
||||||
org.eclipse.cdt.managedbuilder.envvar,
|
org.eclipse.cdt.managedbuilder.envvar,
|
||||||
org.eclipse.cdt.managedbuilder.internal.buildmodel;x-friends:="org.eclipse.cdt.managedbuilder.ui",
|
org.eclipse.cdt.managedbuilder.internal.buildmodel;x-friends:="org.eclipse.cdt.managedbuilder.ui",
|
||||||
org.eclipse.cdt.managedbuilder.internal.core;x-friends:="org.eclipse.cdt.managedbuilder.ui,org.eclipse.cdt.managedbuilder.headlessbuilderapp",
|
org.eclipse.cdt.managedbuilder.internal.core;x-friends:="org.eclipse.cdt.managedbuilder.ui,org.eclipse.cdt.managedbuilder.headlessbuilderapp",
|
||||||
|
org.eclipse.cdt.managedbuilder.internal.core.jsoncdb.generator;x-internal:=true,
|
||||||
org.eclipse.cdt.managedbuilder.internal.dataprovider;x-internal:=true,
|
org.eclipse.cdt.managedbuilder.internal.dataprovider;x-internal:=true,
|
||||||
org.eclipse.cdt.managedbuilder.internal.envvar;x-internal:=true,
|
org.eclipse.cdt.managedbuilder.internal.envvar;x-internal:=true,
|
||||||
org.eclipse.cdt.managedbuilder.internal.language.settings.providers;x-friends:="org.eclipse.cdt.managedbuilder.ui",
|
org.eclipse.cdt.managedbuilder.internal.language.settings.providers;x-friends:="org.eclipse.cdt.managedbuilder.ui",
|
||||||
|
@ -39,7 +41,8 @@ Require-Bundle: org.eclipse.cdt.core;bundle-version="[8.3.0,9.0.0)",
|
||||||
org.eclipse.ui;bundle-version="[3.2.0,4.0.0)",
|
org.eclipse.ui;bundle-version="[3.2.0,4.0.0)",
|
||||||
org.eclipse.core.variables;bundle-version="[3.1.100,4.0.0)",
|
org.eclipse.core.variables;bundle-version="[3.1.100,4.0.0)",
|
||||||
org.eclipse.cdt.make.core;visibility:=reexport,
|
org.eclipse.cdt.make.core;visibility:=reexport,
|
||||||
org.eclipse.core.filesystem;bundle-version="1.2.0"
|
org.eclipse.core.filesystem;bundle-version="1.2.0",
|
||||||
|
org.eclipse.jdt.annotation;bundle-version="[2.2.7,3.0.0)";resolution:=optional
|
||||||
Bundle-ActivationPolicy: lazy
|
Bundle-ActivationPolicy: lazy
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||||
Import-Package: com.google.gson;version="2.8.0"
|
Import-Package: com.google.gson;version="2.8.0"
|
||||||
|
|
|
@ -78,6 +78,7 @@ extension-point.name.0 = Managed Build Definitions
|
||||||
extension-point.name.1 = Managed Build Project Converter
|
extension-point.name.1 = Managed Build Project Converter
|
||||||
extension-point.name.2 = Build Properties
|
extension-point.name.2 = Build Properties
|
||||||
extension-point.name.3 = ToolChain Modification Info
|
extension-point.name.3 = ToolChain Modification Info
|
||||||
|
extension-point.name.4 = Compilation Database Contributor
|
||||||
|
|
||||||
GCCBuildOutputParser.name = CDT GCC Build Output Parser
|
GCCBuildOutputParser.name = CDT GCC Build Output Parser
|
||||||
GCCBuiltinCompilerSettings.name = CDT GCC Built-in Compiler Settings
|
GCCBuiltinCompilerSettings.name = CDT GCC Built-in Compiler Settings
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
<extension-point id="projectConverter" name="%extension-point.name.1" schema="schema/Converter.exsd"/>
|
<extension-point id="projectConverter" name="%extension-point.name.1" schema="schema/Converter.exsd"/>
|
||||||
<extension-point id="buildProperties" name="%extension-point.name.2" schema="schema/buildProperties.exsd"/>
|
<extension-point id="buildProperties" name="%extension-point.name.2" schema="schema/buildProperties.exsd"/>
|
||||||
<extension-point id="tcModificationInfo" name="%extension-point.name.3" schema="schema/tcModificationInfo.exsd"/>
|
<extension-point id="tcModificationInfo" name="%extension-point.name.3" schema="schema/tcModificationInfo.exsd"/>
|
||||||
|
<extension-point id="compilationDatabaseContributor" name="%extension-point.name.4" schema="schema/compilationDatabaseContributor.exsd"/>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- =================================================================================== -->
|
<!-- =================================================================================== -->
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<!-- Schema file written by PDE -->
|
||||||
|
<schema targetNamespace="org.eclipse.cdt.managedbuilder.core" xmlns="http://www.w3.org/2001/XMLSchema">
|
||||||
|
<annotation>
|
||||||
|
<appInfo>
|
||||||
|
<meta.schema plugin="org.eclipse.cdt.managedbuilder.core" id="compilationDatabaseContributor" name="Compilation Database Contributor"/>
|
||||||
|
</appInfo>
|
||||||
|
<documentation>
|
||||||
|
This extension point allows to add specific information to compile_commands.json file.
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
|
||||||
|
<element name="extension">
|
||||||
|
<annotation>
|
||||||
|
<appInfo>
|
||||||
|
<meta.element />
|
||||||
|
</appInfo>
|
||||||
|
</annotation>
|
||||||
|
<complexType>
|
||||||
|
<sequence minOccurs="1" maxOccurs="unbounded">
|
||||||
|
<choice>
|
||||||
|
<element ref="compilationDatabase"/>
|
||||||
|
</choice>
|
||||||
|
</sequence>
|
||||||
|
<attribute name="point" type="string" use="required">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="id" type="string">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="name" type="string">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
<appInfo>
|
||||||
|
<meta.attribute translatable="true"/>
|
||||||
|
</appInfo>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
|
||||||
|
<element name="compilationDatabase">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
Compilation Database for C/C++ projects
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
<complexType>
|
||||||
|
<attribute name="toolchainID" type="string" use="required">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
Toolchain ID
|
||||||
|
</documentation>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
<attribute name="runner" type="string" use="required">
|
||||||
|
<annotation>
|
||||||
|
<documentation>
|
||||||
|
|
||||||
|
</documentation>
|
||||||
|
<appInfo>
|
||||||
|
<meta.attribute kind="java" basedOn=":org.eclipse.cdt.managedbuilder.core.jsoncdb.ICompilationDatabaseContributor"/>
|
||||||
|
</appInfo>
|
||||||
|
</annotation>
|
||||||
|
</attribute>
|
||||||
|
</complexType>
|
||||||
|
</element>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</schema>
|
|
@ -0,0 +1,22 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (c) 2023, 2024 Renesas Electronics Corp. and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
********************************************************************************/
|
||||||
|
package org.eclipse.cdt.managedbuilder.core.jsoncdb;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The compilation database array of “command objects” members to be used for
|
||||||
|
* the extension point
|
||||||
|
* directory: The working directory of the compilation.
|
||||||
|
* command: The compile command. file: The main translation unit source
|
||||||
|
* processed by this compilation step.
|
||||||
|
* @since 9.7
|
||||||
|
*/
|
||||||
|
|
||||||
|
public record CompilationDatabaseInformation(String directory, String command, String file) {
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (c) 2023, 2024 Renesas Electronics Europe. and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
********************************************************************************/
|
||||||
|
package org.eclipse.cdt.managedbuilder.core.jsoncdb;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
|
||||||
|
import org.eclipse.jdt.annotation.NonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 9.7
|
||||||
|
*/
|
||||||
|
public interface ICompilationDatabaseContributor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param config
|
||||||
|
* Adds a new list of files to the compilation database
|
||||||
|
* Implementors should provide concrete implementations of this
|
||||||
|
* interface. IConfiguration will be taken as input, accessing the project and will generate a list of
|
||||||
|
* additional files to be added to compile_commands.json
|
||||||
|
* @return A non-null list of files that will be added to compilation database
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
public List<CompilationDatabaseInformation> getAdditionalFiles(@NonNull IConfiguration config);
|
||||||
|
|
||||||
|
}
|
|
@ -57,6 +57,7 @@ import org.eclipse.cdt.managedbuilder.internal.buildmodel.IBuildModelBuilder;
|
||||||
import org.eclipse.cdt.managedbuilder.internal.buildmodel.IConfigurationBuildState;
|
import org.eclipse.cdt.managedbuilder.internal.buildmodel.IConfigurationBuildState;
|
||||||
import org.eclipse.cdt.managedbuilder.internal.buildmodel.IProjectBuildState;
|
import org.eclipse.cdt.managedbuilder.internal.buildmodel.IProjectBuildState;
|
||||||
import org.eclipse.cdt.managedbuilder.internal.buildmodel.StepBuilder;
|
import org.eclipse.cdt.managedbuilder.internal.buildmodel.StepBuilder;
|
||||||
|
import org.eclipse.cdt.managedbuilder.internal.core.jsoncdb.generator.CompilationDatabaseGenerator;
|
||||||
import org.eclipse.cdt.managedbuilder.macros.BuildMacroException;
|
import org.eclipse.cdt.managedbuilder.macros.BuildMacroException;
|
||||||
import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider;
|
import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider;
|
||||||
import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator;
|
import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator;
|
||||||
|
@ -85,6 +86,9 @@ import org.eclipse.core.runtime.Status;
|
||||||
import org.eclipse.core.runtime.SubProgressMonitor;
|
import org.eclipse.core.runtime.SubProgressMonitor;
|
||||||
import org.eclipse.core.runtime.jobs.ISchedulingRule;
|
import org.eclipse.core.runtime.jobs.ISchedulingRule;
|
||||||
import org.eclipse.core.runtime.jobs.Job;
|
import org.eclipse.core.runtime.jobs.Job;
|
||||||
|
import org.eclipse.core.runtime.preferences.InstanceScope;
|
||||||
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
|
import org.eclipse.ui.preferences.ScopedPreferenceStore;
|
||||||
|
|
||||||
public class CommonBuilder extends ACBuilder implements IIncrementalProjectBuilder2 {
|
public class CommonBuilder extends ACBuilder implements IIncrementalProjectBuilder2 {
|
||||||
|
|
||||||
|
@ -93,6 +97,7 @@ public class CommonBuilder extends ACBuilder implements IIncrementalProjectBuild
|
||||||
private static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$
|
private static final String NEWLINE = System.getProperty("line.separator"); //$NON-NLS-1$
|
||||||
private static final String TRACE_FOOTER = "]: "; //$NON-NLS-1$
|
private static final String TRACE_FOOTER = "]: "; //$NON-NLS-1$
|
||||||
private static final String TRACE_HEADER = "GeneratedmakefileBuilder trace ["; //$NON-NLS-1$
|
private static final String TRACE_HEADER = "GeneratedmakefileBuilder trace ["; //$NON-NLS-1$
|
||||||
|
public static final String COMPILATION_DATABASE_ENABLEMENT = "generateCBDFile"; //$NON-NLS-1$
|
||||||
public static boolean VERBOSE = false;
|
public static boolean VERBOSE = false;
|
||||||
|
|
||||||
private static final int PROGRESS_MONITOR_SCALE = 100;
|
private static final int PROGRESS_MONITOR_SCALE = 100;
|
||||||
|
@ -505,6 +510,10 @@ public class CommonBuilder extends ACBuilder implements IIncrementalProjectBuild
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < num; i++) {
|
for (int i = 0; i < num; i++) {
|
||||||
|
if (isGenerateFileOptionEnabled()) {
|
||||||
|
CompilationDatabaseGenerator generator = new CompilationDatabaseGenerator(getProject(), activeCfg);
|
||||||
|
generator.generate();
|
||||||
|
}
|
||||||
//bug 219337
|
//bug 219337
|
||||||
if (kind == INCREMENTAL_BUILD || kind == AUTO_BUILD) {
|
if (kind == INCREMENTAL_BUILD || kind == AUTO_BUILD) {
|
||||||
if (buildConfigResourceChanges()) { //only build projects with project resource changes
|
if (buildConfigResourceChanges()) { //only build projects with project resource changes
|
||||||
|
@ -1375,4 +1384,15 @@ public class CommonBuilder extends ACBuilder implements IIncrementalProjectBuild
|
||||||
// Success!
|
// Success!
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isGenerateFileOptionEnabled() {
|
||||||
|
try {
|
||||||
|
IPreferenceStore preferenceStore = new ScopedPreferenceStore(InstanceScope.INSTANCE,
|
||||||
|
"org.eclipse.cdt.managedbuilder.ui"); //$NON-NLS-1$
|
||||||
|
return preferenceStore.getBoolean(COMPILATION_DATABASE_ENABLEMENT);
|
||||||
|
} catch (Exception e) {
|
||||||
|
ManagedBuilderCorePlugin.log(e);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (c) 2023, 2024 Renesas Electronics Corp. and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
********************************************************************************/
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.core.jsoncdb.generator;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.IToolChain;
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.jsoncdb.CompilationDatabaseInformation;
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.jsoncdb.ICompilationDatabaseContributor;
|
||||||
|
import org.eclipse.core.runtime.Assert;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.IConfigurationElement;
|
||||||
|
import org.eclipse.core.runtime.IExtension;
|
||||||
|
import org.eclipse.core.runtime.IExtensionPoint;
|
||||||
|
import org.eclipse.core.runtime.Platform;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.jdt.annotation.NonNull;
|
||||||
|
|
||||||
|
/* package */ final class CompilationDatabaseContributionManager {
|
||||||
|
private static final String ATTRIB_RUNNER = "runner"; //$NON-NLS-1$
|
||||||
|
private static final String ATTRIB_TOOLCHAIN_ID = "toolchainID"; //$NON-NLS-1$
|
||||||
|
private static final String ID_COMPILATIONDATABASE = "compilationDatabase"; //$NON-NLS-1$
|
||||||
|
private static final String EXTENSION_ID = "compilationDatabaseContributor"; //$NON-NLS-1$
|
||||||
|
/**
|
||||||
|
* Map of tool chain IDs (see {@link IToolChain#getId()} to
|
||||||
|
* loaded instances of {@link ICompilationDatabaseContributor}
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
private final Map<String, ICompilationDatabaseContributor> loadedInstances = new HashMap<>();
|
||||||
|
/**
|
||||||
|
* Map of tool chain IDs (see {@link IToolChain#getId()} to
|
||||||
|
* extension point information for the compilationDatabaseContributor extension.
|
||||||
|
*/
|
||||||
|
private final Map<String, IConfigurationElement> factoryExtensions = new HashMap<>();
|
||||||
|
|
||||||
|
private class EmptyCompilationDatabaseContributor implements ICompilationDatabaseContributor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final @NonNull List<CompilationDatabaseInformation> getAdditionalFiles(@NonNull IConfiguration config) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CompilationDatabaseContributionManager instance;
|
||||||
|
|
||||||
|
private CompilationDatabaseContributionManager() {
|
||||||
|
initalise();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized CompilationDatabaseContributionManager getInstance() {
|
||||||
|
if (CompilationDatabaseContributionManager.instance == null) {
|
||||||
|
CompilationDatabaseContributionManager.instance = new CompilationDatabaseContributionManager();
|
||||||
|
}
|
||||||
|
return CompilationDatabaseContributionManager.instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initalise() {
|
||||||
|
IExtensionPoint extension = Platform.getExtensionRegistry().getExtensionPoint(
|
||||||
|
"org.eclipse.cdt.managedbuilder.core", CompilationDatabaseContributionManager.EXTENSION_ID); //$NON-NLS-1$
|
||||||
|
if (extension != null) {
|
||||||
|
IExtension[] extensions = extension.getExtensions();
|
||||||
|
for (IExtension extension2 : extensions) {
|
||||||
|
IConfigurationElement[] configElements = extension2.getConfigurationElements();
|
||||||
|
for (IConfigurationElement configElement : configElements) {
|
||||||
|
if (CompilationDatabaseContributionManager.ID_COMPILATIONDATABASE.equals(configElement.getName())) { // $NON-NLS-1$
|
||||||
|
String toolchainId = configElement
|
||||||
|
.getAttribute(CompilationDatabaseContributionManager.ATTRIB_TOOLCHAIN_ID);
|
||||||
|
String className = configElement
|
||||||
|
.getAttribute(CompilationDatabaseContributionManager.ATTRIB_RUNNER);
|
||||||
|
if (toolchainId != null && className != null) {
|
||||||
|
factoryExtensions.put(toolchainId, configElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Code Assist tool with the specified id
|
||||||
|
*
|
||||||
|
* @param id
|
||||||
|
* @return Tool extension or a list with no element if not found.
|
||||||
|
* @throws CoreException
|
||||||
|
*/
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public synchronized ICompilationDatabaseContributor getCompilationDatabaseContributor(
|
||||||
|
@NonNull IConfiguration config) {
|
||||||
|
IToolChain toolChain = config.getToolChain();
|
||||||
|
while (toolChain != null) {
|
||||||
|
String toolchainId = toolChain.getBaseId();
|
||||||
|
if (loadedInstances.containsKey(toolchainId)) {
|
||||||
|
ICompilationDatabaseContributor contributor = loadedInstances.get(toolchainId);
|
||||||
|
Assert.isNotNull(contributor);
|
||||||
|
return contributor;
|
||||||
|
} else if (factoryExtensions.containsKey(toolchainId)) {
|
||||||
|
return createCdbInstance(toolchainId);
|
||||||
|
} else {
|
||||||
|
toolChain = toolChain.getSuperClass();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new EmptyCompilationDatabaseContributor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private ICompilationDatabaseContributor createCdbInstance(String toolchainId) {
|
||||||
|
IConfigurationElement ele = factoryExtensions.get(toolchainId);
|
||||||
|
if (ele != null) {
|
||||||
|
ICompilationDatabaseContributor loaded = null;
|
||||||
|
try {
|
||||||
|
loaded = (ICompilationDatabaseContributor) ele
|
||||||
|
.createExecutableExtension(CompilationDatabaseContributionManager.ATTRIB_RUNNER);
|
||||||
|
|
||||||
|
} catch (CoreException e) {
|
||||||
|
Platform.getLog(getClass()).log(Status.error("Not able to create instance", e)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
if (loaded == null) {
|
||||||
|
loaded = new EmptyCompilationDatabaseContributor();
|
||||||
|
}
|
||||||
|
loadedInstances.put(toolchainId, loaded);
|
||||||
|
return loaded;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new EmptyCompilationDatabaseContributor();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,417 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (c) 2023, 2024 Renesas Electronics Corp. and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
********************************************************************************/
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.core.jsoncdb.generator;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.settings.model.ICSourceEntry;
|
||||||
|
import org.eclipse.cdt.core.settings.model.util.CDataUtil;
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.BuildException;
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.IFileInfo;
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.IFolderInfo;
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineGenerator;
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.IManagedCommandLineInfo;
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.IOutputType;
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.IResourceInfo;
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.ITool;
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.jsoncdb.CompilationDatabaseInformation;
|
||||||
|
import org.eclipse.cdt.managedbuilder.core.jsoncdb.ICompilationDatabaseContributor;
|
||||||
|
import org.eclipse.cdt.managedbuilder.internal.macros.FileContextData;
|
||||||
|
import org.eclipse.cdt.managedbuilder.macros.BuildMacroException;
|
||||||
|
import org.eclipse.cdt.managedbuilder.macros.IBuildMacroProvider;
|
||||||
|
import org.eclipse.core.resources.IFile;
|
||||||
|
import org.eclipse.core.resources.IFolder;
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
|
import org.eclipse.core.resources.IResourceProxy;
|
||||||
|
import org.eclipse.core.resources.IResourceProxyVisitor;
|
||||||
|
import org.eclipse.core.resources.IResourceStatus;
|
||||||
|
import org.eclipse.core.resources.IWorkspace;
|
||||||
|
import org.eclipse.core.resources.ResourcesPlugin;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
import org.eclipse.core.runtime.IStatus;
|
||||||
|
import org.eclipse.core.runtime.Path;
|
||||||
|
import org.eclipse.core.runtime.Platform;
|
||||||
|
import org.eclipse.core.runtime.Status;
|
||||||
|
import org.eclipse.jdt.annotation.NonNull;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
|
||||||
|
public final class CompilationDatabaseGenerator {
|
||||||
|
|
||||||
|
private static final String CDB_FILENAME = "compile_commands.json"; //$NON-NLS-1$
|
||||||
|
private static final String ERROR_MESSAGE = "Can not set contents to compile_commands.json file"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private IProject project;
|
||||||
|
private IConfiguration configuration;
|
||||||
|
private ICSourceEntry[] srcEntries;
|
||||||
|
private Collection<IResource> fileList;
|
||||||
|
|
||||||
|
public CompilationDatabaseGenerator(IProject proj, IConfiguration config) {
|
||||||
|
project = proj;
|
||||||
|
configuration = config;
|
||||||
|
srcEntries = config.getSourceEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param proj
|
||||||
|
* Creates and populates compilation database file
|
||||||
|
* @param config
|
||||||
|
*/
|
||||||
|
public void generate() {
|
||||||
|
IPath buildDirectory = ManagedBuildManager.getBuildFullPath(configuration, configuration.getBuilder());
|
||||||
|
IPath compilationDatabasePath = buildDirectory
|
||||||
|
.append(IPath.SEPARATOR + CompilationDatabaseGenerator.CDB_FILENAME);
|
||||||
|
try {
|
||||||
|
IWorkspace workspace = ResourcesPlugin.getWorkspace();
|
||||||
|
if (!workspace.getRoot().exists(buildDirectory)) {
|
||||||
|
createDirectory(workspace.getRoot().getFolder(buildDirectory).getProjectRelativePath().toString());
|
||||||
|
}
|
||||||
|
IFile compileCommandsFile = createFile(compilationDatabasePath);
|
||||||
|
addToCompilationdatabase(project, compileCommandsFile, configuration);
|
||||||
|
|
||||||
|
} catch (CoreException e) {
|
||||||
|
Platform.getLog(getClass())
|
||||||
|
.log(Status.error("Unable to initialize the creation of compile_commands.json file", e)); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private IFile createFile(IPath compilationDatabasePath) throws CoreException {
|
||||||
|
IWorkspace workspace = ResourcesPlugin.getWorkspace();
|
||||||
|
IFile newFile = workspace.getRoot().getFile(compilationDatabasePath);
|
||||||
|
try {
|
||||||
|
if (!newFile.exists()) {
|
||||||
|
try (InputStream inputStream = new ByteArrayInputStream("".getBytes())) { //$NON-NLS-1$
|
||||||
|
newFile.create(inputStream, true, null);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try (InputStream inputStream = new ByteArrayInputStream("".getBytes())) { //$NON-NLS-1$
|
||||||
|
newFile.setContents(inputStream, true, false, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
IStatus status = new Status(IStatus.ERROR, getClass(), CompilationDatabaseGenerator.ERROR_MESSAGE, e);
|
||||||
|
Platform.getLog(getClass()).log(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addToCompilationdatabase(IProject project, IFile compileCommandsFile, @NonNull IConfiguration config)
|
||||||
|
throws CoreException {
|
||||||
|
List<CompilationDatabaseInformation> objList = new ArrayList<>();
|
||||||
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
ResourceProxyVisitor resourceVisitor = new ResourceProxyVisitor(this, config);
|
||||||
|
project.accept(resourceVisitor, IResource.NONE);
|
||||||
|
try {
|
||||||
|
objList.addAll(populateObjList(project, config));
|
||||||
|
objList.addAll(getRunnerForToolchain(config).getAdditionalFiles(config));
|
||||||
|
CompilationDatabaseGenerator.save(gson.toJson(objList), compileCommandsFile);
|
||||||
|
} catch (Exception e) {
|
||||||
|
IStatus status = new Status(IStatus.ERROR, getClass(), CompilationDatabaseGenerator.ERROR_MESSAGE, e);
|
||||||
|
Platform.getLog(getClass()).log(status);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void save(String buffer, IFile file) throws CoreException {
|
||||||
|
byte[] bytes = buffer.getBytes(StandardCharsets.UTF_8);
|
||||||
|
ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
|
||||||
|
boolean force = true;
|
||||||
|
file.setContents(stream, force, false, null); // Don't record history
|
||||||
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
private ICompilationDatabaseContributor getRunnerForToolchain(@NonNull IConfiguration config) throws CoreException {
|
||||||
|
return CompilationDatabaseContributionManager.getInstance().getCompilationDatabaseContributor(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<CompilationDatabaseInformation> populateObjList(IProject project, IConfiguration config)
|
||||||
|
throws CoreException, BuildException {
|
||||||
|
List<CompilationDatabaseInformation> objList = new ArrayList<>();
|
||||||
|
for (IResource resource : getFileList()) {
|
||||||
|
|
||||||
|
IPath moduleRelativePath = resource.getParent().getProjectRelativePath();
|
||||||
|
String relativePath = moduleRelativePath.toString();
|
||||||
|
IFolder folder = project.getFolder(config.getName());
|
||||||
|
IPath sourceLocation = getPathForResource(resource);
|
||||||
|
String ext = sourceLocation.getFileExtension();
|
||||||
|
IResourceInfo rcInfo = config.getResourceInfo(resource.getProjectRelativePath(), false);
|
||||||
|
ITool tool = null;
|
||||||
|
if (rcInfo instanceof IFileInfo fi) {
|
||||||
|
ITool[] tools = fi.getToolsToInvoke();
|
||||||
|
if (tools != null && tools.length > 0) {
|
||||||
|
tool = tools[0];
|
||||||
|
for (ITool tool2 : tools) {
|
||||||
|
if (!tool2.getCustomBuildStep()) {
|
||||||
|
tool = tool2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (rcInfo instanceof IFolderInfo foInfo) {
|
||||||
|
tool = foInfo.getToolFromInputExtension(ext);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tool != null) {
|
||||||
|
|
||||||
|
ArrayList<IPath> enumeratedPrimaryOutputs = new ArrayList<>();
|
||||||
|
calculateOutputsForSource(tool, relativePath, sourceLocation, enumeratedPrimaryOutputs);
|
||||||
|
ArrayList<String> inputs = new ArrayList<>();
|
||||||
|
inputs.add(resource.getLocation().toString());
|
||||||
|
|
||||||
|
IPath[] addlInputPaths = tool.getAdditionalDependencies();
|
||||||
|
for (IPath addlInputPath : addlInputPaths) {
|
||||||
|
|
||||||
|
IPath addlPath = addlInputPath;
|
||||||
|
if (!(addlPath.toString().startsWith("$(")) && !addlPath.isAbsolute()) { //$NON-NLS-1$
|
||||||
|
IPath tempPath = getPathForResource(project).append(addlPath);
|
||||||
|
if (tempPath != null) {
|
||||||
|
addlPath = ManagedBuildManager.calculateRelativePath(folder.getLocation(), tempPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inputs.add(addlPath.toString());
|
||||||
|
}
|
||||||
|
String[] inputStrings = inputs.toArray(new String[inputs.size()]);
|
||||||
|
String primaryOutputName = null;
|
||||||
|
String resourceName = sourceLocation.removeFileExtension().lastSegment();
|
||||||
|
if (!enumeratedPrimaryOutputs.isEmpty()) {
|
||||||
|
if (enumeratedPrimaryOutputs.size() > 1) {
|
||||||
|
StringBuilder resultBuilder = new StringBuilder();
|
||||||
|
for (IPath outputPath : enumeratedPrimaryOutputs) {
|
||||||
|
resultBuilder.append(outputPath.toString()).append(" "); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
primaryOutputName = resultBuilder.toString().trim();
|
||||||
|
} else {
|
||||||
|
primaryOutputName = enumeratedPrimaryOutputs.get(0).toString();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
primaryOutputName = relativePath + IPath.SEPARATOR + resourceName + ".o"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
IPath outputLocation = Path.fromOSString(primaryOutputName);
|
||||||
|
if (!outputLocation.isAbsolute()) {
|
||||||
|
outputLocation = getPathForResource(project).append(folder.getName()).append(primaryOutputName);
|
||||||
|
}
|
||||||
|
String outflag = tool.getOutputFlag();
|
||||||
|
String outputPrefix = tool.getOutputPrefix();
|
||||||
|
String[] flags = tool.getToolCommandFlags(sourceLocation, folder.getFullPath());
|
||||||
|
IManagedCommandLineInfo cmdLInfo = generateToolCommandLineInfo(tool, flags, outflag, outputPrefix,
|
||||||
|
outputLocation + "", inputStrings, sourceLocation, outputLocation); //$NON-NLS-1$
|
||||||
|
|
||||||
|
IBuildMacroProvider provider = ManagedBuildManager.getBuildMacroProvider();
|
||||||
|
String resolvedOptionFileContents = provider.resolveValueToMakefileFormat(cmdLInfo.getCommandLine(), "", //$NON-NLS-1$
|
||||||
|
" ", IBuildMacroProvider.CONTEXT_FILE, //$NON-NLS-1$
|
||||||
|
new FileContextData(sourceLocation, outputLocation, null, tool));
|
||||||
|
|
||||||
|
objList.add(new CompilationDatabaseInformation(project.getLocation().toString(),
|
||||||
|
resolvedOptionFileContents, resource.getLocation().toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return objList;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private IManagedCommandLineInfo generateToolCommandLineInfo(ITool tool, String[] flags, String outputFlag,
|
||||||
|
String outputPrefix, String outputName, String[] inputResources, IPath inputLocation,
|
||||||
|
IPath outputLocation) {
|
||||||
|
|
||||||
|
String cmd = tool.getToolCommand();
|
||||||
|
try {
|
||||||
|
String resolvedCommand = null;
|
||||||
|
|
||||||
|
if ((inputLocation != null && inputLocation.toString().indexOf(" ") != -1) || //$NON-NLS-1$
|
||||||
|
(outputLocation != null && outputLocation.toString().indexOf(" ") != -1)) { //$NON-NLS-1$
|
||||||
|
resolvedCommand = ManagedBuildManager.getBuildMacroProvider().resolveValue(cmd, "", //$NON-NLS-1$
|
||||||
|
" ", //$NON-NLS-1$
|
||||||
|
IBuildMacroProvider.CONTEXT_FILE,
|
||||||
|
new FileContextData(inputLocation, outputLocation, null, tool));
|
||||||
|
} else {
|
||||||
|
resolvedCommand = ManagedBuildManager.getBuildMacroProvider().resolveValueToMakefileFormat(cmd, "", //$NON-NLS-1$
|
||||||
|
" ", //$NON-NLS-1$
|
||||||
|
IBuildMacroProvider.CONTEXT_FILE,
|
||||||
|
new FileContextData(inputLocation, outputLocation, null, tool));
|
||||||
|
}
|
||||||
|
if ((resolvedCommand = resolvedCommand.trim()).length() > 0) {
|
||||||
|
cmd = resolvedCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (BuildMacroException e) {
|
||||||
|
Platform.getLog(getClass()).log(Status.error(CompilationDatabaseGenerator.ERROR_MESSAGE, e));
|
||||||
|
}
|
||||||
|
|
||||||
|
IManagedCommandLineGenerator gen = tool.getCommandLineGenerator();
|
||||||
|
return gen.generateCommandLineInfo(tool, cmd, flags, outputFlag, outputPrefix, outputName, inputResources,
|
||||||
|
tool.getCommandLinePattern());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void calculateOutputsForSource(ITool tool, String relativePath, IPath sourceLocation,
|
||||||
|
ArrayList<IPath> enumeratedPrimaryOutputs) {
|
||||||
|
|
||||||
|
IOutputType[] outTypes = tool.getOutputTypes();
|
||||||
|
if (outTypes != null && outTypes.length > 0) {
|
||||||
|
IOutputType type = tool.getPrimaryOutputType();
|
||||||
|
boolean primaryOutput = (type == tool.getPrimaryOutputType());
|
||||||
|
String[] extensions = type.getOutputExtensions(tool);
|
||||||
|
if (primaryOutput) {
|
||||||
|
for (String extension : extensions) {
|
||||||
|
String prefix = type.getOutputPrefix();
|
||||||
|
String fileName = sourceLocation.removeFileExtension().lastSegment();
|
||||||
|
IPath outPath = Path.fromOSString(relativePath + IPath.SEPARATOR + prefix + fileName);
|
||||||
|
outPath = outPath.addFileExtension(extension);
|
||||||
|
enumeratedPrimaryOutputs.add(0, outPath);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IPath getPathForResource(IResource resource) {
|
||||||
|
return new Path(resource.getLocationURI().getPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isSource(IPath path) {
|
||||||
|
return !CDataUtil.isExcluded(path, srcEntries);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendFileList(IResource resource) {
|
||||||
|
getFileList().add(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Collection<IResource> getFileList() {
|
||||||
|
if (fileList == null) {
|
||||||
|
fileList = new LinkedHashSet<>();
|
||||||
|
}
|
||||||
|
return fileList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isGeneratedResource(IResource resource) {
|
||||||
|
// Is this a generated directory ...
|
||||||
|
IPath path = resource.getProjectRelativePath();
|
||||||
|
String[] configNames = ManagedBuildManager.getBuildInfo(project).getConfigurationNames();
|
||||||
|
for (String name : configNames) {
|
||||||
|
IPath root = new Path(name);
|
||||||
|
// It is if it is a root of the resource pathname
|
||||||
|
if (root.isPrefixOf(path)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IPath createDirectory(String dirName) throws CoreException {
|
||||||
|
// Create or get the handle for the build directory
|
||||||
|
IFolder folder = project.getFolder(dirName);
|
||||||
|
if (!folder.exists()) {
|
||||||
|
// Make sure that parent folders exist
|
||||||
|
IPath parentPath = (new Path(dirName)).removeLastSegments(1);
|
||||||
|
// Assume that the parent exists if the path is empty
|
||||||
|
if (!parentPath.isEmpty()) {
|
||||||
|
IFolder parent = project.getFolder(parentPath);
|
||||||
|
if (!parent.exists()) {
|
||||||
|
createDirectory(parentPath.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now make the requested folder
|
||||||
|
try {
|
||||||
|
folder.create(true, true, null);
|
||||||
|
} catch (CoreException e) {
|
||||||
|
if (e.getStatus().getCode() == IResourceStatus.PATH_OCCUPIED) {
|
||||||
|
folder.refreshLocal(IResource.DEPTH_ZERO, null);
|
||||||
|
} else {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the folder is marked as derived so it is not added to CM
|
||||||
|
if (!folder.isDerived()) {
|
||||||
|
folder.setDerived(true, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return folder.getFullPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used to recursively walk the project and determine which
|
||||||
|
* modules contribute buildable source files.
|
||||||
|
*/
|
||||||
|
private class ResourceProxyVisitor implements IResourceProxyVisitor {
|
||||||
|
private final CompilationDatabaseGenerator generator;
|
||||||
|
private final IConfiguration config;
|
||||||
|
|
||||||
|
public ResourceProxyVisitor(CompilationDatabaseGenerator generator, IConfiguration cfg) {
|
||||||
|
this.generator = generator;
|
||||||
|
this.config = cfg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see org.eclipse.core.resources.IResourceProxyVisitor#visit(org.eclipse.core.
|
||||||
|
* resources.IResourceProxy)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean visit(IResourceProxy proxy) throws CoreException {
|
||||||
|
// No point in proceeding, is there
|
||||||
|
if (generator == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IResource resource = proxy.requestResource();
|
||||||
|
boolean isSource = isSource(resource.getProjectRelativePath());
|
||||||
|
|
||||||
|
// Is this a resource we should even consider
|
||||||
|
if (proxy.getType() == IResource.FILE) {
|
||||||
|
// If this resource has a Resource Configuration and is not excluded or
|
||||||
|
// if it has a file extension that one of the tools builds, add the sudirectory
|
||||||
|
// to the list
|
||||||
|
IResourceInfo rcInfo = config.getResourceInfo(resource.getProjectRelativePath(), false);
|
||||||
|
if (isSource/* && !rcInfo.isExcluded() */) {
|
||||||
|
if (rcInfo instanceof IFolderInfo) {
|
||||||
|
String ext = resource.getFileExtension();
|
||||||
|
boolean buildFile = ((IFolderInfo) rcInfo).buildsFileType(ext);
|
||||||
|
if (buildFile &&
|
||||||
|
// If this file resource is a generated resource, then it is uninteresting
|
||||||
|
!generator.isGeneratedResource(resource)) {
|
||||||
|
|
||||||
|
generator.appendFileList(resource);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
generator.appendFileList(resource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (proxy.getType() == IResource.FOLDER) {
|
||||||
|
|
||||||
|
if (!isSource || generator.isGeneratedResource(resource)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -25,6 +25,11 @@
|
||||||
<arguments>
|
<arguments>
|
||||||
</arguments>
|
</arguments>
|
||||||
</buildCommand>
|
</buildCommand>
|
||||||
|
<buildCommand>
|
||||||
|
<name>org.eclipse.pde.ds.core.builder</name>
|
||||||
|
<arguments>
|
||||||
|
</arguments>
|
||||||
|
</buildCommand>
|
||||||
</buildSpec>
|
</buildSpec>
|
||||||
<natures>
|
<natures>
|
||||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
dsVersion=V1_3
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
enabled=true
|
||||||
|
generateBundleActivationPolicyLazy=true
|
||||||
|
path=OSGI-INF
|
||||||
|
validationErrorLevel=error
|
||||||
|
validationErrorLevel.missingImplicitUnbindMethod=error
|
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
||||||
Bundle-ManifestVersion: 2
|
Bundle-ManifestVersion: 2
|
||||||
Bundle-Name: %pluginName
|
Bundle-Name: %pluginName
|
||||||
Bundle-SymbolicName: org.eclipse.cdt.managedbuilder.ui; singleton:=true
|
Bundle-SymbolicName: org.eclipse.cdt.managedbuilder.ui; singleton:=true
|
||||||
Bundle-Version: 9.4.100.qualifier
|
Bundle-Version: 9.4.200.qualifier
|
||||||
Bundle-Activator: org.eclipse.cdt.managedbuilder.ui.properties.ManagedBuilderUIPlugin
|
Bundle-Activator: org.eclipse.cdt.managedbuilder.ui.properties.ManagedBuilderUIPlugin
|
||||||
Bundle-Vendor: %providerName
|
Bundle-Vendor: %providerName
|
||||||
Bundle-Localization: plugin
|
Bundle-Localization: plugin
|
||||||
|
@ -27,3 +27,6 @@ Require-Bundle: org.eclipse.core.resources;bundle-version="[3.2.0,4.0.0)",
|
||||||
Bundle-ActivationPolicy: lazy
|
Bundle-ActivationPolicy: lazy
|
||||||
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
Bundle-RequiredExecutionEnvironment: JavaSE-17
|
||||||
Automatic-Module-Name: org.eclipse.cdt.managedbuilder.ui
|
Automatic-Module-Name: org.eclipse.cdt.managedbuilder.ui
|
||||||
|
Service-Component: OSGI-INF/org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.BuiltinPreferedOptionsDefaults.xml,
|
||||||
|
OSGI-INF/org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.PreferenceConfigurationAccess.xml,
|
||||||
|
OSGI-INF/org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.PreferenceMetadataDefaults.xml
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" name="org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.BuiltinPreferedOptionsDefaults">
|
||||||
|
<service>
|
||||||
|
<provide interface="org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.PreferenceOptionsDefaults"/>
|
||||||
|
</service>
|
||||||
|
<implementation class="org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.BuiltinPreferedOptionsDefaults"/>
|
||||||
|
</scr:component>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.3.0" name="org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.PreferenceConfigurationAccess">
|
||||||
|
<service>
|
||||||
|
<provide interface="org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.Configuration"/>
|
||||||
|
</service>
|
||||||
|
<reference cardinality="0..1" field="enable" interface="org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.GenerateCDBEnable" name="enable"/>
|
||||||
|
<reference cardinality="1..1" field="metadata" interface="org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.PreferencesMetadata" name="metadata"/>
|
||||||
|
<reference cardinality="1..1" field="workspace" interface="org.eclipse.core.resources.IWorkspace" name="workspace"/>
|
||||||
|
<implementation class="org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.PreferenceConfigurationAccess"/>
|
||||||
|
</scr:component>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.3.0" name="org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.PreferenceMetadataDefaults">
|
||||||
|
<service>
|
||||||
|
<provide interface="org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.PreferencesMetadata"/>
|
||||||
|
</service>
|
||||||
|
<reference cardinality="1..1" field="defaults" interface="org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.PreferenceOptionsDefaults" name="defaults"/>
|
||||||
|
<implementation class="org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.PreferenceMetadataDefaults"/>
|
||||||
|
</scr:component>
|
|
@ -16,7 +16,8 @@ bin.includes = plugin.xml,\
|
||||||
about.html,\
|
about.html,\
|
||||||
icons/,\
|
icons/,\
|
||||||
.,\
|
.,\
|
||||||
META-INF/
|
META-INF/,\
|
||||||
|
OSGI-INF/
|
||||||
src.includes = schema/,\
|
src.includes = schema/,\
|
||||||
about.html
|
about.html
|
||||||
source.. = src/
|
source.. = src/
|
||||||
|
|
|
@ -119,3 +119,5 @@ Configurations.menu=Build Configurations
|
||||||
|
|
||||||
buildDefinitionsUI.ep.name = Build Definitions UI
|
buildDefinitionsUI.ep.name = Build Definitions UI
|
||||||
extension-point.name = Custom MBS New Wizard Pages
|
extension-point.name = Custom MBS New Wizard Pages
|
||||||
|
|
||||||
|
JSONCompilatioDatabaseGeneratorPage.name = JSON Compilation Database Generator
|
|
@ -340,6 +340,12 @@
|
||||||
id="org.eclipse.cdt.managedbuilder.ui.preferences.PrefPage_MultiConfig"
|
id="org.eclipse.cdt.managedbuilder.ui.preferences.PrefPage_MultiConfig"
|
||||||
name="%multicfg">
|
name="%multicfg">
|
||||||
</page>
|
</page>
|
||||||
|
<page
|
||||||
|
category="org.eclipse.cdt.ui.preferences.BuildSettings"
|
||||||
|
class="org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.CompilationDatabaseGeneratorBlock"
|
||||||
|
id="org.eclipse.cdt.managedbuilder.ui.compilationdatabase.JsonCdbPreferencePage"
|
||||||
|
name="%JSONCompilatioDatabaseGeneratorPage.name">
|
||||||
|
</page>
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
<!-- Action for Project Converter in context menu -->
|
<!-- Action for Project Converter in context menu -->
|
||||||
|
@ -809,6 +815,12 @@
|
||||||
</adapt>
|
</adapt>
|
||||||
</enabledWhen>
|
</enabledWhen>
|
||||||
</page>
|
</page>
|
||||||
|
<page
|
||||||
|
category="org.eclipse.cdt.managedbuilder.ui.properties.Page_head_build"
|
||||||
|
class="org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.CompilationDatabaseGeneratorBlock"
|
||||||
|
id="org.eclipse.cdt.managedbuilder.ui.properties.Page_JsonCompilationDatabaseGenerator"
|
||||||
|
name="%JSONCompilatioDatabaseGeneratorPage.name">
|
||||||
|
</page>
|
||||||
|
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
|
@ -917,5 +929,4 @@
|
||||||
label="%CDTToolchainProperty.keyword.toolchain2">
|
label="%CDTToolchainProperty.keyword.toolchain2">
|
||||||
</keyword>
|
</keyword>
|
||||||
</extension>
|
</extension>
|
||||||
|
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2023 Contributors to the Eclipse Foundation.
|
||||||
|
* This program and the accompanying materials are made
|
||||||
|
* available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* See git history
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
import org.osgi.service.component.annotations.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class BuiltinPreferedOptionsDefaults implements PreferenceOptionsDefaults {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean generateCDB() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,259 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (c) 2023, 2024 Renesas Electronics Corp. and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
********************************************************************************/
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IWorkspace;
|
||||||
|
import org.eclipse.core.resources.ProjectScope;
|
||||||
|
import org.eclipse.core.runtime.Platform;
|
||||||
|
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
|
||||||
|
import org.eclipse.core.runtime.preferences.IScopeContext;
|
||||||
|
import org.eclipse.core.runtime.preferences.InstanceScope;
|
||||||
|
import org.eclipse.jface.dialogs.Dialog;
|
||||||
|
import org.eclipse.jface.layout.GridDataFactory;
|
||||||
|
import org.eclipse.jface.layout.GridLayoutFactory;
|
||||||
|
import org.eclipse.jface.preference.IPreferencePageContainer;
|
||||||
|
import org.eclipse.jface.resource.JFaceResources;
|
||||||
|
import org.eclipse.jface.window.Window;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.events.SelectionAdapter;
|
||||||
|
import org.eclipse.swt.events.SelectionEvent;
|
||||||
|
import org.eclipse.swt.events.SelectionListener;
|
||||||
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
import org.eclipse.swt.widgets.Button;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Control;
|
||||||
|
import org.eclipse.swt.widgets.Label;
|
||||||
|
import org.eclipse.swt.widgets.Link;
|
||||||
|
import org.eclipse.ui.IWorkbench;
|
||||||
|
import org.eclipse.ui.IWorkbenchPreferencePage;
|
||||||
|
import org.eclipse.ui.PlatformUI;
|
||||||
|
import org.eclipse.ui.dialogs.PreferencesUtil;
|
||||||
|
import org.eclipse.ui.dialogs.PropertyPage;
|
||||||
|
import org.eclipse.ui.preferences.IWorkbenchPreferenceContainer;
|
||||||
|
import org.eclipse.ui.preferences.IWorkingCopyManager;
|
||||||
|
import org.eclipse.ui.preferences.WorkingCopyManager;
|
||||||
|
import org.osgi.service.prefs.BackingStoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
* @noextend This class is not intended to be subclasses by clients.
|
||||||
|
* @since 9.5
|
||||||
|
*/
|
||||||
|
public class CompilationDatabaseGeneratorBlock extends PropertyPage implements IWorkbenchPreferencePage {
|
||||||
|
|
||||||
|
private final String id = "org.eclipse.cdt.managedbuilder.ui.compilationdatabase.JsonCdbPreferencePage"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
protected Configuration configuration;
|
||||||
|
protected IWorkspace workspace;
|
||||||
|
|
||||||
|
protected IWorkingCopyManager manager;
|
||||||
|
|
||||||
|
private Link link;
|
||||||
|
private Button specific;
|
||||||
|
private Control control;
|
||||||
|
protected ConfigurationArea area;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(IWorkbench workbench) {
|
||||||
|
this.configuration = workbench.getService(Configuration.class);
|
||||||
|
this.workspace = workbench.getService(IWorkspace.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setContainer(IPreferencePageContainer container) {
|
||||||
|
super.setContainer(container);
|
||||||
|
if (manager == null) {
|
||||||
|
manager = Optional.ofNullable(container)//
|
||||||
|
.filter(IWorkbenchPreferenceContainer.class::isInstance)//
|
||||||
|
.map(IWorkbenchPreferenceContainer.class::cast)//
|
||||||
|
.map(IWorkbenchPreferenceContainer::getWorkingCopyManager)//
|
||||||
|
.orElseGet(WorkingCopyManager::new);
|
||||||
|
}
|
||||||
|
if (configuration == null) {
|
||||||
|
configuration = getConfiguration();
|
||||||
|
}
|
||||||
|
if (workspace == null) {
|
||||||
|
workspace = PlatformUI.getWorkbench().getService(IWorkspace.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Configuration getConfiguration() {
|
||||||
|
return PlatformUI.getWorkbench().getService(Configuration.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Label createDescriptionLabel(Composite parent) {
|
||||||
|
if (projectScope().isPresent()) {
|
||||||
|
Composite composite = new Composite(parent, SWT.NONE);
|
||||||
|
composite.setFont(parent.getFont());
|
||||||
|
composite.setLayout(GridLayoutFactory.fillDefaults().numColumns(2).create());
|
||||||
|
composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||||
|
specific = new Button(composite, SWT.CHECK);
|
||||||
|
specific.setLayoutData(new GridData(SWT.BEGINNING, SWT.TOP, true, false));
|
||||||
|
specific.setText(Messages.JsonCdbGeneratorPropertyPage_enableProjectSpecific);
|
||||||
|
specific.setFont(JFaceResources.getDialogFont());
|
||||||
|
specific.addSelectionListener(SelectionListener.widgetSelectedAdapter(e -> specificSelected()));
|
||||||
|
link = createLink(composite, Messages.JsonCdbGeneratorPropertyPage_configureWorkspace);
|
||||||
|
link.setLayoutData(new GridData(SWT.END, SWT.TOP, false, false));
|
||||||
|
Label line = new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
|
||||||
|
line.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false, 2, 1));
|
||||||
|
line.setFont(composite.getFont());
|
||||||
|
}
|
||||||
|
return super.createDescriptionLabel(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void specificSelected() {
|
||||||
|
enableProjectSpecificSettings(specific.getSelection());
|
||||||
|
refreshWidgets(configuration.options(getElement()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Link createLink(Composite composite, String text) {
|
||||||
|
Link link = new Link(composite, SWT.NONE);
|
||||||
|
link.setFont(composite.getFont());
|
||||||
|
link.setText("<A>" + text + "</A>"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
link.addSelectionListener(new SelectionAdapter() {
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
if (PreferencesUtil.createPreferenceDialogOn(getShell(), getPreferenceId(),
|
||||||
|
new String[] { id, getPreferenceId() }, null).open() == Window.OK) {
|
||||||
|
refreshWidgets(configuration.options(getElement()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return link;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getPreferenceId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Control createContents(Composite parent) {
|
||||||
|
var isProjectScope = projectScope().isPresent();
|
||||||
|
Composite composite = new Composite(parent, SWT.NONE);
|
||||||
|
composite.setLayout(GridLayoutFactory.fillDefaults().numColumns(3).create());
|
||||||
|
composite.setLayoutData(GridDataFactory.fillDefaults().grab(true, false).create());
|
||||||
|
composite.setFont(parent.getFont());
|
||||||
|
control = createPreferenceContent(composite, isProjectScope);
|
||||||
|
control.setLayoutData(new GridData(GridData.FILL_BOTH));
|
||||||
|
if (isProjectScope) {
|
||||||
|
enableProjectSpecificSettings(hasProjectSpecificOptions());
|
||||||
|
}
|
||||||
|
refreshWidgets(configuration.options(getElement()));
|
||||||
|
Dialog.applyDialogFont(composite);
|
||||||
|
return composite;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ConfigurationArea getConfigurationArea(Composite composite, boolean isProjectScope) {
|
||||||
|
return new PreferenceConfigurationArea(composite, (PreferencesMetadata) configuration.metadata(),
|
||||||
|
isProjectScope);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Control createPreferenceContent(Composite parent, boolean isProjectScope) {
|
||||||
|
Composite composite = new Composite(parent, SWT.NONE);
|
||||||
|
composite.setLayout(GridLayoutFactory.fillDefaults().create());
|
||||||
|
composite.setFont(parent.getFont());
|
||||||
|
area = getConfigurationArea(composite, isProjectScope);
|
||||||
|
return composite;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void refreshWidgets(Object options) {
|
||||||
|
setErrorMessage(null);
|
||||||
|
area.load(options, useProjectSettings() || !projectScope().isPresent());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Optional<ProjectScope> projectScope() {
|
||||||
|
return new ResolveProjectScope(workspace).apply(getElement());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void performDefaults() {
|
||||||
|
if (useProjectSettings()) {
|
||||||
|
enableProjectSpecificSettings(false);
|
||||||
|
}
|
||||||
|
IEclipsePreferences prefs = manager.getWorkingCopy(scope().getNode(configuration.qualifier()));
|
||||||
|
try {
|
||||||
|
for (String key : prefs.keys()) {
|
||||||
|
prefs.remove(key);
|
||||||
|
}
|
||||||
|
} catch (BackingStoreException e) {
|
||||||
|
Platform.getLog(getClass()).error("Unable to restore default values.", e); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
refreshWidgets(configuration.defaults());
|
||||||
|
super.performDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean performOk() {
|
||||||
|
IEclipsePreferences prefs;
|
||||||
|
if (projectScope().isPresent()) {
|
||||||
|
prefs = manager.getWorkingCopy(projectScope().get().getNode(configuration.qualifier()));
|
||||||
|
if (!useProjectSettings()) {
|
||||||
|
try {
|
||||||
|
for (String key : prefs.keys()) {
|
||||||
|
prefs.remove(key);
|
||||||
|
}
|
||||||
|
} catch (BackingStoreException e) {
|
||||||
|
Platform.getLog(getClass()).error("Unable to reset project preferences.", e); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
prefs = null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
prefs = manager.getWorkingCopy(InstanceScope.INSTANCE.getNode(configuration.qualifier()));
|
||||||
|
}
|
||||||
|
if (prefs != null) {
|
||||||
|
area.store(prefs);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
manager.applyChanges();
|
||||||
|
} catch (BackingStoreException e) {
|
||||||
|
Platform.getLog(getClass()).error("Unable to save preferences.", e); //$NON-NLS-1$
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IScopeContext scope() {
|
||||||
|
return projectScope().map(IScopeContext.class::cast).orElse(InstanceScope.INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean hasProjectSpecificOptions() {
|
||||||
|
return projectScope()//
|
||||||
|
.map(p -> p.getNode(configuration.qualifier()))//
|
||||||
|
.map(n -> n.get(((PreferencesMetadata) configuration.metadata()).generateCDBFile().identifer(), null))//
|
||||||
|
.isPresent();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean useProjectSettings() {
|
||||||
|
return Optional.ofNullable(specific)//
|
||||||
|
.map(s -> s.getSelection())//
|
||||||
|
.orElse(Boolean.FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void enableProjectSpecificSettings(boolean use) {
|
||||||
|
specific.setSelection(use);
|
||||||
|
updateLinkVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateLinkVisibility() {
|
||||||
|
Optional.ofNullable(link)//
|
||||||
|
.filter(l -> !l.isDisposed())//
|
||||||
|
.ifPresent(l -> l.setEnabled(!useProjectSettings()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
Optional.ofNullable(area).ifPresent(ConfigurationArea::dispose);
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2023 Contributors to the Eclipse Foundation.
|
||||||
|
* This program and the accompanying materials are made
|
||||||
|
* available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* See git history
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
|
import org.eclipse.core.runtime.preferences.IPreferenceMetadataStore;
|
||||||
|
|
||||||
|
public interface Configuration {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the defaults
|
||||||
|
*
|
||||||
|
* @return defaults
|
||||||
|
*/
|
||||||
|
Object defaults();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the options for the given context like {@link IResource} or {@link URI}, must not return <code>null</code>
|
||||||
|
* @param context to be adapter to the proper scope
|
||||||
|
*
|
||||||
|
* @return options
|
||||||
|
*/
|
||||||
|
Object options(Object context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the editor preference store for the given context like {@link IResource} or {@link URI}, must not return <code>null</code>
|
||||||
|
* @param context to be adapter to the proper scope
|
||||||
|
*
|
||||||
|
* @return preference store
|
||||||
|
*/
|
||||||
|
IPreferenceMetadataStore storage(Object context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the metadata for options, must not return <code>null</code>
|
||||||
|
*
|
||||||
|
* @return the option metadata
|
||||||
|
*/
|
||||||
|
Object metadata();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default qualifier to use for preference storage
|
||||||
|
* @return preference qualifier
|
||||||
|
*/
|
||||||
|
String qualifier();
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2023 Contributors to the Eclipse Foundation.
|
||||||
|
* This program and the accompanying materials are made
|
||||||
|
* available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* See git history
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IWorkspace;
|
||||||
|
import org.eclipse.core.resources.ProjectScope;
|
||||||
|
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
|
||||||
|
import org.eclipse.core.runtime.preferences.IScopeContext;
|
||||||
|
import org.eclipse.osgi.util.NLS;
|
||||||
|
|
||||||
|
public abstract class ConfigurationAccess {
|
||||||
|
protected final String qualifier;
|
||||||
|
|
||||||
|
public ConfigurationAccess(String qualifier) {
|
||||||
|
this.qualifier = qualifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Optional<ProjectScope> projectScope(IWorkspace workspace, Object context) {
|
||||||
|
return new ResolveProjectScope(workspace).apply(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected IEclipsePreferences preferences(IScopeContext scope) {
|
||||||
|
return Optional.ofNullable(scope.getNode(qualifier))//
|
||||||
|
.filter(IEclipsePreferences.class::isInstance)//
|
||||||
|
.map(IEclipsePreferences.class::cast)//
|
||||||
|
.orElseThrow(() -> new IllegalStateException(//
|
||||||
|
NLS.bind("Unable to get preferences for node: {0}", // //$NON-NLS-1$
|
||||||
|
qualifier)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2023 Contributors to the Eclipse Foundation.
|
||||||
|
* This program and the accompanying materials are made
|
||||||
|
* available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* See git history
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
|
||||||
|
import org.eclipse.core.runtime.preferences.PreferenceMetadata;
|
||||||
|
import org.eclipse.jface.layout.GridDataFactory;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.events.TypedEvent;
|
||||||
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
|
import org.eclipse.swt.widgets.Button;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Group;
|
||||||
|
|
||||||
|
public abstract class ConfigurationArea {
|
||||||
|
protected final Map<PreferenceMetadata<Boolean>, Button> buttons;
|
||||||
|
protected final List<Consumer<TypedEvent>> listeners;
|
||||||
|
protected final int columns;
|
||||||
|
|
||||||
|
public ConfigurationArea(int columns) {
|
||||||
|
this.buttons = new HashMap<>();
|
||||||
|
this.listeners = new ArrayList<>();
|
||||||
|
this.columns = columns;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Group createGroup(Composite parent, String label, int numColumns) {
|
||||||
|
Group group = new Group(parent, SWT.NONE);
|
||||||
|
group.setFont(parent.getFont());
|
||||||
|
group.setText(label);
|
||||||
|
GridLayout layout = new GridLayout();
|
||||||
|
layout.numColumns = numColumns;
|
||||||
|
group.setLayout(layout);
|
||||||
|
group.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||||
|
return group;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Button createButton(PreferenceMetadata<Boolean> meta, Composite composite, int style,
|
||||||
|
int horizontalIndent) {
|
||||||
|
Button button = new Button(composite, style);
|
||||||
|
button.setLayoutData(GridDataFactory.fillDefaults().span(columns, 1).indent(horizontalIndent, 0).create());
|
||||||
|
button.setData(meta);
|
||||||
|
button.setText(meta.name());
|
||||||
|
button.setToolTipText(meta.description());
|
||||||
|
buttons.put(meta, button);
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addChangeListener(Consumer<TypedEvent> listener) {
|
||||||
|
listeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeChangeListener(Consumer<TypedEvent> listener) {
|
||||||
|
listeners.add(listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void changed(TypedEvent event) {
|
||||||
|
listeners.forEach(c -> c.accept(event));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void dispose() {
|
||||||
|
listeners.clear();
|
||||||
|
buttons.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void load(Object options, boolean enable);
|
||||||
|
|
||||||
|
public abstract void store(IEclipsePreferences prefs);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2023 ArSysOp and others.
|
||||||
|
* This program and the accompanying materials are made
|
||||||
|
* available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Alexander Fedorov (ArSysOp) - initial API
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
|
import org.eclipse.core.resources.IWorkspace;
|
||||||
|
|
||||||
|
public final class ExistingResource implements Function<URI, Optional<IResource>> {
|
||||||
|
|
||||||
|
private final IWorkspace workspace;
|
||||||
|
|
||||||
|
public ExistingResource(IWorkspace workspace) {
|
||||||
|
this.workspace = Objects.requireNonNull(workspace);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<IResource> apply(URI uri) {
|
||||||
|
return forContainer(uri).or(() -> forFile(uri));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<IResource> forContainer(URI uri) {
|
||||||
|
return Arrays.stream(workspace.getRoot().findContainersForLocationURI(uri))//
|
||||||
|
.map(IResource.class::cast)//
|
||||||
|
.filter(c -> c.exists())//
|
||||||
|
.findFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<IResource> forFile(URI uri) {
|
||||||
|
return Arrays.stream(workspace.getRoot().findFilesForLocationURI(uri))//
|
||||||
|
.map(IResource.class::cast)//
|
||||||
|
.filter(c -> c.exists())//
|
||||||
|
.findFirst();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2023 Contributors to the Eclipse Foundation.
|
||||||
|
* This program and the accompanying materials are made
|
||||||
|
* available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* See git history
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
|
||||||
|
public interface GenerateCDBEnable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the generation of the compilation database file should be enabled for the given project.
|
||||||
|
* The enable can be linked with certain project properties (e.g. project natures).
|
||||||
|
* @param project
|
||||||
|
* @return true when the generation of compilation database file should be enabled for the given project
|
||||||
|
*/
|
||||||
|
public boolean isEnabledFor(IProject project);
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (c) 2023, 2024 Renesas Electronics Corp. and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
********************************************************************************/
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.ui.dialogs.ICOptionContainer;
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.jface.preference.PreferencePage;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Control;
|
||||||
|
import org.eclipse.ui.IWorkbench;
|
||||||
|
import org.eclipse.ui.IWorkbenchPreferencePage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preference page for JSON Compilation Database Generator.
|
||||||
|
*/
|
||||||
|
public class JsonCdbGeneratorPreferencePage extends PreferencePage
|
||||||
|
implements IWorkbenchPreferencePage, ICOptionContainer {
|
||||||
|
|
||||||
|
private final CompilationDatabaseGeneratorBlock fOptionBlock;
|
||||||
|
|
||||||
|
public JsonCdbGeneratorPreferencePage() {
|
||||||
|
fOptionBlock = new CompilationDatabaseGeneratorBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Control createContents(Composite parent) {
|
||||||
|
GridLayout gl;
|
||||||
|
Composite composite = new Composite(parent, SWT.NONE);
|
||||||
|
composite.setLayout(gl = new GridLayout());
|
||||||
|
composite.setLayoutData(new GridData());
|
||||||
|
gl.verticalSpacing = 0;
|
||||||
|
fOptionBlock.createControl(composite);
|
||||||
|
return composite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init(IWorkbench workbench) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateContainer() {
|
||||||
|
if (!fOptionBlock.isValid()) {
|
||||||
|
setErrorMessage(fOptionBlock.getErrorMessage());
|
||||||
|
setValid(false);
|
||||||
|
} else {
|
||||||
|
setErrorMessage(null);
|
||||||
|
setValid(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public org.eclipse.core.runtime.Preferences getPreferences() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean performOk() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void performDefaults() {
|
||||||
|
fOptionBlock.performDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IProject getProject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (c) 2023, 2024 Renesas Electronics Corp. and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.ui.dialogs.ICOptionContainer;
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.runtime.IAdaptable;
|
||||||
|
import org.eclipse.core.runtime.Preferences;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Control;
|
||||||
|
import org.eclipse.ui.dialogs.PropertyPage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property page for JSON Compilation Database Generator.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class JsonCdbGeneratorPropertyPage extends PropertyPage implements ICOptionContainer {
|
||||||
|
private CompilationDatabaseGeneratorBlock optionPage;
|
||||||
|
|
||||||
|
public JsonCdbGeneratorPropertyPage() {
|
||||||
|
super();
|
||||||
|
optionPage = new CompilationDatabaseGeneratorBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Control createContents(Composite parent) {
|
||||||
|
Composite composite = new Composite(parent, SWT.NONE);
|
||||||
|
composite.setLayout(new GridLayout());
|
||||||
|
optionPage.createControl(composite);
|
||||||
|
return composite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void performDefaults() {
|
||||||
|
optionPage.performDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean performOk() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IProject getProject() {
|
||||||
|
IProject project = null;
|
||||||
|
IAdaptable elem = getElement();
|
||||||
|
if (elem instanceof IProject) {
|
||||||
|
project = (IProject) elem;
|
||||||
|
} else if (elem != null) {
|
||||||
|
project = elem.getAdapter(IProject.class);
|
||||||
|
}
|
||||||
|
return project;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateContainer() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Preferences getPreferences() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (c) 2023, 2024 Renesas Electronics Corp. and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
import org.eclipse.osgi.util.NLS;
|
||||||
|
|
||||||
|
class Messages extends NLS {
|
||||||
|
private static final String BUNDLE_NAME = "org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.messages"; //$NON-NLS-1$
|
||||||
|
public static String JsonCdbGeneratorPreferencePage_description;
|
||||||
|
public static String JsonCdbGeneratorPreferencePage_generateCompilationdatabase;
|
||||||
|
public static String JsonCdbGeneratorPropertyPage_configureWorkspace;
|
||||||
|
public static String JsonCdbGeneratorPropertyPage_enableProjectSpecific;
|
||||||
|
static {
|
||||||
|
// initialize resource bundle
|
||||||
|
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Messages() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2023 Contributors to the Eclipse Foundation.
|
||||||
|
* This program and the accompanying materials are made
|
||||||
|
* available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* See git history
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IWorkspace;
|
||||||
|
import org.eclipse.core.resources.ProjectScope;
|
||||||
|
import org.eclipse.core.runtime.preferences.DefaultScope;
|
||||||
|
import org.eclipse.core.runtime.preferences.IPreferenceMetadataStore;
|
||||||
|
import org.eclipse.core.runtime.preferences.IScopeContext;
|
||||||
|
import org.eclipse.core.runtime.preferences.InstanceScope;
|
||||||
|
import org.eclipse.core.runtime.preferences.OsgiPreferenceMetadataStore;
|
||||||
|
import org.osgi.service.component.annotations.Component;
|
||||||
|
import org.osgi.service.component.annotations.Reference;
|
||||||
|
import org.osgi.service.component.annotations.ReferenceCardinality;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class PreferenceConfigurationAccess extends ConfigurationAccess implements Configuration {
|
||||||
|
|
||||||
|
@Reference
|
||||||
|
private PreferencesMetadata metadata;
|
||||||
|
|
||||||
|
@Reference
|
||||||
|
private IWorkspace workspace;
|
||||||
|
|
||||||
|
@Reference(cardinality = ReferenceCardinality.OPTIONAL)
|
||||||
|
private GenerateCDBEnable enable;
|
||||||
|
|
||||||
|
public PreferenceConfigurationAccess() {
|
||||||
|
super(new Qualifier().get());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PreferenceOptions defaults() {
|
||||||
|
return new PreferencePreferredOptions(qualifier, new IScopeContext[] { DefaultScope.INSTANCE }, metadata,
|
||||||
|
enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PreferenceOptions options(Object context) {
|
||||||
|
Optional<ProjectScope> project = projectScope(workspace, context);
|
||||||
|
IScopeContext[] scopes;
|
||||||
|
if (project.isPresent()) {
|
||||||
|
scopes = new IScopeContext[] { project.get(), InstanceScope.INSTANCE, DefaultScope.INSTANCE };
|
||||||
|
} else {
|
||||||
|
scopes = new IScopeContext[] { InstanceScope.INSTANCE, DefaultScope.INSTANCE };
|
||||||
|
}
|
||||||
|
return new PreferencePreferredOptions(qualifier, scopes, metadata, enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IPreferenceMetadataStore storage(Object context) {
|
||||||
|
return new OsgiPreferenceMetadataStore(//
|
||||||
|
preferences(//
|
||||||
|
projectScope(workspace, context)//
|
||||||
|
.map(IScopeContext.class::cast)//
|
||||||
|
.orElse(InstanceScope.INSTANCE)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PreferencesMetadata metadata() {
|
||||||
|
return metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String qualifier() {
|
||||||
|
return qualifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2023 ArSysOp.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Alexander Fedorov (ArSysOp) - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.managedbuilder.internal.core.CommonBuilder;
|
||||||
|
import org.eclipse.cdt.managedbuilder.ui.properties.ManagedBuilderUIPlugin;
|
||||||
|
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
|
||||||
|
import org.eclipse.core.runtime.preferences.OsgiPreferenceMetadataStore;
|
||||||
|
import org.eclipse.jface.layout.GridLayoutFactory;
|
||||||
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
import org.eclipse.swt.widgets.Button;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
|
||||||
|
public final class PreferenceConfigurationArea extends ConfigurationArea {
|
||||||
|
|
||||||
|
private final Button generateCDBFileButton;
|
||||||
|
private final String ENABLE_FILE_GENERATION = CommonBuilder.COMPILATION_DATABASE_ENABLEMENT;
|
||||||
|
private IPreferenceStore preferenceStore;
|
||||||
|
|
||||||
|
public PreferenceConfigurationArea(Composite parent, PreferencesMetadata metadata, boolean isProjectScope) {
|
||||||
|
super(1);
|
||||||
|
Composite composite = new Composite(parent, SWT.NONE);
|
||||||
|
composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
|
||||||
|
composite.setLayout(GridLayoutFactory.fillDefaults().numColumns(columns).create());
|
||||||
|
this.generateCDBFileButton = createButton(metadata.generateCDBFile(), composite, SWT.CHECK, 0);
|
||||||
|
preferenceStore = ManagedBuilderUIPlugin.getDefault().getPreferenceStore();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void load(Object options, boolean enable) {
|
||||||
|
if (options instanceof PreferenceOptions editorOptions) {
|
||||||
|
if (generateCDBFileButton != null) {
|
||||||
|
generateCDBFileButton.setSelection(editorOptions.generateCDB());
|
||||||
|
generateCDBFileButton.setEnabled(enable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void store(IEclipsePreferences prefs) {
|
||||||
|
OsgiPreferenceMetadataStore store = new OsgiPreferenceMetadataStore(prefs);
|
||||||
|
buttons.entrySet().forEach(e -> store.save(e.getValue().getSelection(), e.getKey()));
|
||||||
|
preferenceStore.setValue(ENABLE_FILE_GENERATION, generateCDBFileButton.getSelection());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2023 Contributors to the Eclipse Foundation.
|
||||||
|
* This program and the accompanying materials are made
|
||||||
|
* available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* See git history
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.preferences.PreferenceMetadata;
|
||||||
|
import org.osgi.service.component.annotations.Component;
|
||||||
|
import org.osgi.service.component.annotations.Reference;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class PreferenceMetadataDefaults implements PreferencesMetadata {
|
||||||
|
|
||||||
|
@Reference
|
||||||
|
private PreferenceOptionsDefaults defaults;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PreferenceMetadata<Boolean> generateCDBFile() {
|
||||||
|
return new PreferenceMetadata<>(Boolean.class, //
|
||||||
|
"generateCDB", defaults.generateCDB(), // //$NON-NLS-1$
|
||||||
|
Messages.JsonCdbGeneratorPreferencePage_generateCompilationdatabase,
|
||||||
|
Messages.JsonCdbGeneratorPreferencePage_description);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2023 Contributors to the Eclipse Foundation.
|
||||||
|
* This program and the accompanying materials are made
|
||||||
|
* available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* See git history
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
public interface PreferenceOptions {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compilation Database Generator needed
|
||||||
|
*/
|
||||||
|
boolean generateCDB();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2023 Contributors to the Eclipse Foundation.
|
||||||
|
* This program and the accompanying materials are made
|
||||||
|
* available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* See git history
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
public interface PreferenceOptionsDefaults extends PreferenceOptions {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2023 Contributors to the Eclipse Foundation.
|
||||||
|
* This program and the accompanying materials are made
|
||||||
|
* available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* See git history
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.runtime.preferences.IScopeContext;
|
||||||
|
|
||||||
|
public class PreferencePreferredOptions extends PreferredOptions implements PreferenceOptions, GenerateCDBEnable {
|
||||||
|
private final PreferencesMetadata metadata;
|
||||||
|
private final GenerateCDBEnable enable;
|
||||||
|
|
||||||
|
public PreferencePreferredOptions(String qualifier, IScopeContext[] scopes, PreferencesMetadata metadata,
|
||||||
|
GenerateCDBEnable enable) {
|
||||||
|
super(qualifier, scopes);
|
||||||
|
this.metadata = Objects.requireNonNull(metadata);
|
||||||
|
this.enable = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean generateCDB() {
|
||||||
|
return booleanValue(metadata.generateCDBFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabledFor(IProject project) {
|
||||||
|
if (enable != null) {
|
||||||
|
return enable.isEnabledFor(project);
|
||||||
|
}
|
||||||
|
return booleanValue(metadata.generateCDBFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2023 Contributors to the Eclipse Foundation.
|
||||||
|
* This program and the accompanying materials are made
|
||||||
|
* available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* See git history
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.preferences.PreferenceMetadata;
|
||||||
|
|
||||||
|
public interface PreferencesMetadata {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the metadata for the "Generate compile_commands.json file" option, must not return <code>null</code>.
|
||||||
|
*
|
||||||
|
* @return the metadata for the "Generate compile_commands.json file" option
|
||||||
|
*
|
||||||
|
* @see PreferenceOptions#generateCDB()
|
||||||
|
*/
|
||||||
|
PreferenceMetadata<Boolean> generateCDBFile();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2023 Contributors to the Eclipse Foundation.
|
||||||
|
* This program and the accompanying materials are made
|
||||||
|
* available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* See git history
|
||||||
|
*******************************************************************************/
|
||||||
|
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.preferences.IScopeContext;
|
||||||
|
import org.eclipse.core.runtime.preferences.PreferenceMetadata;
|
||||||
|
|
||||||
|
public abstract class PreferredOptions {
|
||||||
|
protected final String qualifier;
|
||||||
|
protected final IScopeContext[] scopes;
|
||||||
|
|
||||||
|
public PreferredOptions(String qualifier, IScopeContext[] scopes) {
|
||||||
|
this.qualifier = Objects.requireNonNull(qualifier);
|
||||||
|
this.scopes = Objects.requireNonNull(scopes);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String stringValue(PreferenceMetadata<?> meta) {
|
||||||
|
String actual = String.valueOf(meta.defaultValue());
|
||||||
|
for (int i = scopes.length - 1; i >= 0; i--) {
|
||||||
|
IScopeContext scope = scopes[i];
|
||||||
|
String previous = actual;
|
||||||
|
actual = scope.getNode(qualifier).get(meta.identifer(), previous);
|
||||||
|
}
|
||||||
|
return actual;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean booleanValue(PreferenceMetadata<Boolean> meta) {
|
||||||
|
return Optional.of(meta)//
|
||||||
|
.map(this::stringValue)//
|
||||||
|
.map(Boolean::valueOf)//
|
||||||
|
.orElseGet(meta::defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
/********************************************************************************
|
||||||
|
* Copyright (c) 2023, 2024 Renesas Electronics Corp. and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-2.0.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
********************************************************************************/
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public final class Qualifier implements Supplier<String> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String get() {
|
||||||
|
return "org.eclipse.cdt.managedbuilder.ui"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2023 ArSysOp.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Alexander Fedorov (ArSysOp) - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IProject;
|
||||||
|
import org.eclipse.core.resources.IResource;
|
||||||
|
import org.eclipse.core.resources.IWorkspace;
|
||||||
|
import org.eclipse.core.runtime.Adapters;
|
||||||
|
|
||||||
|
public final class ResolveProject implements Function<Object, Optional<IProject>> {
|
||||||
|
|
||||||
|
private final ExistingResource resolve;
|
||||||
|
|
||||||
|
public ResolveProject(IWorkspace workspace) {
|
||||||
|
this.resolve = new ExistingResource(workspace);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<IProject> apply(Object context) {
|
||||||
|
return Optional.ofNullable(context)//
|
||||||
|
.flatMap(this::resource)//
|
||||||
|
.map(IResource::getProject);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<IResource> resource(Object object) {
|
||||||
|
return uri(object).or(() -> adapt(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<IResource> uri(Object object) {
|
||||||
|
return Optional.ofNullable(object)//
|
||||||
|
.filter(URI.class::isInstance)//
|
||||||
|
.map(URI.class::cast)//
|
||||||
|
.flatMap(resolve);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<IResource> adapt(Object object) {
|
||||||
|
return Optional.ofNullable(Adapters.adapt(object, IResource.class));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2023 ArSysOp.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Alexander Fedorov (ArSysOp) - Initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IWorkspace;
|
||||||
|
import org.eclipse.core.resources.ProjectScope;
|
||||||
|
|
||||||
|
public final class ResolveProjectScope implements Function<Object, Optional<ProjectScope>> {
|
||||||
|
|
||||||
|
private final ResolveProject project;
|
||||||
|
|
||||||
|
public ResolveProjectScope(IWorkspace workspace) {
|
||||||
|
this.project = new ResolveProject(workspace);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<ProjectScope> apply(Object context) {
|
||||||
|
return project.apply(context).map(ProjectScope::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
###############################################################################
|
||||||
|
# Copyright (c) 2023, 2024 Renesas Electronics Corp. and others.
|
||||||
|
#
|
||||||
|
# This program and the accompanying materials are made available under the
|
||||||
|
# terms of the Eclipse Public License 2.0 which is available at
|
||||||
|
# http://www.eclipse.org/legal/epl-2.0.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: EPL-2.0
|
||||||
|
###############################################################################
|
||||||
|
JsonCdbGeneratorPreferencePage_description=Enables default generation of compile_commands.json file on build process
|
||||||
|
JsonCdbGeneratorPreferencePage_generateCompilationdatabase=Generate compile_commands.json file
|
||||||
|
JsonCdbGeneratorPropertyPage_configureWorkspace=Configure Workspace Settings...
|
||||||
|
JsonCdbGeneratorPropertyPage_enableProjectSpecific=Enable project-specific settings
|
Loading…
Add table
Reference in a new issue