Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/overridemethods/Method.java')
-rw-r--r--core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/overridemethods/Method.java197
1 files changed, 197 insertions, 0 deletions
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/overridemethods/Method.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/overridemethods/Method.java
new file mode 100644
index 00000000000..7da8987a12e
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/refactoring/overridemethods/Method.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Pavel Marek
+ *
+ * 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:
+ * Pavel Marek - initial API and implementation
+ * Marco Stornelli - Improvements
+ *******************************************************************************/
+package org.eclipse.cdt.internal.ui.refactoring.overridemethods;
+
+import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
+import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
+import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTTypeId;
+import org.eclipse.cdt.core.dom.ast.INodeFactory;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExpression;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVirtSpecifier.SpecifierKind;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
+import org.eclipse.cdt.core.dom.rewrite.DeclarationGenerator;
+import org.eclipse.cdt.internal.ui.refactoring.CRefactoringContext;
+import org.eclipse.cdt.internal.ui.refactoring.utils.DefinitionFinder;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.OperationCanceledException;
+
+/**
+ * Wrapper for ICPPMethod
+ */
+public class Method {
+ private IASTDeclSpecifier fDeclSpecifier;
+ private ICPPMethod fMethod;
+ private OverrideOptions fOptions;
+
+ /**
+ * Accepts only methods declared as virtual.
+ * @param method The ICPPMethod to be wrapped
+ * @param declSpecifier The class declaration specifier
+ * @param options Override options
+ */
+ public Method(ICPPMethod method, IASTDeclSpecifier declSpecifier, OverrideOptions options) {
+ fMethod = method;
+ fOptions = options;
+ fDeclSpecifier = declSpecifier;
+ }
+
+ /**
+ * Accepts only methods declared as virtual.
+ * @param method The ICPPMethod to be wrapped
+ * @param options Override options
+ */
+ public Method(ICPPMethod method, OverrideOptions options) {
+ fMethod = method;
+ fOptions = options;
+ fDeclSpecifier = null;
+ }
+
+ /**
+ * Two methods are considered equal if they have same signature ie. name
+ * and types of parameters in same order.
+ */
+ @Override
+ public int hashCode() {
+ StringBuilder stringBuilder = new StringBuilder();
+
+ stringBuilder.append(fMethod.getName());
+ for (ICPPParameter parameter : fMethod.getParameters()) {
+ stringBuilder.append(parameter.getType());
+
+ }
+ return stringBuilder.toString().hashCode();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return this.hashCode() == o.hashCode();
+ }
+
+ /**
+ * Get the wrapped method
+ * @return The method
+ */
+ public ICPPMethod getMethod() {
+ return fMethod;
+ }
+
+ /**
+ * Accepts only methods declared as virtual.
+ * @param fMethod
+ */
+ public void setMethod(ICPPMethod fMethod) {
+ this.fMethod = fMethod;
+ }
+
+ @Override
+ public String toString() {
+ return fMethod.toString();
+ }
+
+ /**
+ * Get the class declaration specifier
+ * @return The class declaration specifier
+ */
+ public IASTDeclSpecifier getDeclSpecifier() {
+ return fDeclSpecifier;
+ }
+
+ /**
+ * Create a IASTNode for this method
+ * @param context The refactoring context
+ * @return The IASTNode for the method declaration
+ * @throws OperationCanceledException
+ * @throws CoreException
+ */
+ public IASTNode createNode(CRefactoringContext context) throws OperationCanceledException, CoreException {
+ ICPPFunctionType functionType = fMethod.getDeclaredType();
+ ICPPParameter[] parameters = fMethod.getParameters();
+ IASTName declaration = DefinitionFinder.getMemberDeclaration(fMethod, getDeclSpecifier().getTranslationUnit(),
+ context, null);
+ INodeFactory factory = getDeclSpecifier().getTranslationUnit().getASTNodeFactory();
+ DeclarationGenerator declGen = DeclarationGenerator.create(factory);
+ if (declaration == null)
+ return null;
+
+ IASTDeclarator declarator = (IASTDeclarator) declaration.getParent();
+ IASTNode parent = declarator.getParent();
+ if (!(parent instanceof IASTSimpleDeclaration))
+ return null;
+
+ /**
+ * We can't just copy the original nodes here but we need to create a new node. We can't do it
+ * because the original node could lack some information needed in the clone. Example: the node
+ * in parent has a parameter to an object inside a namespace but namespace miss because the interface
+ * class is declared in the same namespace too, but in this case the new method of child class may needs
+ * of fully qualified name for the parameter, so a plain copy doesn't work.
+ */
+ IASTStandardFunctionDeclarator newDeclarator = factory.newFunctionDeclarator(declarator.getName().copy());
+ IASTDeclSpecifier newDeclSpec = declGen.createDeclSpecFromType(functionType);
+ if (newDeclSpec instanceof ICPPASTDeclSpecifier && fOptions.preserveVirtual()) {
+ ((ICPPASTDeclSpecifier) newDeclSpec).setVirtual(true);
+ }
+ IASTSimpleDeclaration simple = factory.newSimpleDeclaration(newDeclSpec);
+ if (newDeclarator instanceof ICPPASTFunctionDeclarator) {
+ ICPPASTFunctionDeclarator funcDeclarator = (ICPPASTFunctionDeclarator) newDeclarator;
+ funcDeclarator.setPureVirtual(false);
+ funcDeclarator.setConst(functionType.isConst());
+ if (fOptions.addOverride()) {
+ funcDeclarator.addVirtSpecifier(((ICPPNodeFactory) factory).newVirtSpecifier(SpecifierKind.Override));
+ }
+ for (ICPPParameter par : parameters) {
+ IASTDeclarator parDeclarator = declGen.createDeclaratorFromType(par.getType(),
+ par.getName().toCharArray());
+ IASTDeclSpecifier parSpecifier = declGen.createDeclSpecFromType(par.getType());
+ IASTParameterDeclaration parameter = factory.newParameterDeclaration(parSpecifier, parDeclarator);
+ funcDeclarator.addParameterDeclaration(parameter);
+ }
+ for (IASTPointerOperator op : declarator.getPointerOperators())
+ funcDeclarator.addPointerOperator(op.copy());
+ if (declarator instanceof ICPPASTFunctionDeclarator) {
+ ICPPASTFunctionDeclarator orig = (ICPPASTFunctionDeclarator) declarator;
+ funcDeclarator.setRefQualifier(orig.getRefQualifier());
+ IASTTypeId[] typesId = orig.getExceptionSpecification();
+ if (typesId == IASTTypeId.EMPTY_TYPEID_ARRAY)
+ funcDeclarator.setEmptyExceptionSpecification();
+ else {
+ for (IASTTypeId typeId : typesId) {
+ funcDeclarator.addExceptionSpecificationTypeId(typeId == null ? null : typeId.copy());
+ }
+ }
+ ICPPASTExpression noexceptExpression = orig.getNoexceptExpression();
+ if (noexceptExpression != null) {
+ funcDeclarator.setNoexceptExpression(
+ noexceptExpression == ICPPASTFunctionDeclarator.NOEXCEPT_DEFAULT ? noexceptExpression
+ : (ICPPASTExpression) noexceptExpression.copy());
+ }
+ }
+ }
+ simple.addDeclarator(newDeclarator);
+ simple.setDeclSpecifier(newDeclSpec);
+ simple.setParent(getDeclSpecifier());
+ return simple;
+ }
+}

Back to the top