1 /*******************************************************************************
2 * Copyright (c) 2008, 2011 Institute for Software, HSR Hochschule fuer Technik
3 * Rapperswil, University of applied sciences and others
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Institute for Software - initial API and implementation
11 * Sergey Prigogin (Google)
12 *******************************************************************************/
13 package org.eclipse.cdt.internal.ui.refactoring.gettersandsetters;
15 import java.util.ArrayList;
16 import java.util.SortedSet;
17 import java.util.TreeSet;
19 import org.eclipse.jface.viewers.ITreeContentProvider;
20 import org.eclipse.jface.viewers.Viewer;
22 import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
23 import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
24 import org.eclipse.cdt.core.dom.ast.IASTName;
25 import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
27 import org.eclipse.cdt.internal.ui.refactoring.gettersandsetters.GetterSetterInsertEditProvider.AccessorKind;
29 public class GetterSetterContext implements ITreeContentProvider {
30 public ArrayList<IASTSimpleDeclaration> existingFields = new ArrayList<IASTSimpleDeclaration>();
31 public ArrayList<IASTFunctionDefinition> existingFunctionDefinitions = new ArrayList<IASTFunctionDefinition>();
32 public ArrayList<IASTSimpleDeclaration> existingFunctionDeclarations = new ArrayList<IASTSimpleDeclaration>();
33 public SortedSet<GetterSetterInsertEditProvider> selectedFunctions = new TreeSet<GetterSetterInsertEditProvider>();
34 public IASTName selectedName;
35 private ArrayList<FieldWrapper> wrappedFields;
36 private boolean implementationInHeader = false;
38 public Object[] getChildren(Object parentElement) {
39 ArrayList<GetterSetterInsertEditProvider> children = new ArrayList<GetterSetterInsertEditProvider>();
40 if (parentElement instanceof FieldWrapper) {
41 FieldWrapper wrapper = (FieldWrapper) parentElement;
43 if (wrapper.getChildNodes().isEmpty()) {
44 if (!wrapper.getter.exists()) {
45 wrapper.childNodes.add(createGetterInserter(wrapper.field));
47 if (!wrapper.setter.exists() && !wrapper.field.getDeclSpecifier().isConst()) {
48 wrapper.childNodes.add(createSetterInserter(wrapper.field));
51 children = wrapper.getChildNodes();
53 return children.toArray();
56 public GetterSetterInsertEditProvider createGetterInserter(IASTSimpleDeclaration simpleDeclaration) {
57 IASTName fieldName = getFieldDeclarationName(simpleDeclaration);
58 return new GetterSetterInsertEditProvider(fieldName, simpleDeclaration, AccessorKind.GETTER);
61 public GetterSetterInsertEditProvider createSetterInserter(IASTSimpleDeclaration simpleDeclaration) {
62 IASTName fieldName = getFieldDeclarationName(simpleDeclaration);
63 return new GetterSetterInsertEditProvider(fieldName, simpleDeclaration, AccessorKind.SETTER);
66 public Object getParent(Object element) {
70 public boolean hasChildren(Object element) {
71 if (element instanceof FieldWrapper) {
72 FieldWrapper wrapper = (FieldWrapper) element;
73 return wrapper.missingGetterOrSetter();
78 public Object[] getElements(Object inputElement) {
79 return getWrappedFields().toArray();
82 public void refresh() {
83 // We only recreate the function declarations instead of recreating GetterSetterInsertEditProviders.
84 // That way, selectedFunctions is still valid. Also, the objects inside the TreeViewer are still the same
85 // which is convenient because that way we don't need to save then restore the collapsed/expanded+checked/unchecked state of the TreeViewer.
86 for (FieldWrapper wrapper : wrappedFields) {
87 for (GetterSetterInsertEditProvider provider : wrapper.childNodes) {
88 provider.createFunctionDeclaration();
93 public void dispose() {
96 public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
99 public boolean isImplementationInHeader() {
100 return implementationInHeader;
103 public void setImplementationInHeader(boolean implementationInHeader) {
104 this.implementationInHeader = implementationInHeader;
107 private ArrayList<FieldWrapper> getWrappedFields() {
108 if (wrappedFields == null) {
109 wrappedFields = new ArrayList<FieldWrapper>();
110 for (IASTSimpleDeclaration currentField : existingFields) {
111 FieldWrapper wrapper = new FieldWrapper();
112 wrapper.field = currentField;
113 wrapper.getter = getGetterForField(currentField);
114 wrapper.setter = getSetterForField(currentField);
115 if (wrapper.missingGetterOrSetter()) {
116 wrappedFields.add(wrapper);
120 return wrappedFields;
123 private FunctionWrapper getGetterForField(IASTSimpleDeclaration currentField) {
124 FunctionWrapper wrapper = new FunctionWrapper();
125 String name = GetterSetterNameGenerator.generateGetterName(getFieldDeclarationName(currentField));
126 setFunctionToWrapper(wrapper, name);
130 private IASTName getFieldDeclarationName(IASTSimpleDeclaration fieldDeclaration) {
131 IASTDeclarator declarator = fieldDeclaration.getDeclarators()[0];
132 while (declarator.getNestedDeclarator() != null) {
133 declarator = declarator.getNestedDeclarator();
135 return declarator.getName();
138 private FunctionWrapper getSetterForField(IASTSimpleDeclaration currentField) {
139 FunctionWrapper wrapper = new FunctionWrapper();
140 String name = GetterSetterNameGenerator.generateSetterName(getFieldDeclarationName(currentField));
141 setFunctionToWrapper(wrapper, name);
145 private void setFunctionToWrapper(FunctionWrapper wrapper, String getterName) {
146 for (IASTFunctionDefinition currentDefinition : existingFunctionDefinitions) {
147 if (currentDefinition.getDeclarator().getName().toString().endsWith(getterName)) {
148 wrapper.functionDefinition = currentDefinition;
152 for (IASTSimpleDeclaration currentDeclaration : existingFunctionDeclarations) {
153 if (getFieldDeclarationName(currentDeclaration).toString().endsWith(getterName)) {
154 wrapper.functionDeclaration = currentDeclaration;
159 protected class FieldWrapper {
160 protected IASTSimpleDeclaration field;
161 protected FunctionWrapper getter;
162 protected FunctionWrapper setter;
163 protected ArrayList<GetterSetterInsertEditProvider> childNodes = new ArrayList<GetterSetterInsertEditProvider>(2);
166 public String toString() {
167 IASTDeclarator declarator = field.getDeclarators()[0];
168 while (declarator.getNestedDeclarator() != null) {
169 declarator = declarator.getNestedDeclarator();
171 return declarator.getName().toString();
174 public ArrayList<GetterSetterInsertEditProvider> getChildNodes() {
178 public boolean missingGetterOrSetter() {
179 return !getter.exists() || !setter.exists();
183 protected class FunctionWrapper {
184 protected IASTSimpleDeclaration functionDeclaration;
185 protected IASTFunctionDefinition functionDefinition;
187 public boolean exists() {
188 return functionDeclaration != null || functionDefinition != null;