diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/resources/builderTests/regressions/README.txt b/build/org.eclipse.cdt.managedbuilder.core.tests/resources/builderTests/regressions/README.txt index 58b16439453..5368853f439 100644 --- a/build/org.eclipse.cdt.managedbuilder.core.tests/resources/builderTests/regressions/README.txt +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/resources/builderTests/regressions/README.txt @@ -3,5 +3,9 @@ helloworldC.zip: Basic standard Linux GCC C HelloWorld ManagedBuild Project template. Contains Debug + Release configurations. +helloworldCPP.zip: + Minimal standard Linux GCC C++ HelloWorld ManagedBuild Project template + Contains Debug + Release configurations. + bug_335476.zip: Test for noticing environment variable changes. \ No newline at end of file diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/resources/builderTests/regressions/helloworldCPP.zip b/build/org.eclipse.cdt.managedbuilder.core.tests/resources/builderTests/regressions/helloworldCPP.zip new file mode 100644 index 00000000000..c92696a4e14 Binary files /dev/null and b/build/org.eclipse.cdt.managedbuilder.core.tests/resources/builderTests/regressions/helloworldCPP.zip differ diff --git a/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/CompilationDatabaseGenerationTest.java b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/CompilationDatabaseGenerationTest.java new file mode 100644 index 00000000000..6bb958844b5 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core.tests/tests/org/eclipse/cdt/managedbuilder/core/tests/CompilationDatabaseGenerationTest.java @@ -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); + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/.project b/build/org.eclipse.cdt.managedbuilder.core/.project index cab798d8b70..70542d7e9d9 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/.project +++ b/build/org.eclipse.cdt.managedbuilder.core/.project @@ -25,6 +25,11 @@ + + org.eclipse.pde.ds.core.builder + + + org.eclipse.jdt.core.javanature diff --git a/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF b/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF index 413d69ae823..3d59b08efd7 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF +++ b/build/org.eclipse.cdt.managedbuilder.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName 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-Vendor: %providerName Bundle-Localization: plugin @@ -12,9 +12,11 @@ Export-Package: org.eclipse.cdt.build.core.scannerconfig, org.eclipse.cdt.managedbuilder.buildmodel, org.eclipse.cdt.managedbuilder.buildproperties, org.eclipse.cdt.managedbuilder.core, + org.eclipse.cdt.managedbuilder.core.jsoncdb, org.eclipse.cdt.managedbuilder.envvar, 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.jsoncdb.generator;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.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.core.variables;bundle-version="[3.1.100,4.0.0)", 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-RequiredExecutionEnvironment: JavaSE-17 Import-Package: com.google.gson;version="2.8.0" diff --git a/build/org.eclipse.cdt.managedbuilder.core/plugin.properties b/build/org.eclipse.cdt.managedbuilder.core/plugin.properties index 05c1695ec50..0e5591443c2 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/plugin.properties +++ b/build/org.eclipse.cdt.managedbuilder.core/plugin.properties @@ -78,6 +78,7 @@ extension-point.name.0 = Managed Build Definitions extension-point.name.1 = Managed Build Project Converter extension-point.name.2 = Build Properties extension-point.name.3 = ToolChain Modification Info +extension-point.name.4 = Compilation Database Contributor GCCBuildOutputParser.name = CDT GCC Build Output Parser GCCBuiltinCompilerSettings.name = CDT GCC Built-in Compiler Settings diff --git a/build/org.eclipse.cdt.managedbuilder.core/plugin.xml b/build/org.eclipse.cdt.managedbuilder.core/plugin.xml index f4892de8a22..076b3a70cc7 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/plugin.xml +++ b/build/org.eclipse.cdt.managedbuilder.core/plugin.xml @@ -7,6 +7,8 @@ + + diff --git a/build/org.eclipse.cdt.managedbuilder.core/schema/compilationDatabaseContributor.exsd b/build/org.eclipse.cdt.managedbuilder.core/schema/compilationDatabaseContributor.exsd new file mode 100644 index 00000000000..ebe86d50583 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/schema/compilationDatabaseContributor.exsd @@ -0,0 +1,84 @@ + + + + + + + + + This extension point allows to add specific information to compile_commands.json file. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Compilation Database for C/C++ projects + + + + + + + Toolchain ID + + + + + + + + + + + + + + + + + + + + + + diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/jsoncdb/CompilationDatabaseInformation.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/jsoncdb/CompilationDatabaseInformation.java new file mode 100644 index 00000000000..dd3743e8ad0 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/jsoncdb/CompilationDatabaseInformation.java @@ -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) { +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/jsoncdb/ICompilationDatabaseContributor.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/jsoncdb/ICompilationDatabaseContributor.java new file mode 100644 index 00000000000..e76afa1bb93 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/core/jsoncdb/ICompilationDatabaseContributor.java @@ -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 getAdditionalFiles(@NonNull IConfiguration config); + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java index 2d6c149f7ce..58e9bd75771 100644 --- a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/CommonBuilder.java @@ -57,6 +57,7 @@ import org.eclipse.cdt.managedbuilder.internal.buildmodel.IConfigurationBuildState; import org.eclipse.cdt.managedbuilder.internal.buildmodel.IProjectBuildState; 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.IBuildMacroProvider; import org.eclipse.cdt.managedbuilder.makegen.IManagedBuilderMakefileGenerator; @@ -85,6 +86,9 @@ import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.core.runtime.jobs.ISchedulingRule; 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 { @@ -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 TRACE_FOOTER = "]: "; //$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; private static final int PROGRESS_MONITOR_SCALE = 100; @@ -505,6 +510,10 @@ private IProject[] build(int kind, IProject project, IBuilder[] builders, boolea } for (int i = 0; i < num; i++) { + if (isGenerateFileOptionEnabled()) { + CompilationDatabaseGenerator generator = new CompilationDatabaseGenerator(getProject(), activeCfg); + generator.generate(); + } //bug 219337 if (kind == INCREMENTAL_BUILD || kind == AUTO_BUILD) { if (buildConfigResourceChanges()) { //only build projects with project resource changes @@ -1375,4 +1384,15 @@ public ISchedulingRule getRule(int trigger, Map args) { // Success! 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; + } } diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/jsoncdb/generator/CompilationDatabaseContributionManager.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/jsoncdb/generator/CompilationDatabaseContributionManager.java new file mode 100644 index 00000000000..b6792ab56a9 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/jsoncdb/generator/CompilationDatabaseContributionManager.java @@ -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 loadedInstances = new HashMap<>(); + /** + * Map of tool chain IDs (see {@link IToolChain#getId()} to + * extension point information for the compilationDatabaseContributor extension. + */ + private final Map factoryExtensions = new HashMap<>(); + + private class EmptyCompilationDatabaseContributor implements ICompilationDatabaseContributor { + + @Override + public final @NonNull List 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(); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/jsoncdb/generator/CompilationDatabaseGenerator.java b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/jsoncdb/generator/CompilationDatabaseGenerator.java new file mode 100644 index 00000000000..70382ed667d --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.core/src/org/eclipse/cdt/managedbuilder/internal/core/jsoncdb/generator/CompilationDatabaseGenerator.java @@ -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 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 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 populateObjList(IProject project, IConfiguration config) + throws CoreException, BuildException { + List 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 enumeratedPrimaryOutputs = new ArrayList<>(); + calculateOutputsForSource(tool, relativePath, sourceLocation, enumeratedPrimaryOutputs); + ArrayList 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 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 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; + } + + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/.project b/build/org.eclipse.cdt.managedbuilder.ui/.project index 0efa7a6ca87..9724ff19b08 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/.project +++ b/build/org.eclipse.cdt.managedbuilder.ui/.project @@ -25,6 +25,11 @@ + + org.eclipse.pde.ds.core.builder + + + org.eclipse.jdt.core.javanature diff --git a/build/org.eclipse.cdt.managedbuilder.ui/.settings/org.eclipse.pde.ds.annotations.prefs b/build/org.eclipse.cdt.managedbuilder.ui/.settings/org.eclipse.pde.ds.annotations.prefs new file mode 100644 index 00000000000..38f9eecff8e --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/.settings/org.eclipse.pde.ds.annotations.prefs @@ -0,0 +1,7 @@ +dsVersion=V1_3 +eclipse.preferences.version=1 +enabled=true +generateBundleActivationPolicyLazy=true +path=OSGI-INF +validationErrorLevel=error +validationErrorLevel.missingImplicitUnbindMethod=error diff --git a/build/org.eclipse.cdt.managedbuilder.ui/META-INF/MANIFEST.MF b/build/org.eclipse.cdt.managedbuilder.ui/META-INF/MANIFEST.MF index 211ddabea56..9f9770f226e 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/META-INF/MANIFEST.MF +++ b/build/org.eclipse.cdt.managedbuilder.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName 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-Vendor: %providerName 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-RequiredExecutionEnvironment: JavaSE-17 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 diff --git a/build/org.eclipse.cdt.managedbuilder.ui/OSGI-INF/org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.BuiltinPreferedOptionsDefaults.xml b/build/org.eclipse.cdt.managedbuilder.ui/OSGI-INF/org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.BuiltinPreferedOptionsDefaults.xml new file mode 100644 index 00000000000..ac26a7bcdae --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/OSGI-INF/org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.BuiltinPreferedOptionsDefaults.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/build/org.eclipse.cdt.managedbuilder.ui/OSGI-INF/org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.PreferenceConfigurationAccess.xml b/build/org.eclipse.cdt.managedbuilder.ui/OSGI-INF/org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.PreferenceConfigurationAccess.xml new file mode 100644 index 00000000000..45f61850759 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/OSGI-INF/org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.PreferenceConfigurationAccess.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/build/org.eclipse.cdt.managedbuilder.ui/OSGI-INF/org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.PreferenceMetadataDefaults.xml b/build/org.eclipse.cdt.managedbuilder.ui/OSGI-INF/org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.PreferenceMetadataDefaults.xml new file mode 100644 index 00000000000..383524e4d1c --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/OSGI-INF/org.eclipse.cdt.managedbuilder.internal.ui.compilationdatabase.PreferenceMetadataDefaults.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/build/org.eclipse.cdt.managedbuilder.ui/build.properties b/build/org.eclipse.cdt.managedbuilder.ui/build.properties index a22b5265eb1..dfd8c9af335 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/build.properties +++ b/build/org.eclipse.cdt.managedbuilder.ui/build.properties @@ -16,7 +16,8 @@ bin.includes = plugin.xml,\ about.html,\ icons/,\ .,\ - META-INF/ + META-INF/,\ + OSGI-INF/ src.includes = schema/,\ about.html source.. = src/ diff --git a/build/org.eclipse.cdt.managedbuilder.ui/plugin.properties b/build/org.eclipse.cdt.managedbuilder.ui/plugin.properties index 14a4812b3e0..1ab240aa55e 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/plugin.properties +++ b/build/org.eclipse.cdt.managedbuilder.ui/plugin.properties @@ -119,3 +119,5 @@ Configurations.menu=Build Configurations buildDefinitionsUI.ep.name = Build Definitions UI extension-point.name = Custom MBS New Wizard Pages + +JSONCompilatioDatabaseGeneratorPage.name = JSON Compilation Database Generator \ No newline at end of file diff --git a/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml b/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml index 198bcea8041..204de3966ee 100644 --- a/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml +++ b/build/org.eclipse.cdt.managedbuilder.ui/plugin.xml @@ -340,6 +340,12 @@ id="org.eclipse.cdt.managedbuilder.ui.preferences.PrefPage_MultiConfig" name="%multicfg"> + + @@ -809,6 +815,12 @@ + + @@ -917,5 +929,4 @@ label="%CDTToolchainProperty.keyword.toolchain2"> - diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/BuiltinPreferedOptionsDefaults.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/BuiltinPreferedOptionsDefaults.java new file mode 100644 index 00000000000..439376d4c0e --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/BuiltinPreferedOptionsDefaults.java @@ -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; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/CompilationDatabaseGeneratorBlock.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/CompilationDatabaseGeneratorBlock.java new file mode 100644 index 00000000000..bfc6e6d6102 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/CompilationDatabaseGeneratorBlock.java @@ -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("" + text + ""); //$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() { + 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(); + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/Configuration.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/Configuration.java new file mode 100644 index 00000000000..3ca5b288b9d --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/Configuration.java @@ -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 null + * @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 null + * @param context to be adapter to the proper scope + * + * @return preference store + */ + IPreferenceMetadataStore storage(Object context); + + /** + * Return the metadata for options, must not return null + * + * @return the option metadata + */ + Object metadata(); + + /** + * Default qualifier to use for preference storage + * @return preference qualifier + */ + String qualifier(); +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/ConfigurationAccess.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/ConfigurationAccess.java new file mode 100644 index 00000000000..a749a783ee2 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/ConfigurationAccess.java @@ -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(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))); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/ConfigurationArea.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/ConfigurationArea.java new file mode 100644 index 00000000000..8c71ba10fbb --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/ConfigurationArea.java @@ -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, Button> buttons; + protected final List> 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 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 listener) { + listeners.add(listener); + } + + public void removeChangeListener(Consumer 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); + +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/ExistingResource.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/ExistingResource.java new file mode 100644 index 00000000000..84b88d3caf0 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/ExistingResource.java @@ -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> { + + private final IWorkspace workspace; + + public ExistingResource(IWorkspace workspace) { + this.workspace = Objects.requireNonNull(workspace); + } + + @Override + public Optional apply(URI uri) { + return forContainer(uri).or(() -> forFile(uri)); + } + + private Optional forContainer(URI uri) { + return Arrays.stream(workspace.getRoot().findContainersForLocationURI(uri))// + .map(IResource.class::cast)// + .filter(c -> c.exists())// + .findFirst(); + } + + private Optional forFile(URI uri) { + return Arrays.stream(workspace.getRoot().findFilesForLocationURI(uri))// + .map(IResource.class::cast)// + .filter(c -> c.exists())// + .findFirst(); + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/GenerateCDBEnable.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/GenerateCDBEnable.java new file mode 100644 index 00000000000..d82b320c876 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/GenerateCDBEnable.java @@ -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); +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/JsonCdbGeneratorPreferencePage.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/JsonCdbGeneratorPreferencePage.java new file mode 100644 index 00000000000..6ca2209fa70 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/JsonCdbGeneratorPreferencePage.java @@ -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; + } + +} \ No newline at end of file diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/JsonCdbGeneratorPropertyPage.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/JsonCdbGeneratorPropertyPage.java new file mode 100644 index 00000000000..a5833de00a5 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/JsonCdbGeneratorPropertyPage.java @@ -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; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/Messages.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/Messages.java new file mode 100644 index 00000000000..1836c7e3754 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/Messages.java @@ -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() { + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferenceConfigurationAccess.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferenceConfigurationAccess.java new file mode 100644 index 00000000000..f3e520eacb8 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferenceConfigurationAccess.java @@ -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 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; + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferenceConfigurationArea.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferenceConfigurationArea.java new file mode 100644 index 00000000000..61dbccbfa9a --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferenceConfigurationArea.java @@ -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()); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferenceMetadataDefaults.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferenceMetadataDefaults.java new file mode 100644 index 00000000000..260031a4f08 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferenceMetadataDefaults.java @@ -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 generateCDBFile() { + return new PreferenceMetadata<>(Boolean.class, // + "generateCDB", defaults.generateCDB(), // //$NON-NLS-1$ + Messages.JsonCdbGeneratorPreferencePage_generateCompilationdatabase, + Messages.JsonCdbGeneratorPreferencePage_description); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferenceOptions.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferenceOptions.java new file mode 100644 index 00000000000..e52f5cf430f --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferenceOptions.java @@ -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(); + +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferenceOptionsDefaults.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferenceOptionsDefaults.java new file mode 100644 index 00000000000..bcb8c3cda1a --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferenceOptionsDefaults.java @@ -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 { + +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferencePreferredOptions.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferencePreferredOptions.java new file mode 100644 index 00000000000..667c13cb68b --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferencePreferredOptions.java @@ -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()); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferencesMetadata.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferencesMetadata.java new file mode 100644 index 00000000000..13805c5ccea --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferencesMetadata.java @@ -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 null. + * + * @return the metadata for the "Generate compile_commands.json file" option + * + * @see PreferenceOptions#generateCDB() + */ + PreferenceMetadata generateCDBFile(); + +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferredOptions.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferredOptions.java new file mode 100644 index 00000000000..a72dc8f758c --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/PreferredOptions.java @@ -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 meta) { + return Optional.of(meta)// + .map(this::stringValue)// + .map(Boolean::valueOf)// + .orElseGet(meta::defaultValue); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/Qualifier.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/Qualifier.java new file mode 100644 index 00000000000..1955d2e9094 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/Qualifier.java @@ -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 { + + @Override + public String get() { + return "org.eclipse.cdt.managedbuilder.ui"; //$NON-NLS-1$ + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/ResolveProject.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/ResolveProject.java new file mode 100644 index 00000000000..0ebcf815568 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/ResolveProject.java @@ -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> { + + private final ExistingResource resolve; + + public ResolveProject(IWorkspace workspace) { + this.resolve = new ExistingResource(workspace); + } + + @Override + public Optional apply(Object context) { + return Optional.ofNullable(context)// + .flatMap(this::resource)// + .map(IResource::getProject); + } + + private Optional resource(Object object) { + return uri(object).or(() -> adapt(object)); + } + + private Optional uri(Object object) { + return Optional.ofNullable(object)// + .filter(URI.class::isInstance)// + .map(URI.class::cast)// + .flatMap(resolve); + } + + private Optional adapt(Object object) { + return Optional.ofNullable(Adapters.adapt(object, IResource.class)); + } +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/ResolveProjectScope.java b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/ResolveProjectScope.java new file mode 100644 index 00000000000..b190a9d60a4 --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/ResolveProjectScope.java @@ -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> { + + private final ResolveProject project; + + public ResolveProjectScope(IWorkspace workspace) { + this.project = new ResolveProject(workspace); + } + + @Override + public Optional apply(Object context) { + return project.apply(context).map(ProjectScope::new); + } + +} diff --git a/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/messages.properties b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/messages.properties new file mode 100644 index 00000000000..ad0a26b0c7e --- /dev/null +++ b/build/org.eclipse.cdt.managedbuilder.ui/src/org/eclipse/cdt/managedbuilder/internal/ui/compilationdatabase/messages.properties @@ -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 \ No newline at end of file