1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-25 18:05:33 +02:00

Bug 120883 - Compliant "rule of 5" class wizard

Added the optional generation of copy constructor, move
constructor, assignment operator and move assignment operator.

Change-Id: I1fc0a04fd52ea828ca24d0fe57148b06dd27ed95
Signed-off-by: Marco Stornelli <marco.stornelli@gmail.com>
This commit is contained in:
Marco Stornelli 2019-05-04 09:05:11 +02:00
parent f90cd7214d
commit bdb0da6b73
9 changed files with 401 additions and 2 deletions

View file

@ -104,4 +104,9 @@ public abstract class AbstractMethodStub implements IMethodStub {
@Override
public abstract String createMethodImplementation(ITranslationUnit tu, String className,
IBaseClassInfo[] baseClasses, String lineDelimiter) throws CoreException;
@Override
public boolean isEnabledByDefault() {
return true;
}
}

View file

@ -0,0 +1,95 @@
/*******************************************************************************
* Copyright (c) 2019 Marco Stornelli
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Marco Stornelli - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.wizards.classwizard;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.cdt.ui.CodeGeneration;
import org.eclipse.core.runtime.CoreException;
public final class AssignOpMethodStub extends AbstractMethodStub {
private static String NAME = NewClassWizardMessages.NewClassCodeGeneration_stub_assign_op_name;
public AssignOpMethodStub() {
this(ASTAccessVisibility.PUBLIC, false);
}
public AssignOpMethodStub(ASTAccessVisibility access, boolean isInline) {
super(NAME, access, false, isInline);
}
@Override
public String createMethodDeclaration(ITranslationUnit tu, String className, IBaseClassInfo[] baseClasses,
String lineDelimiter) throws CoreException {
StringBuilder buf = new StringBuilder();
buf.append(className);
buf.append("& operator=(const "); //$NON-NLS-1$
buf.append(className);
buf.append("& other)"); //$NON-NLS-1$
if (fIsInline) {
buf.append('{');
buf.append(lineDelimiter);
String body = CodeGeneration.getMethodBodyContent(tu, className, "operator=", null, lineDelimiter); //$NON-NLS-1$
if (body != null) {
buf.append(body);
buf.append(lineDelimiter);
}
buf.append('}');
} else {
buf.append(";"); //$NON-NLS-1$
}
return buf.toString();
}
@Override
public String createMethodImplementation(ITranslationUnit tu, String className, IBaseClassInfo[] baseClasses,
String lineDelimiter) throws CoreException {
if (fIsInline) {
return ""; //$NON-NLS-1$
}
StringBuilder buf = new StringBuilder();
buf.append(className);
buf.append("& "); //$NON-NLS-1$
buf.append(className);
buf.append("::"); //$NON-NLS-1$
buf.append("operator=(const "); //$NON-NLS-1$
buf.append(className);
buf.append("& other)"); //$NON-NLS-1$
buf.append(lineDelimiter);
buf.append('{');
buf.append(lineDelimiter);
String body = CodeGeneration.getMethodBodyContent(tu, className, "operator=", null, lineDelimiter); //$NON-NLS-1$
if (body != null) {
buf.append(body);
buf.append(lineDelimiter);
}
buf.append('}');
return buf.toString();
}
@Override
public boolean isConstructor() {
return false;
}
@Override
public boolean isEnabledByDefault() {
return false;
}
@Override
public boolean canModifyVirtual() {
return false;
}
}

View file

@ -0,0 +1,94 @@
/*******************************************************************************
* Copyright (c) 2019 Marco Stornelli
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Marco Stornelli - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.wizards.classwizard;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.cdt.ui.CodeGeneration;
import org.eclipse.core.runtime.CoreException;
public final class CopyConstructorMethodStub extends AbstractMethodStub {
private static String NAME = NewClassWizardMessages.NewClassCodeGeneration_stub_copy_constructor_name;
public CopyConstructorMethodStub() {
this(ASTAccessVisibility.PUBLIC, false);
}
public CopyConstructorMethodStub(ASTAccessVisibility access, boolean isInline) {
super(NAME, access, false, isInline);
}
@Override
public String createMethodDeclaration(ITranslationUnit tu, String className, IBaseClassInfo[] baseClasses,
String lineDelimiter) throws CoreException {
StringBuilder buf = new StringBuilder();
buf.append(className);
buf.append("(const "); //$NON-NLS-1$
buf.append(className);
buf.append("& other)"); //$NON-NLS-1$
if (fIsInline) {
buf.append('{');
buf.append(lineDelimiter);
String body = CodeGeneration.getConstructorBodyContent(tu, className, null, lineDelimiter);
if (body != null) {
buf.append(body);
buf.append(lineDelimiter);
}
buf.append('}');
} else {
buf.append(";"); //$NON-NLS-1$
}
return buf.toString();
}
@Override
public String createMethodImplementation(ITranslationUnit tu, String className, IBaseClassInfo[] baseClasses,
String lineDelimiter) throws CoreException {
if (fIsInline) {
return ""; //$NON-NLS-1$
}
StringBuilder buf = new StringBuilder();
buf.append(className);
buf.append("::"); //$NON-NLS-1$
buf.append(className);
buf.append("(const "); //$NON-NLS-1$
buf.append(className);
buf.append("& other)"); //$NON-NLS-1$
buf.append(lineDelimiter);
buf.append('{');
buf.append(lineDelimiter);
String body = CodeGeneration.getConstructorBodyContent(tu, className, null, lineDelimiter);
if (body != null) {
buf.append(body);
buf.append(lineDelimiter);
}
buf.append('}');
return buf.toString();
}
@Override
public boolean isConstructor() {
return true;
}
@Override
public boolean isEnabledByDefault() {
return false;
}
@Override
public boolean canModifyVirtual() {
return false;
}
}

View file

@ -45,6 +45,8 @@ public interface IMethodStub {
public boolean isDestructor();
public boolean isEnabledByDefault();
public String createMethodDeclaration(ITranslationUnit tu, String className, IBaseClassInfo[] baseClasses,
String lineDelimiter) throws CoreException;

View file

@ -0,0 +1,95 @@
/*******************************************************************************
* Copyright (c) 2019 Marco Stornelli
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Marco Stornelli - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.wizards.classwizard;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.cdt.ui.CodeGeneration;
import org.eclipse.core.runtime.CoreException;
public final class MoveAssignOpMethodStub extends AbstractMethodStub {
private static String NAME = NewClassWizardMessages.NewClassCodeGeneration_stub_move_op_name;
public MoveAssignOpMethodStub() {
this(ASTAccessVisibility.PUBLIC, false);
}
public MoveAssignOpMethodStub(ASTAccessVisibility access, boolean isInline) {
super(NAME, access, false, isInline);
}
@Override
public String createMethodDeclaration(ITranslationUnit tu, String className, IBaseClassInfo[] baseClasses,
String lineDelimiter) throws CoreException {
StringBuilder buf = new StringBuilder();
buf.append(className);
buf.append("& operator=("); //$NON-NLS-1$
buf.append(className);
buf.append("&& other)"); //$NON-NLS-1$
if (fIsInline) {
buf.append('{');
buf.append(lineDelimiter);
String body = CodeGeneration.getMethodBodyContent(tu, className, "operator=", null, lineDelimiter); //$NON-NLS-1$
if (body != null) {
buf.append(body);
buf.append(lineDelimiter);
}
buf.append('}');
} else {
buf.append(";"); //$NON-NLS-1$
}
return buf.toString();
}
@Override
public String createMethodImplementation(ITranslationUnit tu, String className, IBaseClassInfo[] baseClasses,
String lineDelimiter) throws CoreException {
if (fIsInline) {
return ""; //$NON-NLS-1$
}
StringBuilder buf = new StringBuilder();
buf.append(className);
buf.append("& "); //$NON-NLS-1$
buf.append(className);
buf.append("::"); //$NON-NLS-1$
buf.append("operator=("); //$NON-NLS-1$
buf.append(className);
buf.append("&& other)"); //$NON-NLS-1$
buf.append(lineDelimiter);
buf.append('{');
buf.append(lineDelimiter);
String body = CodeGeneration.getMethodBodyContent(tu, className, "operator=", null, lineDelimiter); //$NON-NLS-1$
if (body != null) {
buf.append(body);
buf.append(lineDelimiter);
}
buf.append('}');
return buf.toString();
}
@Override
public boolean isConstructor() {
return false;
}
@Override
public boolean isEnabledByDefault() {
return false;
}
@Override
public boolean canModifyVirtual() {
return false;
}
}

View file

@ -0,0 +1,94 @@
/*******************************************************************************
* Copyright (c) 2019 Marco Stornelli
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Marco Stornelli - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.ui.wizards.classwizard;
import org.eclipse.cdt.core.model.ITranslationUnit;
import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility;
import org.eclipse.cdt.ui.CodeGeneration;
import org.eclipse.core.runtime.CoreException;
public final class MoveConstructorMethodStub extends AbstractMethodStub {
private static String NAME = NewClassWizardMessages.NewClassCodeGeneration_stub_move_constructor_name;
public MoveConstructorMethodStub() {
this(ASTAccessVisibility.PUBLIC, false);
}
public MoveConstructorMethodStub(ASTAccessVisibility access, boolean isInline) {
super(NAME, access, false, isInline);
}
@Override
public String createMethodDeclaration(ITranslationUnit tu, String className, IBaseClassInfo[] baseClasses,
String lineDelimiter) throws CoreException {
StringBuilder buf = new StringBuilder();
buf.append(className);
buf.append("("); //$NON-NLS-1$
buf.append(className);
buf.append("&& other)"); //$NON-NLS-1$
if (fIsInline) {
buf.append('{');
buf.append(lineDelimiter);
String body = CodeGeneration.getConstructorBodyContent(tu, className, null, lineDelimiter);
if (body != null) {
buf.append(body);
buf.append(lineDelimiter);
}
buf.append('}');
} else {
buf.append(";"); //$NON-NLS-1$
}
return buf.toString();
}
@Override
public String createMethodImplementation(ITranslationUnit tu, String className, IBaseClassInfo[] baseClasses,
String lineDelimiter) throws CoreException {
if (fIsInline) {
return ""; //$NON-NLS-1$
}
StringBuilder buf = new StringBuilder();
buf.append(className);
buf.append("::"); //$NON-NLS-1$
buf.append(className);
buf.append("("); //$NON-NLS-1$
buf.append(className);
buf.append("&& other)"); //$NON-NLS-1$
buf.append(lineDelimiter);
buf.append('{');
buf.append(lineDelimiter);
String body = CodeGeneration.getConstructorBodyContent(tu, className, null, lineDelimiter);
if (body != null) {
buf.append(body);
buf.append(lineDelimiter);
}
buf.append('}');
return buf.toString();
}
@Override
public boolean isConstructor() {
return true;
}
@Override
public boolean isEnabledByDefault() {
return false;
}
@Override
public boolean canModifyVirtual() {
return false;
}
}

View file

@ -123,6 +123,10 @@ public final class NewClassWizardMessages extends NLS {
public static String NewClassCodeGeneration_createType_task_source;
public static String NewClassCodeGeneration_stub_constructor_name;
public static String NewClassCodeGeneration_stub_destructor_name;
public static String NewClassCodeGeneration_stub_copy_constructor_name;
public static String NewClassCodeGeneration_stub_move_constructor_name;
public static String NewClassCodeGeneration_stub_assign_op_name;
public static String NewClassCodeGeneration_stub_move_op_name;
static {
NLS.initializeMessages(NewClassWizardMessages.class.getName(), NewClassWizardMessages.class);

View file

@ -151,3 +151,7 @@ NewClassCodeGeneration_createType_task_header_addIncludePaths=Adding new include
NewClassCodeGeneration_createType_task_source=Creating source file....
NewClassCodeGeneration_stub_constructor_name=Constructor
NewClassCodeGeneration_stub_destructor_name=Destructor
NewClassCodeGeneration_stub_copy_constructor_name=Copy constructor
NewClassCodeGeneration_stub_move_constructor_name=Move constructor
NewClassCodeGeneration_stub_assign_op_name=Copy assignment operator
NewClassCodeGeneration_stub_move_op_name=Move assignment operator

View file

@ -44,13 +44,17 @@ import org.eclipse.cdt.internal.ui.dialogs.StatusUtil;
import org.eclipse.cdt.internal.ui.util.SWTUtil;
import org.eclipse.cdt.internal.ui.wizards.NewElementWizardPage;
import org.eclipse.cdt.internal.ui.wizards.SourceFolderSelectionDialog;
import org.eclipse.cdt.internal.ui.wizards.classwizard.AssignOpMethodStub;
import org.eclipse.cdt.internal.ui.wizards.classwizard.BaseClassInfo;
import org.eclipse.cdt.internal.ui.wizards.classwizard.BaseClassesListDialogField;
import org.eclipse.cdt.internal.ui.wizards.classwizard.ConstructorMethodStub;
import org.eclipse.cdt.internal.ui.wizards.classwizard.CopyConstructorMethodStub;
import org.eclipse.cdt.internal.ui.wizards.classwizard.DestructorMethodStub;
import org.eclipse.cdt.internal.ui.wizards.classwizard.IBaseClassInfo;
import org.eclipse.cdt.internal.ui.wizards.classwizard.IMethodStub;
import org.eclipse.cdt.internal.ui.wizards.classwizard.MethodStubsListDialogField;
import org.eclipse.cdt.internal.ui.wizards.classwizard.MoveAssignOpMethodStub;
import org.eclipse.cdt.internal.ui.wizards.classwizard.MoveConstructorMethodStub;
import org.eclipse.cdt.internal.ui.wizards.classwizard.NamespaceSelectionDialog;
import org.eclipse.cdt.internal.ui.wizards.classwizard.NewBaseClassSelectionDialog;
import org.eclipse.cdt.internal.ui.wizards.classwizard.NewBaseClassSelectionDialog.ITypeSelectionListener;
@ -491,7 +495,7 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
if (stub.canModifyInline()) {
stub.setInline(getBooleanSettingWithDefault(KEY_STUB_INLINE + i, stub.isInline()));
}
addMethodStub(stub, getBooleanSettingWithDefault(KEY_STUB_SELECTED + i, true));
addMethodStub(stub, getBooleanSettingWithDefault(KEY_STUB_SELECTED + i, stub.isEnabledByDefault()));
}
setTestFileSelection(fDialogSettings.getBoolean(KEY_TEST_FILE_SELECTED), true);
@ -574,7 +578,9 @@ public class NewClassCreationWizardPage extends NewElementWizardPage {
* @nooverride This method is not intended to be re-implemented or extended by clients.
*/
protected IMethodStub[] getDefaultMethodStubs() {
return new IMethodStub[] { new ConstructorMethodStub(), new DestructorMethodStub() };
return new IMethodStub[] { new ConstructorMethodStub(), new DestructorMethodStub(),
new CopyConstructorMethodStub(), new MoveConstructorMethodStub(), new AssignOpMethodStub(),
new MoveAssignOpMethodStub() };
}
/**