/******************************************************************************* * Copyright (c) 2011, 2012 Google, Inc 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: * Sergey Prigogin (Google) - initial API and implementation *******************************************************************************/ package org.eclipse.cdt.internal.ui.refactoring.gettersandsetters; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier; 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.IArrayType; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IPointerType; import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.cdt.internal.ui.refactoring.gettersandsetters.AccessorDescriptor.AccessorKind; class FieldDescriptor { private final IASTName fieldName; private final IASTDeclarator fieldDeclarator; private final AccessorDescriptor getter; private final AccessorDescriptor setter; private final AccessorDescriptor[] childNodes; private final GetterSetterContext context; FieldDescriptor(IASTDeclarator field, GetterSetterContext context) { this.fieldName = GetterSetterContext.getDeclaratorName(field); this.fieldDeclarator = field; this.context = context; Set<String> namesToAvoid = getNamesToAvoid(); String name = GetterSetterNameGenerator.generateGetterName(fieldName, namesToAvoid); this.getter = new AccessorDescriptor(AccessorKind.GETTER, name, this); name = GetterSetterNameGenerator.generateSetterName(fieldName, namesToAvoid); if (!isAssignable(field)) name = null; this.setter = new AccessorDescriptor(AccessorKind.SETTER, name, this); List<AccessorDescriptor> children = new ArrayList<AccessorDescriptor>(2); if (getter.canBeGenerated()) { children.add(getter); } if (setter.canBeGenerated()) { children.add(setter); } childNodes = children.toArray(new AccessorDescriptor[children.size()]); } private Set<String> getNamesToAvoid() { Set<String> namesToAvoid = new HashSet<String>(); // Add field names. for (IASTDeclarator fieldDeclarator : context.existingFields) { namesToAvoid.add(String.valueOf(GetterSetterContext.getDeclaratorName(fieldDeclarator).getSimpleID())); } // Add constructor name. if (!context.existingFields.isEmpty()) { IASTNode node = context.existingFields.get(0).getParent(); while (!(node instanceof IASTCompositeTypeSpecifier)) { node = node.getParent(); } IASTCompositeTypeSpecifier comp = (IASTCompositeTypeSpecifier) node; namesToAvoid.add(String.valueOf(comp.getName().getLastName().getSimpleID())); } return namesToAvoid; } private static boolean isAssignable(IASTDeclarator fieldDeclarator) { IASTName name = GetterSetterContext.getDeclaratorName(fieldDeclarator); IBinding binding = name.resolveBinding(); if (!(binding instanceof ICPPField)) return false; ICPPField field = (ICPPField) binding; IType type = field.getType(); type = SemanticUtil.getNestedType(type, SemanticUtil.TDEF); if (type instanceof IArrayType || type instanceof ICPPReferenceType) return false; if (type instanceof IPointerType && ((IPointerType) type).isConst()) return false; if (type instanceof IQualifierType && ((IQualifierType) type).isConst()) return false; return true; } @Override public String toString() { return fieldName.toString(); } AccessorDescriptor[] getChildNodes() { return childNodes; } boolean missingGetterOrSetter() { return getter.canBeGenerated() || setter.canBeGenerated(); } public GetterSetterContext getContext() { return context; } public IASTName getFieldName() { return fieldName; } public IASTDeclarator getFieldDeclarator() { return fieldDeclarator; } public AccessorDescriptor getGetter() { return getter; } public AccessorDescriptor getSetter() { return setter; } }