diff --git a/plugin_ide.core.tests/src-lang/melnorme/lang/ide/core/engine/ModelReconcilationTest.java b/plugin_ide.core.tests/src-lang/melnorme/lang/ide/core/engine/ModelReconcilationTest.java index 09838068f..fc7a459c2 100644 --- a/plugin_ide.core.tests/src-lang/melnorme/lang/ide/core/engine/ModelReconcilationTest.java +++ b/plugin_ide.core.tests/src-lang/melnorme/lang/ide/core/engine/ModelReconcilationTest.java @@ -42,6 +42,7 @@ import melnorme.lang.tooling.ast.ParserError; import melnorme.lang.tooling.structure.SourceFileStructure; import melnorme.utilbox.collections.Indexable; +import melnorme.utilbox.core.CommonException; class AnnotationsModelManager { @@ -72,7 +73,7 @@ public void dispose() throws Exception { super.dispose(); } - public void initProject() throws CoreException { + public void initProject() throws CoreException, CommonException { fixtureProject = new SampleProject(ModelReconcilationTest.class.getSimpleName()) { @Override protected void fillProject() throws CoreException { @@ -81,7 +82,6 @@ protected void fillProject() throws CoreException { ResourceUtils.writeStringToFile(folder.getFile("fileA"), "default contents A", null); ResourceUtils.writeStringToFile(folder.getFile("fileB"), "default contents B", null); - } }; } diff --git a/plugin_ide.core.tests/src-lang/melnorme/lang/ide/core/operations/build/BuildManager_Test.java b/plugin_ide.core.tests/src-lang/melnorme/lang/ide/core/operations/build/BuildManager_Test.java index a26a5a59c..2f2bd2d1d 100644 --- a/plugin_ide.core.tests/src-lang/melnorme/lang/ide/core/operations/build/BuildManager_Test.java +++ b/plugin_ide.core.tests/src-lang/melnorme/lang/ide/core/operations/build/BuildManager_Test.java @@ -29,13 +29,11 @@ import melnorme.lang.ide.core.launch.LaunchMessages; import melnorme.lang.ide.core.operations.ILangOperationsListener_Default.NullOperationMonitor; import melnorme.lang.ide.core.operations.ToolManager; -import melnorme.lang.ide.core.operations.ToolchainPreferences; import melnorme.lang.ide.core.operations.build.BuildManager_Test.TestsBuildManager.SampleStrictBuildType; import melnorme.lang.ide.core.operations.build.BuildTargetOperation.BuildOperationParameters; import melnorme.lang.ide.core.project_model.LangBundleModel; import melnorme.lang.ide.core.tests.BuildTestsHelper; import melnorme.lang.ide.core.tests.CoreTestWithProject; -import melnorme.lang.ide.core.tests.SampleProject; import melnorme.lang.tooling.bundle.BuildConfiguration; import melnorme.lang.tooling.bundle.BuildTargetNameParser; import melnorme.lang.tooling.data.StatusException; @@ -157,85 +155,48 @@ protected BuildConfiguration getValidBuildconfiguration(String buildConfigName, @Test public void test() throws Exception { test$(); } public void test$() throws Exception { + initSampleProject(); - try(SampleProject sampleProj = initSampleProject()){ - - buildMgr.loadProjectBuildInfo(project, bundleInfo); - - ProjectBuildInfo buildInfo = buildMgr.getBuildInfo(project); - assertNotNull(buildInfo); - checkBuildTargets(buildInfo.getBuildTargets().toArrayList(), list( - sampleBT_A, - sampleBT_B, - sampleBT_STRICT) - ); - - assertEquals( - buildMgr.getBuildTarget(project, "TargetA", true).getData(), - sampleBT_A); - assertEquals( - buildMgr.getBuildTarget(project, "TargetB", true).getData(), - sampleBT_B); - verifyThrows( - () -> buildMgr.getBuildTarget(project, "TargetA#default", true).getData(), - CommonException.class, - LaunchMessages.BuildTarget_NotFound); - - verifyThrows( - () -> buildMgr.getBuildTarget(project, "TargetA"+SEP+"bad_config", false).getData(), - CommonException.class, - "No such build type: `bad_config`"); // Build Type not found - - assertEquals( - buildMgr.getBuildTarget(project, "ImplicitTarget"+SEP+"default", false).getData(), - bt("ImplicitTarget"+SEP+"default", false, false, null, null)); - - verifyThrows( - () -> buildMgr.getBuildTarget(project, "ImplicitTarget"+SEP+"strict", false).getData(), - CommonException.class, - "Build configuration `ImplicitTarget` not found"); // Config not found - - } - - try(SampleProject sampleProj = initSampleProject()){ - testSaveLoadProjectInfo(); - } - - try(SampleProject sampleProj = initSampleProject()){ - testBuildOperation(); - } - } - - protected void testSaveLoadProjectInfo() throws CommonException { - - SampleStrictBuildType buildType = buildMgr.new SampleStrictBuildType("default"); - BuildConfiguration buildConfig = new BuildConfiguration("configA", null); - - BuildTarget btA = new BuildTarget(project, bundleInfo, bt("TargetA", false, true, "new1", "new3"), - buildType, buildConfig); - BuildTarget btNonExistentButValid = new BuildTarget(project, bundleInfo, - new BuildTargetData("TargetA" + SEP + "default", true, false), - buildType, buildConfig); - BuildTarget btNonExistent = new BuildTarget(project, bundleInfo, - new BuildTargetData("TargetA" + SEP + "NonExistentType", false, true), - buildType, buildConfig); - - ProjectBuildInfo newProjectBuildInfo = new ProjectBuildInfo(buildMgr, project, bundleInfo, - new ArrayList2<>(btA, btNonExistentButValid, btNonExistent)); - buildMgr.setProjectBuildInfo(project, newProjectBuildInfo); - buildMgr.saveProjectInfo(project); - - buildMgr.getBuildModel().removeProjectInfo(project); - assertTrue(buildMgr.getBuildModel().getProjectInfo(project) == null); buildMgr.loadProjectBuildInfo(project, bundleInfo); ProjectBuildInfo buildInfo = buildMgr.getBuildInfo(project); + assertNotNull(buildInfo); checkBuildTargets(buildInfo.getBuildTargets().toArrayList(), list( - bt("TargetA", false, true, "new1", "new3"), // Ensure TargetA uses previous settings + sampleBT_A, sampleBT_B, sampleBT_STRICT) ); + + assertEquals( + buildMgr.getBuildTarget(project, "TargetA", true).getData(), + sampleBT_A); + assertEquals( + buildMgr.getBuildTarget(project, "TargetB", true).getData(), + sampleBT_B); + verifyThrows( + () -> buildMgr.getBuildTarget(project, "TargetA#default", true).getData(), + CommonException.class, + LaunchMessages.BuildTarget_NotFound); + verifyThrows( + () -> buildMgr.getBuildTarget(project, "TargetA"+SEP+"bad_config", false).getData(), + CommonException.class, + "No such build type: `bad_config`"); // Build Type not found + + assertEquals( + buildMgr.getBuildTarget(project, "ImplicitTarget"+SEP+"default", false).getData(), + bt("ImplicitTarget"+SEP+"default", false, false, null, null)); + + verifyThrows( + () -> buildMgr.getBuildTarget(project, "ImplicitTarget"+SEP+"strict", false).getData(), + CommonException.class, + "Build configuration `ImplicitTarget` not found"); // Config not found + + + test_compositeBuildTargetSettings(); + test_BuildType(); + + testBuildOperation(); } public void checkBuildTargets(Indexable buildTargets, Indexable expectedSettings) { @@ -248,28 +209,23 @@ public void checkBuildTargets(Indexable buildTargets, Indexable buildTargetA.getEffectiveValidExecutablePath(), CommonException.class, - LaunchMessages.MSG_BuildTarget_NoExecutableAvailable()); - - BuildTargetData target2 = bt("SampleTarget2", true, true, "sample args", "sample path"); - BuildTarget buildTarget2 = BuildTarget.create(project, bundleInfo, target2, buildType, ""); - - assertAreEqual(buildTarget2.getEffectiveValidExecutablePath(), "sample path"); + ProjectBuildInfo buildInfo = buildMgr.getValidBuildInfo(project); + BundleInfo bundleInfo = buildInfo.getBundleInfo(); + + BuildTargetData targetA = bt("SampleTarget", true, true, null, null); + BuildTarget buildTargetA = BuildTarget.create(project, bundleInfo, targetA, buildType, ""); + verifyThrows(() -> buildTargetA.getEffectiveValidExecutablePath(), CommonException.class, + LaunchMessages.MSG_BuildTarget_NoExecutableAvailable()); + + BuildTargetData target2 = bt("SampleTarget2", true, true, "sample args", "sample path"); + BuildTarget buildTarget2 = BuildTarget.create(project, bundleInfo, target2, buildType, ""); + + assertAreEqual(buildTarget2.getEffectiveValidExecutablePath(), "sample path"); - } } protected NullOperationMonitor opMonitor = new NullOperationMonitor(); @@ -349,30 +297,37 @@ protected void testBuildOperation() throws CommonException, StatusException { BuildTarget btA = buildMgr.getBuildTarget(project, "TargetA", true); assertTrue(btA.getData().getBuildArguments() == null); - BuildTarget btB = buildMgr.getBuildTarget(project, "TargetB", true); - assertTrue(btB.getData().getBuildArguments() != null); - assertAreEqual( btA.getBuildOperation(toolMgr, opMonitor).getEffectiveProccessCommandLine(), - list("default:", "build_args") + list(strSDKTool(), "default:", "build_args") ); + BuildTarget btB = buildMgr.getBuildTarget(project, "TargetB", true); + assertTrue(btB.getData().getBuildArguments() != null); + assertAreEqual( btB.getBuildOperation(toolMgr, opMonitor).getEffectiveProccessCommandLine(), list("B:", "build_args") ); testBuildOperation_Vars(buildInfo, btB); + + // Test invalid command - empty + verifyThrows( + () -> getBuildOperation(buildInfo, btB, ""), + + CommonException.class, "Build command is empty" + ); + } protected void testBuildOperation_Vars(ProjectBuildInfo buildInfo, BuildTarget btB) throws CommonException { - ToolchainPreferences.SDK_PATH2.setValue(project, "my_tool_path"); // Test var resolution - SDK tool var assertAreEqual( getBuildOperation(buildInfo, btB, variableRefString(VAR_NAME_SdkToolPath) + " build"), - list("my_tool_path", "build") + list(strSDKTool(), "build") ); // Test var resolution - undefined var @@ -402,4 +357,41 @@ protected Indexable getBuildOperation(ProjectBuildInfo buildInfo, BuildT return buildOperation.getEffectiveProccessCommandLine(); } + /* ----------------- ----------------- */ + + @Test + public void test_SaveLoadProjectInfo() throws Exception { test_SaveLoadProjectInfo$(); } + public void test_SaveLoadProjectInfo$() throws Exception { + initSampleProject(); + + SampleStrictBuildType buildType = buildMgr.new SampleStrictBuildType("default"); + BuildConfiguration buildConfig = new BuildConfiguration("configA", null); + + BuildTarget btA = new BuildTarget(project, bundleInfo, bt("TargetA", false, true, "new1", "new3"), + buildType, buildConfig); + BuildTarget btNonExistentButValid = new BuildTarget(project, bundleInfo, + new BuildTargetData("TargetA" + SEP + "default", true, false), + buildType, buildConfig); + BuildTarget btNonExistent = new BuildTarget(project, bundleInfo, + new BuildTargetData("TargetA" + SEP + "NonExistentType", false, true), + buildType, buildConfig); + + ProjectBuildInfo newProjectBuildInfo = new ProjectBuildInfo(buildMgr, project, bundleInfo, + new ArrayList2<>(btA, btNonExistentButValid, btNonExistent)); + buildMgr.setProjectBuildInfo(project, newProjectBuildInfo); + buildMgr.saveProjectInfo(project); + + buildMgr.getBuildModel().removeProjectInfo(project); + assertTrue(buildMgr.getBuildModel().getProjectInfo(project) == null); + buildMgr.loadProjectBuildInfo(project, bundleInfo); + + ProjectBuildInfo buildInfo = buildMgr.getBuildInfo(project); + checkBuildTargets(buildInfo.getBuildTargets().toArrayList(), list( + bt("TargetA", false, true, "new1", "new3"), // Ensure TargetA uses previous settings + sampleBT_B, + sampleBT_STRICT) + ); + + } + } \ No newline at end of file diff --git a/plugin_ide.core.tests/src-lang/melnorme/lang/ide/core/tests/CoreTestWithProject.java b/plugin_ide.core.tests/src-lang/melnorme/lang/ide/core/tests/CoreTestWithProject.java index cba16166c..6f0dde676 100644 --- a/plugin_ide.core.tests/src-lang/melnorme/lang/ide/core/tests/CoreTestWithProject.java +++ b/plugin_ide.core.tests/src-lang/melnorme/lang/ide/core/tests/CoreTestWithProject.java @@ -11,30 +11,64 @@ package melnorme.lang.ide.core.tests; +import static melnorme.utilbox.core.Assert.AssertNamespace.assertNotNull; +import static melnorme.utilbox.core.Assert.AssertNamespace.assertTrue; + +import java.nio.file.Path; + import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; -import melnorme.lang.ide.core.tests.CommonCoreTest_ActualClass; +import melnorme.lang.ide.core.CorePreferences.PreferenceField; +import melnorme.lang.ide.core.LangCore; +import melnorme.lang.tests.LangCoreTests_Actual; +import melnorme.lang.tooling.data.StatusException; import melnorme.utilbox.core.CommonException; import melnorme.utilbox.ownership.IDisposable; public abstract class CoreTestWithProject extends CommonCoreTest_ActualClass { + public static class TestsProject extends SampleProject { + public TestsProject(String name, boolean create) throws CoreException, CommonException { + super(name, create); + } + + @Override + public void doCreate() throws CoreException, CommonException { + super.doCreate(); + + String SDK_PATH = LangCoreTests_Actual.SAMPLE_SDK_PATH.toString(); + SDK_LOCATION.doSetRawValue(project, SDK_PATH); + } + } + public CoreTestWithProject() { super(); } + protected static final PreferenceField SDK_LOCATION = LangCore.preferences().SDK_LOCATION; protected SampleProject sampleProject; protected IProject project; protected SampleProject initSampleProject() throws CoreException, CommonException { - this.sampleProject = new SampleProject(getClass().getSimpleName()); - return setSampleProject(sampleProject); + return setSampleProject(new TestsProject(getClass().getSimpleName(), false)); } - protected SampleProject setSampleProject(SampleProject sampleProject) { + protected SampleProject setSampleProject(SampleProject sampleProject) throws CoreException, CommonException { + if(this.sampleProject == sampleProject) { + return sampleProject; + } + + if(this.sampleProject != null) { + this.sampleProject.cleanUp(); + } + + this.sampleProject = sampleProject; this.project = sampleProject.getProject(); + sampleProject.create(); + assertTrue(sampleProject.getProject().exists()); + owned.add(new IDisposable() { @Override public void dispose() { @@ -48,4 +82,13 @@ public void dispose() { return sampleProject; } + protected Path getSDKToolPath() throws StatusException { + assertNotNull(project); + return SDK_LOCATION.getValue(project); + } + + protected String strSDKTool() throws StatusException { + return getSDKToolPath().toString(); + } + } \ No newline at end of file diff --git a/plugin_ide.core.tests/src-lang/melnorme/lang/ide/core/tests/SampleProject.java b/plugin_ide.core.tests/src-lang/melnorme/lang/ide/core/tests/SampleProject.java index ba77dedf2..78a250808 100644 --- a/plugin_ide.core.tests/src-lang/melnorme/lang/ide/core/tests/SampleProject.java +++ b/plugin_ide.core.tests/src-lang/melnorme/lang/ide/core/tests/SampleProject.java @@ -10,6 +10,7 @@ *******************************************************************************/ package melnorme.lang.ide.core.tests; +import static melnorme.utilbox.core.Assert.AssertNamespace.assertEquals; import static melnorme.utilbox.core.Assert.AssertNamespace.assertTrue; import org.eclipse.core.resources.IFile; @@ -18,7 +19,11 @@ import org.eclipse.core.runtime.CoreException; import melnorme.lang.ide.core.LangNature; +import melnorme.lang.ide.core.operations.ICoreOperation; +import melnorme.lang.ide.core.utils.EclipseUtils; import melnorme.lang.ide.core.utils.ResourceUtils; +import melnorme.utilbox.concurrency.OperationCancellation; +import melnorme.utilbox.core.CommonException; import melnorme.utilbox.misc.Location; @@ -26,8 +31,29 @@ public class SampleProject implements AutoCloseable { public final IProject project; - public SampleProject(String name) throws CoreException { - project = CommonCoreTest.createAndOpenProject(name, true); + public SampleProject(String name) throws CoreException, CommonException { + this(name, true); + } + + public SampleProject(String name, boolean create) throws CoreException, CommonException { + this.project = EclipseUtils.getWorkspaceRoot().getProject(name); + if(create) { + create(); + } + } + + public final void create() throws CoreException, CommonException { + ICoreOperation operation = (pm) -> doCreate(); + try { + ResourceUtils.runCommonOperationInWorkspace(operation, null, null); + } catch(OperationCancellation e) { + throw melnorme.utilbox.core.ExceptionAdapter.unchecked(e); + } + } + + public void doCreate() throws CoreException, CommonException { + IProject newProject = CommonCoreTest.createAndOpenProject(project.getName(), true); + assertEquals(project, newProject); fillProject(); CommonCoreTest.setupLangProject(project, false); assertTrue(project.getNature(LangNature.NATURE_ID) != null); diff --git a/plugin_ide.core/src-lang/melnorme/lang/ide/core/CorePreferences.java b/plugin_ide.core/src-lang/melnorme/lang/ide/core/CorePreferences.java new file mode 100644 index 000000000..e5813ad22 --- /dev/null +++ b/plugin_ide.core/src-lang/melnorme/lang/ide/core/CorePreferences.java @@ -0,0 +1,97 @@ +/******************************************************************************* + * Copyright (c) 2016 Bruno Medeiros and other Contributors. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bruno Medeiros - initial API and implementation + *******************************************************************************/ +package melnorme.lang.ide.core; + +import static melnorme.utilbox.core.Assert.AssertNamespace.assertNotNull; + +import java.nio.file.Path; +import java.util.Optional; +import java.util.function.Function; +import java.util.function.Supplier; + +import org.eclipse.core.resources.IProject; + +import melnorme.lang.ide.core.operations.ToolchainPreferences; +import melnorme.lang.ide.core.utils.prefs.IProjectPreference; +import melnorme.lang.ide.core.utils.prefs.PreferenceHelper; +import melnorme.lang.tooling.data.IValidator; +import melnorme.lang.tooling.data.StatusException; +import melnorme.lang.tooling.ops.SDKLocationValidator; +import melnorme.utilbox.misc.Location; + +public abstract class CorePreferences { + + public final PreferenceField SDK_LOCATION; + + public CorePreferences() { + SDK_LOCATION = newPathPreference(ToolchainPreferences.SDK_PATH, getSDKLocationValidator()); + } + + protected abstract SDKLocationValidator getSDKLocationValidator(); + + public static PreferenceField newPathPreference( + IProjectPreference pref, IValidator validator) { + return new PreferenceField<>(pref, validator, (path) -> path.toString()); + } + + public static PreferenceField newLocationPreference( + IProjectPreference pref, IValidator validator) { + return new PreferenceField<>(pref, validator, (loc) -> loc.toString()); + } + + public static class PreferenceField { + + public final IProjectPreference preference; + public final IValidator validator; + public final IValidator validator_toString; + + public PreferenceField(IProjectPreference preference, IValidator validator, + Function backToString) { + this.preference = assertNotNull(preference); + this.validator = assertNotNull(validator); + this.validator_toString = (value) -> backToString.apply(validator.getValidatedField(value)); + } + + public TYPE getValue(IProject project) throws StatusException { + return validator.getValidatedField(preference.getStoredValue(Optional.of(project))); + } + + public TYPE getValue() throws StatusException { + return validator.getValidatedField(preference.getGlobalPreference().get()); + } + + public IValidator getValidator() { + return validator; + } + + public IValidator getValidator_toString() { + return validator_toString; + } + + public PreferenceHelper getGlobalPreference() { + return preference.getGlobalPreference(); + } + + public Supplier getRawPreference(Optional project) { + if(project.isPresent()) { + return preference.getProperty(project); + } else { + return preference.getGlobalPreference(); + } + } + + public void doSetRawValue(IProject project, String value) { + preference.doSetValue(project, value); + } + + } + +} \ No newline at end of file diff --git a/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/ToolManager.java b/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/ToolManager.java index 5c70095c8..700a23a91 100644 --- a/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/ToolManager.java +++ b/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/ToolManager.java @@ -15,7 +15,6 @@ import java.nio.file.Path; import java.util.Optional; -import java.util.function.Supplier; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; @@ -23,6 +22,7 @@ import org.eclipse.core.variables.IStringVariableManager; import org.eclipse.core.variables.VariablesPlugin; +import melnorme.lang.ide.core.CorePreferences.PreferenceField; import melnorme.lang.ide.core.ILangOperationsListener; import melnorme.lang.ide.core.LangCore; import melnorme.lang.ide.core.LangCore_Actual; @@ -64,13 +64,7 @@ public void shutdownNow() { /* ----------------- ----------------- */ public Path getSDKToolPath(IProject project) throws CommonException { - Path validatedPath = getSDKToolPathValidator().getValidatedPath(getSDKPathPreference(project)); - assertNotNull(validatedPath); - return validatedPath; - } - - public String getSDKPathPreference(IProject project) { - return ToolchainPreferences.SDK_PATH2.getEffectiveValue(project); + return LangCore.preferences().SDK_LOCATION.getValue(project); } public abstract PathValidator getSDKToolPathValidator(); @@ -81,6 +75,7 @@ public String getSDKPathPreference(IProject project) { public VariablesResolver getVariablesManager(Optional project) { project = MiscUtil.toOptional(project); + VariablesResolver variablesResolver = new VariablesResolver(globalVarManager); setupVariableResolver(variablesResolver, project); @@ -88,18 +83,13 @@ public VariablesResolver getVariablesManager(Optional project) { } protected void setupVariableResolver(VariablesResolver variablesResolver, Optional project) { - Supplier sdkToolPath; - - if(project.isPresent()) { - sdkToolPath = ToolchainPreferences.SDK_PATH2.getProperty(project.get()); - } else { - sdkToolPath = ToolchainPreferences.SDK_PATH2.getGlobalPreference(); - } + PreferenceField pref = LangCore.preferences().SDK_LOCATION; variablesResolver.putDynamicVar(new SupplierAdapterVar( LangCore_Actual.VAR_NAME_SdkToolPath, LangCore_Actual.VAR_NAME_SdkToolPath_DESCRIPTION, - sdkToolPath) + pref.getRawPreference(project), + pref.getValidator_toString()) ); } diff --git a/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/ToolchainPreferences.java b/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/ToolchainPreferences.java index 2652a2a7c..006e0a6c6 100644 --- a/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/ToolchainPreferences.java +++ b/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/ToolchainPreferences.java @@ -20,7 +20,7 @@ public interface ToolchainPreferences { IProjectPreference USE_PROJECT_SETTINGS = new BooleanPreference( "toolchain_prefs.use_project_settings", false).getProjectPreference(); - public static final IProjectPreference SDK_PATH2 = new StringPreference(LangCore.PLUGIN_ID, "sdk_path", "", + public static final IProjectPreference SDK_PATH = new StringPreference(LangCore.PLUGIN_ID, "sdk_path", "", USE_PROJECT_SETTINGS).getProjectPreference(); public static final BooleanPreference FORMAT_ON_SAVE = diff --git a/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/build/BuildManager.java b/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/build/BuildManager.java index 4bf8083cd..88ea48773 100644 --- a/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/build/BuildManager.java +++ b/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/build/BuildManager.java @@ -17,6 +17,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.Map.Entry; import org.eclipse.core.resources.IProject; @@ -164,7 +165,7 @@ protected BuildTargetsSerializer createSerializer() { } protected String getBuildTargetsPref(IProject project) { - return StringUtil.emptyAsNull(BUILD_TARGETS_DATA.getStoredValue(project)); + return StringUtil.emptyAsNull(BUILD_TARGETS_DATA.getStoredValue(Optional.of(project))); } /* ----------------- ProjectBuildInfo ----------------- */ diff --git a/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/build/BuildTarget.java b/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/build/BuildTarget.java index 040ece079..5503daf35 100644 --- a/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/build/BuildTarget.java +++ b/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/build/BuildTarget.java @@ -219,7 +219,18 @@ public void validateForBuild(ToolManager toolManager) throws StatusException { public CommandInvocation getCommandInvocation(ToolManager toolManager) throws StatusException { String buildCommandString = getEffectiveBuildCommand(); VariablesResolver variablesResolver = toolManager.getVariablesManager(Optional.of(getProject())); - return new CommandInvocation(buildCommandString, variablesResolver); + return new BuildCommandInvocation(buildCommandString, variablesResolver); + } + + public static class BuildCommandInvocation extends CommandInvocation { + public BuildCommandInvocation(String commandArguments, VariablesResolver variablesResolver) { + super(commandArguments, variablesResolver); + } + + @Override + protected void handleEmptyCommandLine() throws CommonException { + throw new CommonException("Build command is empty."); + } } public BuildTargetOperation getBuildOperation(ToolManager toolManager, IOperationMonitor opMonitor) diff --git a/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/build/CommandInvocation.java b/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/build/CommandInvocation.java index 06762aaff..eaeba34ad 100644 --- a/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/build/CommandInvocation.java +++ b/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/build/CommandInvocation.java @@ -34,10 +34,18 @@ public CommandInvocation(String commandArguments, VariablesResolver variablesRes public Indexable getEffectiveCommandLine() throws CommonException { String evaluatedCommandLine = variablesResolver.performStringSubstitution(commandArguments); + if(evaluatedCommandLine.trim().isEmpty()) { + handleEmptyCommandLine(); + } + String[] evaluatedArguments = DebugPlugin.parseArguments(evaluatedCommandLine); return new ArrayList2<>(evaluatedArguments); } + protected void handleEmptyCommandLine() throws CommonException { + throw new CommonException("No command specified."); + } + @Override public IStatusMessage getValidationStatus() { try { diff --git a/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/build/VariablesResolver.java b/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/build/VariablesResolver.java index 3e608793a..dec716b70 100644 --- a/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/build/VariablesResolver.java +++ b/plugin_ide.core/src-lang/melnorme/lang/ide/core/operations/build/VariablesResolver.java @@ -24,6 +24,8 @@ import melnorme.lang.ide.core.LangCore; import melnorme.lang.ide.core.utils.ForwardingVariableManager; import melnorme.lang.ide.core.utils.StringSubstitutionEngine; +import melnorme.lang.tooling.data.IValidator; +import melnorme.lang.tooling.data.StatusException; import melnorme.utilbox.collections.ArrayList2; import melnorme.utilbox.collections.HashMap2; import melnorme.utilbox.core.CommonException; @@ -144,12 +146,20 @@ public static class SupplierAdapterVar implements IDynamicVariable { protected final String name; protected final String description; - protected final Supplier fieldView; + protected final Supplier value; + protected final IValidator validator; - public SupplierAdapterVar(String name, String description, Supplier fieldView) { + public SupplierAdapterVar(String name, String description, Supplier value) { + this(name, description, value, null); + } + + public SupplierAdapterVar(String name, String description, Supplier value, + IValidator validator) { this.name = assertNotNull(name); this.description = assertNotNull(description); - this.fieldView = assertNotNull(fieldView); + this.value = assertNotNull(value); + + this.validator = validator; } @Override @@ -173,7 +183,15 @@ public String getValue(String argument) throws CoreException { throw LangCore.createCoreException( MessageFormat.format("Variable {0} does not accept arguments.", getName()) , null); } - return fieldView.get(); + if(validator != null) { + try { + return validator.getValidatedField(value.get()); + } catch(StatusException e) { + String msg = MessageFormat.format("Variable {0} error: {1}", getName(), e.getMessage()); + throw LangCore.createCoreException(msg, e.getCause()); + } + } + return value.get(); } } diff --git a/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/DerivedValuePreference.java b/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/DerivedValuePreference.java index 602a22138..93212de4a 100644 --- a/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/DerivedValuePreference.java +++ b/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/DerivedValuePreference.java @@ -12,6 +12,8 @@ import static melnorme.utilbox.core.Assert.AssertNamespace.assertNotNull; +import java.util.Optional; + import org.eclipse.core.resources.IProject; import melnorme.lang.tooling.data.IValidatableValue; @@ -51,7 +53,7 @@ public VALUE getDerivedValue() throws StatusException { } public VALUE getDerivedValue(IProject project) throws StatusException { - String stringValue = preference.getProjectPreference().getEffectiveValue(project); + String stringValue = preference.getProjectPreference().getEffectiveValue(Optional.of(project)); return validator.getValidatedField(stringValue); } diff --git a/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/IGlobalPreference.java b/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/IGlobalPreference.java index b3b7b075a..593aa6457 100644 --- a/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/IGlobalPreference.java +++ b/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/IGlobalPreference.java @@ -10,6 +10,7 @@ *******************************************************************************/ package melnorme.lang.ide.core.utils.prefs; +import java.util.Optional; import java.util.function.Supplier; import org.eclipse.core.resources.IProject; @@ -35,7 +36,7 @@ default T get() { IProjectPreference getProjectPreference(); default T getEffectiveValue(IProject project) { - return getProjectPreference().getEffectiveValue(project); + return getProjectPreference().getEffectiveValue(Optional.of(project)); } } \ No newline at end of file diff --git a/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/IProjectPreference.java b/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/IProjectPreference.java index 5f1a0223f..091abaa6e 100644 --- a/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/IProjectPreference.java +++ b/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/IProjectPreference.java @@ -10,6 +10,7 @@ *******************************************************************************/ package melnorme.lang.ide.core.utils.prefs; +import java.util.Optional; import java.util.function.Supplier; import org.eclipse.core.resources.IProject; @@ -27,14 +28,16 @@ default String getKey() { T getDefaultValue(); - T getStoredValue(IProject project); + T getStoredValue(Optional project); + + void doSetValue(IProject project, T value); void setValue(IProject project, T value) throws CommonException; - T getEffectiveValue(IProject project); + T getEffectiveValue(Optional project); IProjectPreference getEnableProjectSettingPref(); - Supplier getProperty(IProject project); + Supplier getProperty(Optional project); } \ No newline at end of file diff --git a/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/PreferenceHelper.java b/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/PreferenceHelper.java index f88080f3e..367e19e8e 100644 --- a/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/PreferenceHelper.java +++ b/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/PreferenceHelper.java @@ -14,6 +14,7 @@ import static melnorme.utilbox.core.Assert.AssertNamespace.assertTrue; import java.util.HashMap; +import java.util.Optional; import java.util.function.Supplier; import org.eclipse.core.resources.IProject; @@ -110,7 +111,7 @@ protected IPreferencesAccess prefScopes() { return new PreferencesLookupHelper(getQualifier()); } - protected IPreferencesAccess prefScopes(IProject project) { + protected IPreferencesAccess prefScopes(Optional project) { return new PreferencesLookupHelper(getQualifier(), project); } @@ -153,12 +154,12 @@ public final void setInstanceScopeValue(T value) throws CommonException { try { prefs.flush(); } catch(BackingStoreException e) { - throw toCommonException(e); + throwCommonException(e); } } - public static CommonException toCommonException(BackingStoreException e) throws CommonException { - return new CommonException(e.getMessage(), e.getCause()); + public static void throwCommonException(BackingStoreException e) throws CommonException { + throw new CommonException(e.getMessage(), e.getCause()); } protected void handlePreferenceChange(PreferenceChangeEvent event) { @@ -193,7 +194,7 @@ public T getDefaultValue() { } @Override - public Supplier getProperty(IProject project) { + public Supplier getProperty(Optional project) { return new Supplier() { @Override public T get() { @@ -203,21 +204,25 @@ public T get() { } @Override - public T getStoredValue(IProject project) { + public T getStoredValue(Optional project) { return getProjectScopeValue(project); } @Override public void setValue(IProject project, T value) throws CommonException { - try { - setProjectScopeValue(project, value); - } catch(BackingStoreException e) { - toCommonException(e); - } + doSetValue(project, value); + flush(project); + } + + @Override + public void doSetValue(IProject project, T value) { + assertNotNull(project); + IEclipsePreferences projectPreferences = getProjectNode(project); + setPrefValue(projectPreferences, value); } @Override - public T getEffectiveValue(IProject project) { + public T getEffectiveValue(Optional project) { assertNotNull(getEnableProjectSettingPref()); if(project != null && getEnableProjectSettingPref().getStoredValue(project) == true) { return getStoredValue(project); @@ -232,14 +237,16 @@ public IProjectPreference getEnableProjectSettingPref() { }; - protected final T getProjectScopeValue(IProject project) { + protected final T getProjectScopeValue(Optional project) { return getPrefValue(prefScopes(project)); } - protected final void setProjectScopeValue(IProject project, T value) throws BackingStoreException { - IEclipsePreferences projectPreferences = getProjectNode(project); - setPrefValue(projectPreferences, value); - projectPreferences.flush(); + protected void flush(IProject project) throws CommonException { + try { + getProjectNode(project).flush(); + } catch(BackingStoreException e) { + throwCommonException(e); + } } protected IEclipsePreferences getProjectNode(IProject project) { diff --git a/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/PreferencesLookupHelper.java b/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/PreferencesLookupHelper.java index 43b6b6ceb..533feb9d8 100644 --- a/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/PreferencesLookupHelper.java +++ b/plugin_ide.core/src-lang/melnorme/lang/ide/core/utils/prefs/PreferencesLookupHelper.java @@ -13,6 +13,8 @@ import static melnorme.utilbox.core.Assert.AssertNamespace.assertNotNull; import static melnorme.utilbox.core.CoreUtil.array; +import java.util.Optional; + import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.runtime.Platform; @@ -22,6 +24,7 @@ import org.eclipse.core.runtime.preferences.InstanceScope; import melnorme.lang.ide.core.utils.prefs.PreferenceHelper.IPreferencesAccess; +import melnorme.utilbox.misc.MiscUtil; public class PreferencesLookupHelper implements IPreferencesAccess { @@ -32,11 +35,12 @@ public PreferencesLookupHelper(String qualifier) { this(qualifier, null); } - public PreferencesLookupHelper(String qualifier, IProject project) { + public PreferencesLookupHelper(String qualifier, Optional project) { this.qualifier = qualifier; - if(project != null) { - contexts = array(new ProjectScope(project), InstanceScope.INSTANCE, DefaultScope.INSTANCE); + project = MiscUtil.toOptional(project); + if(project.isPresent()) { + contexts = array(new ProjectScope(project.get()), InstanceScope.INSTANCE, DefaultScope.INSTANCE); } else { contexts = array(InstanceScope.INSTANCE, DefaultScope.INSTANCE); } diff --git a/plugin_ide.core/src/melnorme/lang/ide/core/LangCore_Actual.java b/plugin_ide.core/src/melnorme/lang/ide/core/LangCore_Actual.java index ec07da788..2f604ec74 100644 --- a/plugin_ide.core/src/melnorme/lang/ide/core/LangCore_Actual.java +++ b/plugin_ide.core/src/melnorme/lang/ide/core/LangCore_Actual.java @@ -9,6 +9,8 @@ import melnorme.lang.ide.core.operations.build.BuildManager; import melnorme.lang.ide.core.project_model.BundleModelManager; import melnorme.lang.ide.core.project_model.LangBundleModel; +import melnorme.lang.tooling.data.LANGUAGE_SDKLocationValidator; +import melnorme.lang.tooling.ops.SDKLocationValidator; public class LangCore_Actual { @@ -30,6 +32,7 @@ public class LangCore_Actual { /* ----------------- Owned singletons: ----------------- */ + protected final CorePreferences corePrefs; protected final ToolManager toolManager; protected final LANGUAGE_BundleModelManager bundleManager; protected final BuildManager buildManager; @@ -38,12 +41,22 @@ public class LangCore_Actual { public LangCore_Actual() { instance = (LangCore) this; + corePrefs = createCorePreferences(); toolManager = createToolManagerSingleton(); bundleManager = createBundleModelManager(); buildManager = createBuildManager(bundleManager.getModel()); sourceModelManager = createSourceModelManager(); } + protected CorePreferences createCorePreferences() { + return new CorePreferences() { + @Override + protected SDKLocationValidator getSDKLocationValidator() { + return new LANGUAGE_SDKLocationValidator(); + } + }; + } + public static LANGUAGE_ToolManager createToolManagerSingleton() { return new LANGUAGE_ToolManager(); } @@ -62,6 +75,9 @@ public static LANGUAGE_SourceModelManager createSourceModelManager() { /* ----------------- ----------------- */ + public static CorePreferences preferences() { + return instance.corePrefs; + } public static ToolManager getToolManager() { return instance.toolManager; diff --git a/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/dialogs/LangProjectWizardFirstPage.java b/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/dialogs/LangProjectWizardFirstPage.java index e97468172..6bd018915 100644 --- a/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/dialogs/LangProjectWizardFirstPage.java +++ b/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/dialogs/LangProjectWizardFirstPage.java @@ -375,7 +375,9 @@ protected void setPreferencesErrorMessage(CommonException ve) { } - protected abstract void validatePreferences() throws CommonException; + protected void validatePreferences() throws StatusException { + LangCore.preferences().SDK_LOCATION.getValue(); + } protected boolean validateDialog() { IStatus validationStatus = getValidationStatus(); diff --git a/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/BuildTargetEditor.java b/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/BuildTargetEditor.java index a4c1edd31..702315ae3 100644 --- a/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/BuildTargetEditor.java +++ b/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/BuildTargetEditor.java @@ -14,11 +14,13 @@ import melnorme.lang.ide.core.operations.build.BuildManager; import melnorme.lang.ide.core.operations.build.BuildManagerMessages; +import melnorme.lang.ide.core.operations.build.BuildTarget.BuildCommandInvocation; import melnorme.lang.ide.core.operations.build.BuildTargetData; import melnorme.lang.ide.core.operations.build.BuildTargetDataView; import melnorme.lang.ide.core.operations.build.VariablesResolver; import melnorme.lang.ide.ui.LangUIMessages; import melnorme.lang.ide.ui.utils.ControlUtils; +import melnorme.lang.tooling.data.StatusException; import melnorme.util.swt.components.AbstractCompositeWidget; import melnorme.util.swt.components.fields.CheckBoxField; import melnorme.util.swt.components.fields.EnablementButtonTextField; @@ -76,7 +78,7 @@ protected BuildManager getBuildManager() { protected CommandInvocationEditor init_createArgumentsField() { VariablesResolver varResolver = buildManager.getToolManager().getVariablesManager(null); - return new CommandInvocationEditor(getDefaultBuildCommand, varResolver); + return new BuildCommandEditor(getDefaultBuildCommand, varResolver); } protected EnablementButtonTextField init_createProgramPathField() { @@ -107,6 +109,26 @@ public int getPreferredLayoutColumns() { return 1; } + public static class BuildCommandEditor extends CommandInvocationEditor { + + public BuildCommandEditor(CommonGetter getDefaultCommandArguments, + VariablesResolver variablesResolver) { + super(getDefaultCommandArguments, variablesResolver); + + commandArgumentsField.setLabelText(LangUIMessages.Fields_BuildCommand); + } + + @Override + protected void handleNoBuildCommandSupplied() throws StatusException { + throw new StatusException("No build command supplied."); + } + + @Override + protected void doValidate(String commandArguments) throws StatusException { + new BuildCommandInvocation(commandArguments, variablesResolver).validate(); + } + } + public class ProgramPathField extends EnablementButtonTextField { public ProgramPathField() { diff --git a/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/CommandInvocationEditor.java b/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/CommandInvocationEditor.java index cc7fae06e..6fcf29298 100644 --- a/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/CommandInvocationEditor.java +++ b/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/CommandInvocationEditor.java @@ -13,7 +13,6 @@ import org.eclipse.core.runtime.CoreException; import org.eclipse.debug.ui.StringVariableSelectionDialog; import org.eclipse.jface.layout.GridDataFactory; -import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; import melnorme.lang.ide.core.operations.build.CommandInvocation; @@ -42,8 +41,8 @@ public CommandInvocationEditor(CommonGetter getDefaultCommandArguments, this.variablesResolver = variablesResolver; commandArgumentsField = new CommandArgumentsField(); - commandArgumentsField.setLabelText(LangUIMessages.Fields_BuildCommand /* FIXME: */); - commandArgumentsField.setDefaultTextStyle(SWT.MULTI | SWT.BORDER); + commandArgumentsField.setLabelText("Command Invocation"); + commandArgumentsField.setMultiLineStyle(); addSubComponent(commandArgumentsField); @@ -66,9 +65,17 @@ protected void validateArguments() throws StatusException { } } if(commandArguments == null) { - throw new StatusException("No commands supplied."); + handleNoBuildCommandSupplied(); } - new CommandInvocation(commandArguments, variablesResolver).validate();; + doValidate(commandArguments); + } + + protected void handleNoBuildCommandSupplied() throws StatusException { + throw new StatusException("No command supplied."); + } + + protected void doValidate(String commandArguments) throws StatusException { + new CommandInvocation(commandArguments, variablesResolver).validate(); } public class CommandArgumentsField extends EnablementButtonTextField { diff --git a/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/LangSDKConfigBlock.java b/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/LangSDKConfigBlock.java index f5f965ac7..34ab9719b 100644 --- a/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/LangSDKConfigBlock.java +++ b/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/LangSDKConfigBlock.java @@ -13,7 +13,7 @@ import org.eclipse.jface.layout.GridLayoutFactory; import org.eclipse.swt.widgets.Composite; -import melnorme.lang.ide.core.operations.ToolchainPreferences; +import melnorme.lang.ide.core.LangCore; import melnorme.lang.ide.ui.preferences.common.PreferencesPageContext; import melnorme.lang.tooling.ops.util.PathValidator; import melnorme.util.swt.SWTFactoryUtil; @@ -55,8 +55,7 @@ public LanguageSDKLocationGroup() { } protected void initBindings() { - prefContext.bindToPreference(sdkLocationField, ToolchainPreferences.SDK_PATH2); - validation.addFieldValidation(true, sdkLocationField, getSDKValidator()); + prefContext.bindToPreference(sdkLocationField, LangCore.preferences().SDK_LOCATION); } protected ButtonTextField createSdkLocationField() { diff --git a/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/ProjectPreferencesBlock.java b/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/ProjectPreferencesBlock.java index 0733d9440..28a5a9d38 100644 --- a/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/ProjectPreferencesBlock.java +++ b/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/ProjectPreferencesBlock.java @@ -17,6 +17,8 @@ import static melnorme.utilbox.core.Assert.AssertNamespace.assertNotNull; import static melnorme.utilbox.core.Assert.AssertNamespace.assertTrue; +import java.util.Optional; + import org.eclipse.core.resources.IProject; import org.eclipse.jface.layout.GridDataFactory; import org.eclipse.swt.SWT; @@ -132,11 +134,11 @@ public PreferencePropertyBinding(IProperty property, IProjectPreference pr this.preference = preference; this.project = project; - property.set(preference.getStoredValue(project)); + property.set(preference.getStoredValue(Optional.of(project))); } public void updateFieldFromInput() { - property.set(preference.getStoredValue(project)); + property.set(preference.getStoredValue(Optional.of(project))); } @Override diff --git a/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/common/PreferencesPageContext.java b/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/common/PreferencesPageContext.java index eccbe2ddd..99fbed824 100644 --- a/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/common/PreferencesPageContext.java +++ b/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/preferences/common/PreferencesPageContext.java @@ -12,10 +12,12 @@ import static melnorme.utilbox.core.Assert.AssertNamespace.assertNotNull; +import melnorme.lang.ide.core.CorePreferences.PreferenceField; import melnorme.lang.ide.core.utils.prefs.DerivedValuePreference; import melnorme.lang.ide.core.utils.prefs.IGlobalPreference; import melnorme.lang.ide.core.utils.prefs.IProjectPreference; import melnorme.lang.tooling.data.CompositeValidatableField; +import melnorme.util.swt.components.FieldWidget; import melnorme.utilbox.collections.ArrayList2; import melnorme.utilbox.core.CommonException; import melnorme.utilbox.fields.IField; @@ -45,6 +47,10 @@ public void doSaveSettings() throws CommonException { public void addPrefElement(IPreferencesEditor prefElement) { prefAdapters.add(prefElement); } + public void bindToPreference(FieldWidget field, PreferenceField prefField) { + bindToPreference(field, prefField.getGlobalPreference()); + field.getValidation().addFieldValidation(true, field, prefField.getValidator()); + } public void bindToPreference(IProperty field, IProjectPreference pref) { bindToPreference(field, pref.getGlobalPreference()); } diff --git a/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/text/completion/LangContentAssistProcessor.java b/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/text/completion/LangContentAssistProcessor.java index 7b179b997..7319e9d2b 100644 --- a/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/text/completion/LangContentAssistProcessor.java +++ b/plugin_ide.ui/src-lang/melnorme/lang/ide/ui/text/completion/LangContentAssistProcessor.java @@ -15,6 +15,7 @@ import static melnorme.utilbox.core.Assert.AssertNamespace.assertTrue; import java.text.MessageFormat; +import java.util.Optional; import org.eclipse.core.resources.IProject; import org.eclipse.jface.bindings.TriggerSequence; @@ -220,7 +221,7 @@ protected ICompletionProposal[] doComputeCompletionProposals(ITextViewer viewer, try { proposals = cat.computeCompletionProposals(context); } catch(CommonException ce) { - if(ContentAssistPreferences.ShowDialogIfContentAssistErrors.getEffectiveValue(project)) { + if(ContentAssistPreferences.ShowDialogIfContentAssistErrors.getEffectiveValue(Optional.of(project))) { handleExceptionInUI(ce); } else { LangCore.logError(LangUIMessages.ContentAssistProcessor_opName, ce); diff --git a/plugin_ide.ui/src-lang/melnorme/util/swt/components/IValidatableWidget.java b/plugin_ide.ui/src-lang/melnorme/util/swt/components/IValidatableWidget.java index 5e356b9ee..3fd7894ce 100644 --- a/plugin_ide.ui/src-lang/melnorme/util/swt/components/IValidatableWidget.java +++ b/plugin_ide.ui/src-lang/melnorme/util/swt/components/IValidatableWidget.java @@ -16,6 +16,7 @@ public interface IValidatableWidget extends IWidgetComponent, IStatusFieldSource { + /* FIXME: WTF */ @Override default IFieldView getStatusField() { return IFieldView.NULL_FIELD_VIEW(); diff --git a/plugin_ide.ui/src-lang/melnorme/util/swt/components/fields/TextFieldWidget.java b/plugin_ide.ui/src-lang/melnorme/util/swt/components/fields/TextFieldWidget.java index c3e44bac9..dcf4b9306 100644 --- a/plugin_ide.ui/src-lang/melnorme/util/swt/components/fields/TextFieldWidget.java +++ b/plugin_ide.ui/src-lang/melnorme/util/swt/components/fields/TextFieldWidget.java @@ -43,6 +43,10 @@ public void setDefaultTextStyle(int defaultTextStyle) { this.defaultTextStyle = defaultTextStyle; } + public void setMultiLineStyle() { + this.defaultTextStyle |= SWT.MULTI; + } + @Override public int getPreferredLayoutColumns() { return 2; diff --git a/plugin_ide.ui/src/LANG_PROJECT_ID/ide/ui/wizards/LANGUAGE_ProjectWizard.java b/plugin_ide.ui/src/LANG_PROJECT_ID/ide/ui/wizards/LANGUAGE_ProjectWizard.java index 6091d927e..363341840 100644 --- a/plugin_ide.ui/src/LANG_PROJECT_ID/ide/ui/wizards/LANGUAGE_ProjectWizard.java +++ b/plugin_ide.ui/src/LANG_PROJECT_ID/ide/ui/wizards/LANGUAGE_ProjectWizard.java @@ -16,13 +16,9 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.jface.wizard.WizardPage; -import melnorme.lang.ide.core.operations.ToolchainPreferences; -import melnorme.lang.ide.core.utils.prefs.PreferenceHelper; import melnorme.lang.ide.ui.WizardMessages_Actual; import melnorme.lang.ide.ui.dialogs.LangNewProjectWizard; import melnorme.lang.ide.ui.dialogs.LangProjectWizardFirstPage; -import melnorme.lang.tooling.data.LANGUAGE_SDKLocationValidator; -import melnorme.lang.tooling.data.ValidationException; /** * LANG_NAME New Project Wizard. @@ -63,10 +59,4 @@ public LANGUAGE_ProjectWizardFirstPage() { setDescription(WizardMessages_Actual.LangNewProject_Page1_pageDescription); } - @Override - protected void validatePreferences() throws ValidationException { - PreferenceHelper globalPref = ToolchainPreferences.SDK_PATH2.getGlobalPreference(); - new LANGUAGE_SDKLocationValidator().getValidatedField(globalPref.get()); - } - } \ No newline at end of file diff --git a/plugin_tooling/src-lang/melnorme/lang/tooling/ops/util/LocationValidator.java b/plugin_tooling/src-lang/melnorme/lang/tooling/ops/util/LocationValidator.java index 4228236b8..09b423fc1 100644 --- a/plugin_tooling/src-lang/melnorme/lang/tooling/ops/util/LocationValidator.java +++ b/plugin_tooling/src-lang/melnorme/lang/tooling/ops/util/LocationValidator.java @@ -10,6 +10,8 @@ *******************************************************************************/ package melnorme.lang.tooling.ops.util; +import static melnorme.utilbox.core.Assert.AssertNamespace.assertNotNull; + import java.nio.file.Path; import melnorme.lang.tooling.data.IValidator; @@ -43,4 +45,23 @@ public IValidator asLocationValidator() { return asLocationValidator; } + public static class LocationValidator2 implements IValidator { + + protected final LocationValidator validator; + + public LocationValidator2(String fieldNamePrefix) { + this(new LocationValidator(fieldNamePrefix)); + } + + public LocationValidator2(LocationValidator pathValidator) { + this.validator = assertNotNull(pathValidator); + } + + @Override + public Location getValidatedField(String pathString) throws StatusException { + return validator.getValidatedLocation(pathString); + } + + } + } \ No newline at end of file diff --git a/plugin_tooling/src-tests/melnorme/lang/tests/LangCoreTests_Actual.java b/plugin_tooling/src-tests/melnorme/lang/tests/LangCoreTests_Actual.java new file mode 100644 index 000000000..4d043fb65 --- /dev/null +++ b/plugin_tooling/src-tests/melnorme/lang/tests/LangCoreTests_Actual.java @@ -0,0 +1,21 @@ +/******************************************************************************* + * Copyright (c) 2016 Bruno Medeiros and other Contributors. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Bruno Medeiros - initial API and implementation + *******************************************************************************/ +package melnorme.lang.tests; + +import melnorme.lang.tooling.LANG_SPECIFIC; +import melnorme.utilbox.misc.Location; + +@LANG_SPECIFIC +public class LangCoreTests_Actual { + + public static Location SAMPLE_SDK_PATH = LangToolingTestResources.getTestResourceLoc("default_SDK"); + +} \ No newline at end of file diff --git a/plugin_tooling/src-util/melnorme/utilbox/misc/MiscUtil.java b/plugin_tooling/src-util/melnorme/utilbox/misc/MiscUtil.java index 4b1b9721c..e6be0218e 100644 --- a/plugin_tooling/src-util/melnorme/utilbox/misc/MiscUtil.java +++ b/plugin_tooling/src-util/melnorme/utilbox/misc/MiscUtil.java @@ -22,7 +22,6 @@ import java.util.Collection; import java.util.Optional; import java.util.function.Predicate; -import melnorme.utilbox.ownership.IDisposable; public class MiscUtil extends PathUtil { @@ -165,12 +164,4 @@ public static String getClassResource(Class klass, String resourceName, Chars } } - /** Dispose given disposable, and return null. Mean to be used for variables. */ - public static T dispose(T disposable) { - if (disposable != null) { - disposable.dispose(); - } - return null; - } - } \ No newline at end of file diff --git a/plugin_tooling/src-util/melnorme/utilbox/ownership/IDisposable.java b/plugin_tooling/src-util/melnorme/utilbox/ownership/IDisposable.java index c6ce574fb..ef311a173 100644 --- a/plugin_tooling/src-util/melnorme/utilbox/ownership/IDisposable.java +++ b/plugin_tooling/src-util/melnorme/utilbox/ownership/IDisposable.java @@ -20,4 +20,18 @@ public interface IDisposable { void dispose(); + /* ----------------- ----------------- */ + + /** + * Dispose given disposable, and return null. + * The null return is just syntax sugar to nullify a disposed variable in one line, like this: + * myObject = IDisposable.dispose(myObject) . + */ + static T dispose(T disposable) { + if (disposable != null) { + disposable.dispose(); + } + return null; + } + } \ No newline at end of file diff --git a/plugin_tooling/src-util/melnorme/utilbox/tests/CommonTestExt.java b/plugin_tooling/src-util/melnorme/utilbox/tests/CommonTestExt.java index 5dc26e23b..2f625eb00 100644 --- a/plugin_tooling/src-util/melnorme/utilbox/tests/CommonTestExt.java +++ b/plugin_tooling/src-util/melnorme/utilbox/tests/CommonTestExt.java @@ -12,8 +12,6 @@ import static melnorme.utilbox.core.Assert.AssertNamespace.assertTrue; -import java.util.Collection; -import java.util.Iterator; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -36,29 +34,6 @@ public CommonTestExt() { /* -------- iteration/checkers -------- */ - public static interface Visitor { - void visit(T obj); - } - - @SafeVarargs - public static > void visitContainer(Collection coll, PRED... predicates) { - Iterator iterator = coll.iterator(); - assertTrue(coll.size() == predicates.length); - for (int i = 0; iterator.hasNext(); i++) { - T next = iterator.next(); - predicates[i].visit(next); - } - } - - @SafeVarargs - public static > void visitContainer(T[] coll, PRED... predicates) { - assertTrue(coll.length == predicates.length); - for (int i = 0; i < coll.length; i++) { - T next = coll[i]; - predicates[i].visit(next); - } - } - public static final Location IGNORE_PATH = PathUtil.DEFAULT_ROOT_LOC.resolve_fromValid("###NO_CHECK###"); public static final String IGNORE_STR = "###NO_CHECK###"; public static final Object[] IGNORE_ARR = new Object[0]; diff --git a/plugin_tooling/src/melnorme/lang/tooling/data/LANGUAGE_SDKLocationValidator.java b/plugin_tooling/src/melnorme/lang/tooling/data/LANGUAGE_SDKLocationValidator.java index e6bd51f23..2790fb9f6 100644 --- a/plugin_tooling/src/melnorme/lang/tooling/data/LANGUAGE_SDKLocationValidator.java +++ b/plugin_tooling/src/melnorme/lang/tooling/data/LANGUAGE_SDKLocationValidator.java @@ -21,11 +21,11 @@ public LANGUAGE_SDKLocationValidator() { @Override protected String getSDKExecutable_append() { - return "bin/ls"; // TODO: LANG + return "bin/foobar"; // TODO: LANG } @Override protected String getSDKExecutableErrorMessage(Location exeLocation) { - return "Foo executable not found."; // TODO: LANG + return "foobar executable not found."; // TODO: LANG } } \ No newline at end of file diff --git a/plugin_tooling/testdata/default_sdk/bin/foobar b/plugin_tooling/testdata/default_sdk/bin/foobar new file mode 100644 index 000000000..e69de29bb diff --git a/plugin_tooling/testdata/default_sdk/bin/foobar.exe b/plugin_tooling/testdata/default_sdk/bin/foobar.exe new file mode 100644 index 000000000..e69de29bb