/******************************************************************************* * Copyright (c) 2007, 2014 Symbian Software Systems 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: * Andrew Ferguson (Symbian) - Initial implementation * Markus Schorn (Wind River Systems) * Sergey Prigogin (Google) * Thomas Corbat (IFS) *******************************************************************************/ package org.eclipse.cdt.internal.core.index.composite.cpp; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType; import java.util.Arrays; import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; import org.eclipse.cdt.internal.core.index.IIndexType; import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory; class CompositeCPPClassType extends CompositeCPPBinding implements ICPPClassType, IIndexType { public CompositeCPPClassType(ICompositesFactory cf, ICPPClassType rbinding) { super(cf, rbinding); } @Override public Object clone() { fail(); return null; } @Override public final IField findField(String name) { return ClassTypeHelper.findField(this, name); } @Override public ICPPMethod[] getAllDeclaredMethods() { return ClassTypeHelper.getAllDeclaredMethods(this, null); } private class CPPBaseDelegate implements ICPPBase { private final ICPPBase base; private IType baseClass; private final boolean writable; CPPBaseDelegate(ICPPBase b) { this(b, false); } CPPBaseDelegate(ICPPBase b, boolean writable) { this.base= b; this.writable= writable; } @Override public IBinding getBaseClass() { IType type= getBaseClassType(); type = getNestedType(type, TDEF); if (type instanceof IBinding) return (IBinding) type; return null; } @Override public IType getBaseClassType() { if (baseClass == null) { baseClass= cf.getCompositeType(base.getBaseClassType()); } return baseClass; } @Override public IName getClassDefinitionName() { return base.getClassDefinitionName(); } @Override public int getVisibility() { return base.getVisibility(); } @Override public boolean isVirtual() { return base.isVirtual(); } @Override public boolean isInheritedConstructorsSource() { return base.isInheritedConstructorsSource(); } @Override public void setBaseClass(IBinding binding) { if (writable && binding instanceof IType) { baseClass= (IType) binding; } else { base.setBaseClass(binding); } } @Override public void setBaseClass(IType binding) { if (writable) { baseClass= binding; } else { base.setBaseClass(binding); } } @Override public ICPPBase clone(){ return new CPPBaseDelegate(base, true); } } @Override public ICPPBase[] getBases() { ICPPBase[] bases = ((ICPPClassType) rbinding).getBases(); return wrapBases(bases); } @Override public ICPPConstructor[] getConstructors() { ICPPConstructor[] result = ((ICPPClassType) rbinding).getConstructors(); return wrapBindings(result); } @Override public ICPPField[] getDeclaredFields() { ICPPField[] result = ((ICPPClassType) rbinding).getDeclaredFields(); return wrapBindings(result); } @Override public ICPPMethod[] getDeclaredMethods() { ICPPMethod[] result = ((ICPPClassType) rbinding).getDeclaredMethods(); return wrapBindings(result); } @Override public IField[] getFields() { return ClassTypeHelper.getFields(this, null); } @Override public IBinding[] getFriends() { IBinding[] preResult = ((ICPPClassType) rbinding).getFriends(); return wrapBindings(preResult); } @Override public ICPPMethod[] getMethods() { return ClassTypeHelper.getMethods(this, null); } @Override public ICPPClassType[] getNestedClasses() { ICPPClassType[] result = ((ICPPClassType) rbinding).getNestedClasses(); return wrapBindings(result); } @Override public ICPPScope getCompositeScope() { return new CompositeCPPClassScope(cf, rbinding); } @Override public int getKey() { return ((ICPPClassType) rbinding).getKey(); } @Override public boolean isSameType(IType type) { return ((ICPPClassType) rbinding).isSameType(type); } @Override public boolean isAnonymous() { return ((ICPPClassType) rbinding).isAnonymous(); } protected ICPPBase[] wrapBases(final ICPPBase[] bases) { ICPPBase[] result = new ICPPBase[bases.length]; for (int i= 0; i < bases.length; i++) { result[i] = new CPPBaseDelegate(bases[i]); } return result; } @SuppressWarnings("unchecked") protected <T extends IBinding> T[] wrapBindings(T[] bindings) { T[] result = Arrays.copyOf(bindings, bindings.length); for (int i= 0; i < bindings.length; i++) { result[i] = (T) cf.getCompositeBinding((IIndexFragmentBinding) bindings[i]); } return result; } @Override public boolean isFinal() { return ((ICPPClassType) rbinding).isFinal(); } @Override public int getVisibility(IBinding member) { return ((ICPPClassType) rbinding).getVisibility(member); } }