mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-30 20:35:38 +02:00
Bug 411579 - Add a "Create new class" Quick fix.
Change-Id: I57dc46f079357de7d5c281d016a25baa3f2154a6
This commit is contained in:
parent
bc953d2348
commit
d3e933501e
11 changed files with 215 additions and 70 deletions
|
@ -11,6 +11,7 @@ Require-Bundle: org.eclipse.core.resources,
|
|||
org.eclipse.cdt.codan.core,
|
||||
org.eclipse.cdt.codan.core.cxx,
|
||||
org.eclipse.cdt.codan.ui.cxx,
|
||||
org.eclipse.cdt.ui,
|
||||
org.eclipse.jface.text,
|
||||
org.eclipse.ltk.core.refactoring,
|
||||
org.eclipse.ui,
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
class="org.eclipse.cdt.codan.internal.checkers.ui.quickfix.QuickFixCreateLocalVariable"
|
||||
problemId="org.eclipse.cdt.codan.internal.checkers.VariableResolutionProblem">
|
||||
</resolution>
|
||||
<resolution
|
||||
class="org.eclipse.cdt.codan.internal.checkers.ui.quickfix.QuickFixCreateNewClass"
|
||||
problemId="org.eclipse.cdt.codan.internal.checkers.TypeResolutionProblem"
|
||||
/>
|
||||
<resolution
|
||||
class="org.eclipse.cdt.codan.internal.checkers.ui.quickfix.QuickFixCreateLocalVariable"
|
||||
messagePattern="`(.*)' undeclared \(first use in this function\)">
|
||||
|
|
|
@ -0,0 +1,89 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2016 Alena Laskavaia
|
||||
* 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:
|
||||
* Alena Laskavaia - initial API and implementation,
|
||||
* inspired by work of Erik Johansson <erik.johansson.979@gmail.com>
|
||||
*
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.codan.internal.checkers.ui.quickfix;
|
||||
|
||||
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.ui.wizards.NewClassCreationWizard;
|
||||
import org.eclipse.cdt.ui.CDTSharedImages;
|
||||
import org.eclipse.core.resources.IMarker;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
import org.eclipse.jface.viewers.IStructuredSelection;
|
||||
import org.eclipse.jface.viewers.StructuredSelection;
|
||||
import org.eclipse.jface.window.Window;
|
||||
import org.eclipse.jface.wizard.WizardDialog;
|
||||
import org.eclipse.swt.graphics.Image;
|
||||
import org.eclipse.ui.IMarkerResolution2;
|
||||
import org.eclipse.ui.PlatformUI;
|
||||
|
||||
public class QuickFixCreateNewClass extends AbstractCodanCMarkerResolution implements IMarkerResolution2 {
|
||||
@Override
|
||||
public String getLabel() {
|
||||
// TODO Should provide class name as message parameter
|
||||
return QuickFixMessages.QuickFixCreateClass_CreateNewClass;
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDescription() {
|
||||
return QuickFixMessages.QuickFixCreateClass_CreateNewClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Image getImage() {
|
||||
return CDTSharedImages.getImage("icons/etool16/newclass_wiz.gif"); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(IMarker marker, IDocument document) {
|
||||
String name = null;
|
||||
try {
|
||||
name = getProblemArgument(marker, 0);
|
||||
} catch (Exception e) {
|
||||
CheckersUiActivator.log(e);
|
||||
// fallthrough
|
||||
// will still open new wizard dialog but without class name filled
|
||||
}
|
||||
ICElement element = getCElementFromMarker(marker);
|
||||
IStructuredSelection selection = element == null ? new StructuredSelection() : new StructuredSelection(element);
|
||||
if (openWizard(name, selection) == Window.OK) {
|
||||
try {
|
||||
marker.delete();
|
||||
} catch (CoreException e) {
|
||||
CheckersUiActivator.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int openWizard(final String className, IStructuredSelection selection) {
|
||||
NewClassCreationWizard wizard = new NewClassCreationWizard();
|
||||
wizard.setClassName(className);
|
||||
wizard.init(PlatformUI.getWorkbench(), selection);
|
||||
return new WizardDialog(null, wizard).open();
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2011 Alena Laskavaia and others.
|
||||
* Copyright (c) 2011,2016 Alena Laskavaia 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
|
||||
|
@ -15,6 +15,7 @@ import org.eclipse.osgi.util.NLS;
|
|||
public class QuickFixMessages extends NLS {
|
||||
public static String CaseBreakQuickFixBreak_Label;
|
||||
public static String CaseBreakQuickFixComment_Label;
|
||||
public static String QuickFixCreateClass_CreateNewClass;
|
||||
public static String QuickFixCreateField_create_field;
|
||||
public static String QuickFixCreateLocalVariable_create_local_variable;
|
||||
public static String QuickFixCreateParameter_create_parameter;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
###############################################################################
|
||||
# Copyright (c) 2011 Alena Laskavaia and others.
|
||||
# Copyright (c) 2011,2015 Alena Laskavaia 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
|
||||
|
@ -10,6 +10,7 @@
|
|||
###############################################################################
|
||||
CaseBreakQuickFixBreak_Label=Add break statement
|
||||
CaseBreakQuickFixComment_Label=Add suppressing comment
|
||||
QuickFixCreateClass_CreateNewClass=Create new class
|
||||
QuickFixCreateField_create_field=Create field
|
||||
QuickFixCreateLocalVariable_create_local_variable=Create local variable
|
||||
QuickFixCreateParameter_create_parameter=Create parameter
|
|
@ -2,7 +2,7 @@ Manifest-Version: 1.0
|
|||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: %Bundle-Name
|
||||
Bundle-SymbolicName: org.eclipse.cdt.codan.ui.cxx;singleton:=true
|
||||
Bundle-Version: 3.2.0.qualifier
|
||||
Bundle-Version: 3.3.0.qualifier
|
||||
Bundle-Activator: org.eclipse.cdt.codan.internal.ui.cxx.Activator
|
||||
Bundle-Vendor: %Bundle-Vendor
|
||||
Require-Bundle: org.eclipse.ui,
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<version>3.2.0-SNAPSHOT</version>
|
||||
<version>3.3.0-SNAPSHOT</version>
|
||||
<artifactId>org.eclipse.cdt.codan.ui.cxx</artifactId>
|
||||
<packaging>eclipse-plugin</packaging>
|
||||
</project>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009, 2011 Alena Laskavaia
|
||||
* Copyright (c) 2009, 2011 Alena Laskavaia
|
||||
* 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
|
||||
|
@ -20,7 +20,9 @@ import org.eclipse.cdt.core.CCorePlugin;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.index.IIndex;
|
||||
import org.eclipse.cdt.core.model.CModelException;
|
||||
import org.eclipse.cdt.core.model.CoreModel;
|
||||
import org.eclipse.cdt.core.model.ICElement;
|
||||
import org.eclipse.cdt.core.model.ICProject;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.ui.CDTUITools;
|
||||
|
@ -42,7 +44,7 @@ import org.eclipse.ui.texteditor.ITextEditor;
|
|||
* class for codanMarkerResolution extension. To add specific icon and
|
||||
* description client class should additionally implement
|
||||
* {@link IMarkerResolution2}
|
||||
*
|
||||
*
|
||||
* @since 2.0
|
||||
*/
|
||||
public abstract class AbstractCodanCMarkerResolution implements ICodanMarkerResolution {
|
||||
|
@ -51,7 +53,7 @@ public abstract class AbstractCodanCMarkerResolution implements ICodanMarkerReso
|
|||
/**
|
||||
* Get position offset from marker. If CHAR_START attribute is not set for
|
||||
* marker, line and document would be used.
|
||||
*
|
||||
*
|
||||
* @param marker
|
||||
* @param doc
|
||||
* @return
|
||||
|
@ -82,10 +84,11 @@ public abstract class AbstractCodanCMarkerResolution implements ICodanMarkerReso
|
|||
|
||||
/**
|
||||
* Runs this resolution.
|
||||
*
|
||||
*
|
||||
* @param marker
|
||||
* the marker to resolve
|
||||
*/
|
||||
@Override
|
||||
public void run(IMarker marker) {
|
||||
IDocument doc = openDocument(marker);
|
||||
if (doc != null) {
|
||||
|
@ -96,7 +99,7 @@ public abstract class AbstractCodanCMarkerResolution implements ICodanMarkerReso
|
|||
|
||||
/**
|
||||
* Apply marker resolution for given marker in given open document.
|
||||
*
|
||||
*
|
||||
* @param marker
|
||||
* @param document
|
||||
*/
|
||||
|
@ -105,10 +108,11 @@ public abstract class AbstractCodanCMarkerResolution implements ICodanMarkerReso
|
|||
/**
|
||||
* Override is extra checks is required to determine appicablity of marker
|
||||
* resolution
|
||||
*
|
||||
*
|
||||
* @param marker
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean isApplicable(IMarker marker) {
|
||||
return true;
|
||||
}
|
||||
|
@ -118,7 +122,7 @@ public abstract class AbstractCodanCMarkerResolution implements ICodanMarkerReso
|
|||
* returns the corresponding IEditorPart. Please note that is code analysis
|
||||
* is setup to run on reconsile this action would trigger checkers run, and
|
||||
* original marker may be removed as a result.
|
||||
*
|
||||
*
|
||||
* @param marker
|
||||
* the problem marker
|
||||
* @return the opened document
|
||||
|
@ -137,7 +141,7 @@ public abstract class AbstractCodanCMarkerResolution implements ICodanMarkerReso
|
|||
/**
|
||||
* Opens the editor and returns the document corresponding to a given
|
||||
* marker.
|
||||
*
|
||||
*
|
||||
* @param marker
|
||||
* the marker to find the editor
|
||||
* @return the corresponding document
|
||||
|
@ -148,7 +152,7 @@ public abstract class AbstractCodanCMarkerResolution implements ICodanMarkerReso
|
|||
|
||||
/**
|
||||
* Returns the document corresponding to a given editor part.
|
||||
*
|
||||
*
|
||||
* @param editorPart
|
||||
* an editor part
|
||||
* @return the document of that part
|
||||
|
@ -164,7 +168,7 @@ public abstract class AbstractCodanCMarkerResolution implements ICodanMarkerReso
|
|||
|
||||
/**
|
||||
* Receives a translation unit from a given marker. Opens the editor.
|
||||
*
|
||||
*
|
||||
* @param marker
|
||||
* A marker in an editor to get the translation unit
|
||||
* @return The translation unit
|
||||
|
@ -176,7 +180,7 @@ public abstract class AbstractCodanCMarkerResolution implements ICodanMarkerReso
|
|||
|
||||
/**
|
||||
* Receives a translation unit from a given marker using the marker's path.
|
||||
*
|
||||
*
|
||||
* @param marker
|
||||
* A marker in a translation unit
|
||||
* @return The translation unit
|
||||
|
@ -190,7 +194,7 @@ public abstract class AbstractCodanCMarkerResolution implements ICodanMarkerReso
|
|||
|
||||
/**
|
||||
* Receives an ASTName enclosing a given IMarker
|
||||
*
|
||||
*
|
||||
* @param marker
|
||||
* The marker enclosing an ASTName
|
||||
* @param ast
|
||||
|
@ -214,10 +218,40 @@ public abstract class AbstractCodanCMarkerResolution implements ICodanMarkerReso
|
|||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the smallest element within translation unit that
|
||||
* includes the given source position (that is, a method, field, etc.), or
|
||||
* {@code null} if there is no element other than the translation
|
||||
* unit itself at the given position, or if the given position is not
|
||||
* within the source range of this translation unit.
|
||||
*
|
||||
* @param marker that contains a position inside the translation unit
|
||||
* @return the innermost C element enclosing a given source position or
|
||||
* {@code null}
|
||||
* if none found (excluding the translation unit).
|
||||
* @since 3.3
|
||||
*/
|
||||
protected ICElement getCElementFromMarker(IMarker marker) {
|
||||
ITranslationUnit tu = getTranslationUnitViaEditor(marker);
|
||||
ICElement element = null;
|
||||
try {
|
||||
int charStart = marker.getAttribute(IMarker.CHAR_START, -1);
|
||||
if (charStart > 0) {
|
||||
element = tu.getElementAtOffset(charStart);
|
||||
} else {
|
||||
int lineNumber = marker.getAttribute(IMarker.LINE_NUMBER, -1);
|
||||
element = tu.getElementAtLine(lineNumber);
|
||||
}
|
||||
} catch (CModelException e) {
|
||||
CodanUIActivator.log(e);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Receives an {@link IIndex} corresponding to the given {@link IMarker}'s
|
||||
* resource.
|
||||
*
|
||||
*
|
||||
* @param marker
|
||||
* the marker to use
|
||||
* @return the received index
|
||||
|
|
|
@ -65,7 +65,7 @@ Export-Package: org.eclipse.cdt.internal.corext;x-internal:=true,
|
|||
org.eclipse.cdt.internal.ui.typehierarchy;x-internal:=true,
|
||||
org.eclipse.cdt.internal.ui.util;x-friends:="org.eclipse.cdt.debug.ui,org.eclipse.cdt.debug.edc.tests,org.eclipse.cdt.managedbuilder.ui",
|
||||
org.eclipse.cdt.internal.ui.viewsupport;x-internal:=true,
|
||||
org.eclipse.cdt.internal.ui.wizards;x-internal:=true,
|
||||
org.eclipse.cdt.internal.ui.wizards;x-friends:="org.eclipse.cdt.codan.checkers.ui",
|
||||
org.eclipse.cdt.internal.ui.wizards.classwizard;x-internal:=true,
|
||||
org.eclipse.cdt.internal.ui.wizards.dialogfields;x-friends:="org.eclipse.cdt.codan.ui",
|
||||
org.eclipse.cdt.internal.ui.wizards.filewizard;x-internal:=true,
|
||||
|
|
|
@ -21,53 +21,68 @@ import org.eclipse.cdt.internal.ui.CPluginImages;
|
|||
import org.eclipse.cdt.internal.ui.wizards.classwizard.NewClassWizardMessages;
|
||||
|
||||
public class NewClassCreationWizard extends NewElementWizard {
|
||||
private NewClassCreationWizardPage fPage;
|
||||
|
||||
public NewClassCreationWizard() {
|
||||
super();
|
||||
setDefaultPageImageDescriptor(CPluginImages.DESC_WIZBAN_NEWCLASS);
|
||||
setDialogSettings(CUIPlugin.getDefault().getDialogSettings());
|
||||
setWindowTitle(NewClassWizardMessages.NewClassCreationWizard_title);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see Wizard#createPages
|
||||
*/
|
||||
@Override
|
||||
private NewClassCreationWizardPage fPage;
|
||||
private String className;
|
||||
|
||||
public NewClassCreationWizard() {
|
||||
super();
|
||||
setDefaultPageImageDescriptor(CPluginImages.DESC_WIZBAN_NEWCLASS);
|
||||
setDialogSettings(CUIPlugin.getDefault().getDialogSettings());
|
||||
setWindowTitle(NewClassWizardMessages.NewClassCreationWizard_title);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see Wizard#createPages
|
||||
*/
|
||||
@Override
|
||||
public void addPages() {
|
||||
super.addPages();
|
||||
fPage = new NewClassCreationWizardPage();
|
||||
addPage(fPage);
|
||||
fPage.init(getSelection());
|
||||
}
|
||||
|
||||
@Override
|
||||
super.addPages();
|
||||
fPage = new NewClassCreationWizardPage();
|
||||
addPage(fPage);
|
||||
fPage.init(getSelection());
|
||||
if (className != null)
|
||||
fPage.setClassName(className, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the class name for creation in the wizard.
|
||||
*
|
||||
* @param className
|
||||
* Name of the class or null, null will indicate default behavior
|
||||
* which is extract class name from editor context. Setting an
|
||||
* empty string will force the empty fields.
|
||||
*/
|
||||
public void setClassName(String className) {
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean canRunForked() {
|
||||
return !fPage.isNamespaceSelected();
|
||||
}
|
||||
|
||||
@Override
|
||||
return !fPage.isNamespaceSelected();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void finishPage(IProgressMonitor monitor) throws InterruptedException, CoreException {
|
||||
fPage.createClass(monitor); // use the full progress monitor
|
||||
}
|
||||
|
||||
@Override
|
||||
fPage.createClass(monitor); // use the full progress monitor
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performFinish() {
|
||||
boolean finished = super.performFinish();
|
||||
if (finished) {
|
||||
if (fPage.openClassInEditor()) {
|
||||
IFile source = fPage.getCreatedSourceFile();
|
||||
if (source != null) {
|
||||
selectAndReveal(source);
|
||||
openResource(source);
|
||||
}
|
||||
IFile header = fPage.getCreatedHeaderFile();
|
||||
if (header != null) {
|
||||
selectAndReveal(header);
|
||||
openResource(header);
|
||||
}
|
||||
}
|
||||
}
|
||||
return finished;
|
||||
}
|
||||
boolean finished = super.performFinish();
|
||||
if (finished) {
|
||||
if (fPage.openClassInEditor()) {
|
||||
IFile source = fPage.getCreatedSourceFile();
|
||||
if (source != null) {
|
||||
selectAndReveal(source);
|
||||
openResource(source);
|
||||
}
|
||||
IFile header = fPage.getCreatedHeaderFile();
|
||||
if (header != null) {
|
||||
selectAndReveal(header);
|
||||
openResource(header);
|
||||
}
|
||||
}
|
||||
}
|
||||
return finished;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -448,13 +448,12 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (namespace == null) {
|
||||
namespace = fDialogSettings.get(KEY_NAMESPACE);
|
||||
}
|
||||
if (namespace == null) {
|
||||
namespace = fDialogSettings.get(KEY_NAMESPACE);
|
||||
}
|
||||
|
||||
setNamespaceText(namespace, false);
|
||||
setNamespaceSelection(namespace != null || fDialogSettings.getBoolean(KEY_NAMESPACE_SELECTED),
|
||||
true);
|
||||
setNamespaceText(namespace, false);
|
||||
setNamespaceSelection(namespace != null || fDialogSettings.getBoolean(KEY_NAMESPACE_SELECTED), true);
|
||||
|
||||
IPath folderPath = null;
|
||||
if (celem != null) {
|
||||
|
@ -479,7 +478,8 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
|
|||
className = text;
|
||||
}
|
||||
}
|
||||
setClassName(className, false);
|
||||
// Forcing update will also populate default file names.
|
||||
setClassName(className, true);
|
||||
|
||||
IMethodStub[] stubs = getDefaultMethodStubs();
|
||||
for (int i = 0; i < stubs.length; ++i) {
|
||||
|
|
Loading…
Add table
Reference in a new issue