diff --git a/codan/org.eclipse.cdt.codan.checkers.ui.test/.classpath b/codan/org.eclipse.cdt.codan.checkers.ui.test/.classpath
new file mode 100644
index 00000000000..eca7bdba8f0
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.checkers.ui.test/.classpath
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/codan/org.eclipse.cdt.codan.checkers.ui.test/.project b/codan/org.eclipse.cdt.codan.checkers.ui.test/.project
new file mode 100644
index 00000000000..031b00c6527
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.checkers.ui.test/.project
@@ -0,0 +1,28 @@
+
+
+ org.eclipse.cdt.codan.checkers.ui.test
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.pde.ManifestBuilder
+
+
+
+
+ org.eclipse.pde.SchemaBuilder
+
+
+
+
+
+ org.eclipse.pde.PluginNature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/codan/org.eclipse.cdt.codan.checkers.ui.test/.settings/org.eclipse.jdt.core.prefs b/codan/org.eclipse.cdt.codan.checkers.ui.test/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 00000000000..0c68a61dca8
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.checkers.ui.test/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/codan/org.eclipse.cdt.codan.checkers.ui.test/META-INF/MANIFEST.MF b/codan/org.eclipse.cdt.codan.checkers.ui.test/META-INF/MANIFEST.MF
new file mode 100644
index 00000000000..6c8e44c7604
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.checkers.ui.test/META-INF/MANIFEST.MF
@@ -0,0 +1,23 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: %Bundle-Name
+Bundle-SymbolicName: org.eclipse.cdt.codan.checkers.ui.test
+Bundle-Version: 3.2.0.qualifier
+Bundle-Activator: org.eclipse.cdt.codan.checkers.ui.Activator
+Require-Bundle: org.eclipse.core.runtime,
+ org.eclipse.cdt.codan.checkers.ui,
+ org.eclipse.core.resources,
+ org.eclipse.cdt.codan.ui,
+ org.eclipse.cdt.codan.ui.cxx,
+ org.eclipse.ui,
+ org.eclipse.ui.ide,
+ org.junit,
+ org.mockito,
+ org.hamcrest,
+ org.eclipse.cdt.core,
+ org.eclipse.jface.text,
+ org.eclipse.ui.workbench.texteditor,
+ org.eclipse.ui.editors
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Bundle-ActivationPolicy: lazy
+Bundle-Vendor: %Bundle-Vendor
diff --git a/codan/org.eclipse.cdt.codan.checkers.ui.test/OSGI-INF/l10n/bundle.properties b/codan/org.eclipse.cdt.codan.checkers.ui.test/OSGI-INF/l10n/bundle.properties
new file mode 100644
index 00000000000..c796fcf3c02
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.checkers.ui.test/OSGI-INF/l10n/bundle.properties
@@ -0,0 +1,13 @@
+###############################################################################
+# Copyright (c) 2016 COSEDA Technologies GmbH and others.
+# 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:
+# Dominic Scharfe (COSEDA Technologies GmbH) - initial API and implementation
+###############################################################################
+#Properties file for org.eclipse.cdt.codan.checkers.ui
+Bundle-Vendor = Eclipse CDT
+Bundle-Name = Codan Checkers UI Tests
diff --git a/codan/org.eclipse.cdt.codan.checkers.ui.test/build.properties b/codan/org.eclipse.cdt.codan.checkers.ui.test/build.properties
new file mode 100644
index 00000000000..34d2e4d2dad
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.checkers.ui.test/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/codan/org.eclipse.cdt.codan.checkers.ui.test/pom.xml b/codan/org.eclipse.cdt.codan.checkers.ui.test/pom.xml
new file mode 100644
index 00000000000..8920e5cad8b
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.checkers.ui.test/pom.xml
@@ -0,0 +1,39 @@
+
+
+ 4.0.0
+
+
+ org.eclipse.cdt
+ cdt-parent
+ 9.1.0-SNAPSHOT
+ ../../pom.xml
+
+
+ 3.2.0-SNAPSHOT
+ org.eclipse.cdt.codan.checkers.ui.test
+ eclipse-test-plugin
+
+
+
+
+ org.eclipse.tycho
+ tycho-surefire-plugin
+ ${tycho-version}
+
+
+ true
+ ${tycho.testArgLine} ${base.ui.test.vmargs}
+ true
+
+
+ org.eclipse.platform.feature.group
+ p2-installable-unit
+
+
+
+
+
+
+
diff --git a/codan/org.eclipse.cdt.codan.checkers.ui.test/src/org/eclipse/cdt/codan/checkers/ui/Activator.java b/codan/org.eclipse.cdt.codan.checkers.ui.test/src/org/eclipse/cdt/codan/checkers/ui/Activator.java
new file mode 100644
index 00000000000..928d0408ae9
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.checkers.ui.test/src/org/eclipse/cdt/codan/checkers/ui/Activator.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2016 COSEDA Technologies GmbH
+ * 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:
+ * Dominic Scharfe (COSEDA Technologies GmbH) - initial implementation
+ *
+ *******************************************************************************/
+package org.eclipse.cdt.codan.checkers.ui;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+
+ private static BundleContext context;
+
+ static BundleContext getContext() {
+ return context;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext bundleContext) throws Exception {
+ Activator.context = bundleContext;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext bundleContext) throws Exception {
+ Activator.context = null;
+ }
+
+}
diff --git a/codan/org.eclipse.cdt.codan.checkers.ui.test/src/org/eclipse/cdt/codan/checkers/ui/quickfix/QuickFixCreateNewClassTest.java b/codan/org.eclipse.cdt.codan.checkers.ui.test/src/org/eclipse/cdt/codan/checkers/ui/quickfix/QuickFixCreateNewClassTest.java
new file mode 100644
index 00000000000..687f1fd7884
--- /dev/null
+++ b/codan/org.eclipse.cdt.codan.checkers.ui.test/src/org/eclipse/cdt/codan/checkers/ui/quickfix/QuickFixCreateNewClassTest.java
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2016 COSEDA Technologies GmbH
+ * 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:
+ * Dominic Scharfe (COSEDA Technologies GmbH) - initial implementation
+ *
+ *******************************************************************************/
+package org.eclipse.cdt.codan.checkers.ui.quickfix;
+
+import static org.junit.Assert.*;
+
+import org.eclipse.cdt.codan.internal.checkers.ui.quickfix.QuickFixCreateNewClass;
+import org.eclipse.cdt.codan.ui.AbstractCodanCMarkerResolution;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import static org.mockito.Mockito.*;
+
+import java.util.function.Function;
+
+import org.eclipse.cdt.core.dom.ILinkage;
+import org.eclipse.cdt.core.model.ILanguage;
+import org.eclipse.cdt.core.model.ITranslationUnit;
+
+@RunWith(MockitoJUnitRunner.class)
+public class QuickFixCreateNewClassTest {
+
+ QuickFixCreateNewClass qut;
+
+ @Mock
+ IMarker marker;
+
+ /**
+ * TranslationUnit of the marker's resource which is received from the
+ * workspace.
+ */
+ @Mock
+ ITranslationUnit translationUnitViaWorkspace;
+
+ /**
+ * TranslationUnit of the marker's resource if there is an open editor.
+ */
+ @Mock
+ ITranslationUnit translationUnitWorkingCopy;
+
+ /**
+ * Function to get the working copy of translationUnitViaWorkspace
+ */
+ @Mock
+ Function toWorkingCopy;
+
+ /**
+ * Language of the TranslationUnit
+ */
+ @Mock
+ ILanguage translationUnitLanguage;
+
+ @Before
+ public void setUp() throws Exception {
+ qut = new QuickFixCreateNewClass(toWorkingCopy) {
+ @Override
+ protected ITranslationUnit getTranslationUnitViaWorkspace(IMarker marker) {
+ if (QuickFixCreateNewClassTest.this.marker == marker) {
+ return translationUnitViaWorkspace;
+ }
+ throw new RuntimeException("Invalid marker");
+ };
+ };
+
+ when(toWorkingCopy.apply(translationUnitViaWorkspace)).thenReturn(translationUnitWorkingCopy);
+ when(translationUnitWorkingCopy.getLanguage()).thenReturn(translationUnitLanguage);
+ }
+
+ /**
+ * Test if the marker is applicable if
+ * {@link AbstractCodanCMarkerResolution#getTranslationUnitViaWorkspace}
+ * returns null.
+ */
+ @Test
+ public void isApplicableForUnresolvableMarker() {
+ translationUnitViaWorkspace = null;
+ assertTrue("Unresolvable marker is not applicable", qut.isApplicable(marker));
+ }
+
+ /**
+ * Test if the marker is applicable if
+ * {@link AbstractCodanCMarkerResolution#getTranslationUnitViaWorkspace}
+ * returns a marker valid marker.
+ */
+ @Test
+ public void isApplicableForResolvableMarker() {
+ assertTrue("Resolvable marker is not applicable", qut.isApplicable(marker));
+ }
+
+ /**
+ * Test if the marker is applicable if
+ * tu.getLanguage().getLinkageID() == ILinkage.C_LINKAGE_ID
+ */
+ @Test
+ public void isNotApplicableForResolvableMarkerWithCLinkage() {
+ when(translationUnitLanguage.getLinkageID()).thenReturn(ILinkage.C_LINKAGE_ID);
+ assertFalse("Resolvable marker with ILinkage.C_LINKAGE_ID must not be applicable", qut.isApplicable(marker));
+ }
+
+ /**
+ * Test if the marker is applicable if tu.getLanguage()
throws
+ * a {@link CoreException}.
+ *
+ * @throws CoreException
+ */
+ @Test
+ public void isApplicableForResolvableMarkerWithCLinkageResolutionCoreException() throws CoreException {
+ CoreException coreException = new CoreException(mock(IStatus.class));
+ doThrow(coreException).when(translationUnitWorkingCopy).getLanguage();
+ assertTrue("Resolvable marker with invalid language must be applicable", qut.isApplicable(marker));
+ }
+}
diff --git a/codan/org.eclipse.cdt.codan.checkers.ui/META-INF/MANIFEST.MF b/codan/org.eclipse.cdt.codan.checkers.ui/META-INF/MANIFEST.MF
index 62aa6c037e1..ae0d4e02558 100644
--- a/codan/org.eclipse.cdt.codan.checkers.ui/META-INF/MANIFEST.MF
+++ b/codan/org.eclipse.cdt.codan.checkers.ui/META-INF/MANIFEST.MF
@@ -20,5 +20,5 @@ Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-Vendor: %Bundle-Vendor
Export-Package: org.eclipse.cdt.codan.internal.checkers.ui;x-internal:=true,
- org.eclipse.cdt.codan.internal.checkers.ui.quickfix;x-internal:=true
+ org.eclipse.cdt.codan.internal.checkers.ui.quickfix;x-friends:="org.eclipse.cdt.codan.checkers.ui.test"
diff --git a/codan/org.eclipse.cdt.codan.checkers.ui/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/QuickFixCreateNewClass.java b/codan/org.eclipse.cdt.codan.checkers.ui/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/QuickFixCreateNewClass.java
index 0907027dc77..605484d03d8 100644
--- a/codan/org.eclipse.cdt.codan.checkers.ui/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/QuickFixCreateNewClass.java
+++ b/codan/org.eclipse.cdt.codan.checkers.ui/src/org/eclipse/cdt/codan/internal/checkers/ui/quickfix/QuickFixCreateNewClass.java
@@ -8,15 +8,20 @@
* Contributors:
* Alena Laskavaia - initial API and implementation,
* inspired by work of Erik Johansson
+ * Dominic Scharfe (COSEDA Technologies GmbH) - Fix for bug 507148
*
*******************************************************************************/
package org.eclipse.cdt.codan.internal.checkers.ui.quickfix;
+import java.util.Optional;
+import java.util.function.Function;
+
import org.eclipse.cdt.codan.internal.checkers.ui.CheckersUiActivator;
import org.eclipse.cdt.codan.ui.AbstractCodanCMarkerResolution;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.model.ICElement;
import org.eclipse.cdt.core.model.ITranslationUnit;
+import org.eclipse.cdt.internal.corext.util.CModelUtil;
import org.eclipse.cdt.internal.ui.wizards.NewClassCreationWizard;
import org.eclipse.cdt.ui.CDTSharedImages;
import org.eclipse.core.resources.IMarker;
@@ -31,6 +36,27 @@ import org.eclipse.ui.IMarkerResolution2;
import org.eclipse.ui.PlatformUI;
public class QuickFixCreateNewClass extends AbstractCodanCMarkerResolution implements IMarkerResolution2 {
+ /**
+ * Returns the working copy TU of the given TU. If the TU is already a
+ * working copy or the TU has no working copy the input TU is returned.
+ */
+ private final Function toWorkingCopy;
+
+ /**
+ * Default constructor.
+ * Uses {@link CModelUtil#toWorkingCopy(ITranslationUnit)} to get the
+ * working copy of a {@link ITranslationUnit}.
+ *
+ * TODO: Inject {@link #toWorkingCopy} as a dependency.
+ */
+ public QuickFixCreateNewClass() {
+ this(tu -> CModelUtil.toWorkingCopy(tu));
+ }
+
+ public QuickFixCreateNewClass(Function toWorkingCopy) {
+ this.toWorkingCopy = toWorkingCopy;
+ }
+
@Override
public String getLabel() {
// TODO Should provide class name as message parameter
@@ -39,14 +65,26 @@ public class QuickFixCreateNewClass extends AbstractCodanCMarkerResolution imple
@Override
public boolean isApplicable(IMarker marker) {
- ITranslationUnit tu = getTranslationUnitViaEditor(marker);
- try {
- if (tu.getLanguage().getLinkageID() == ILinkage.C_LINKAGE_ID)
- return false;
- } catch (CoreException e) {
- // ignore
- }
- return true;
+ return getTranslationUnitViaEditorOrWorkspace(marker).map(tu -> {
+ try {
+ return tu.getLanguage().getLinkageID() != ILinkage.C_LINKAGE_ID;
+ } catch (CoreException e) {
+ return true;
+ }
+ }).orElse(true);
+ }
+
+ /**
+ * Receives a translation unit from a given marker. The TU is received from
+ * an editor (if opened),
+ * or by calling {@link #getTranslationUnitViaWorkspace(IMarker)}.
+ *
+ * @param marker
+ * A marker in a translation unit
+ * @return The translation unit
+ */
+ protected Optional getTranslationUnitViaEditorOrWorkspace(IMarker marker) {
+ return Optional.ofNullable(getTranslationUnitViaWorkspace(marker)).map(toWorkingCopy);
}
@Override
diff --git a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF
index 75d1c1c7d8c..3fe3c4d2342 100644
--- a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF
+++ b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF
@@ -11,7 +11,7 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true,
org.eclipse.cdt.internal.corext.fix;x-internal:=true,
org.eclipse.cdt.internal.corext.refactoring.code.flow;x-internal:=true,
org.eclipse.cdt.internal.corext.template.c;x-internal:=true,
- org.eclipse.cdt.internal.corext.util;x-friends:="org.eclipse.cdt.codan.ui",
+ org.eclipse.cdt.internal.corext.util;x-friends:="org.eclipse.cdt.codan.ui,org.eclipse.cdt.codan.checkers.ui",
org.eclipse.cdt.internal.ui;x-friends:="org.eclipse.cdt.debug.edc.tests",
org.eclipse.cdt.internal.ui.actions;x-internal:=true,
org.eclipse.cdt.internal.ui.browser.opentype;x-internal:=true,
diff --git a/pom.xml b/pom.xml
index cc0f5b59104..29afaeedf72 100644
--- a/pom.xml
+++ b/pom.xml
@@ -175,6 +175,7 @@
core/org.eclipse.cdt.core.tests
core/org.eclipse.cdt.ui.tests
codan/org.eclipse.cdt.codan.core.test
+ codan/org.eclipse.cdt.codan.checkers.ui.test
build/org.eclipse.cdt.managedbuilder.core.tests
build/org.eclipse.cdt.managedbuilder.ui.tests
build/org.eclipse.cdt.make.core.tests