/*******************************************************************************
* Copyright (c) 2007, 2010 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)
*******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
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.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.index.IIndexFragment;
import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding;
import org.eclipse.cdt.internal.core.index.IIndexScope;
import org.eclipse.cdt.internal.core.index.composite.ICompositesFactory;
public class CompositeCPPClassSpecialization extends CompositeCPPClassType implements ICPPClassSpecialization {
private ObjectMap specializationMap= null;
public CompositeCPPClassSpecialization(ICompositesFactory cf, ICPPClassType rbinding) {
super(cf, rbinding);
}
@Override
public ICPPClassScope getCompositeScope() {
return (ICPPClassScope) cf.getCompositeScope((IIndexScope) ((ICPPClassType) rbinding).getCompositeScope());
}
public ICPPClassType getSpecializedBinding() {
return (ICPPClassType) TemplateInstanceUtil.getSpecializedBinding(cf, rbinding);
}
public ICPPTemplateParameterMap getTemplateParameterMap() {
IBinding owner= getOwner();
if (owner instanceof ICPPSpecialization) {
return ((ICPPSpecialization) owner).getTemplateParameterMap();
}
return CPPTemplateParameterMap.EMPTY;
}
public IBinding specializeMember(IBinding original) {
if (specializationMap == null) {
final Object key= CPPCompositesFactory.createSpecializationKey(cf, rbinding);
final IIndexFragment frag= rbinding.getFragment();
Object cached= frag.getCachedResult(key);
if (cached != null) {
specializationMap= (ObjectMap) cached;
} else {
final ObjectMap newMap= new ObjectMap(2);
// in any fragment explicit specializations may be defined.
IIndexFragmentBinding[] frags= cf.findEquivalentBindings(rbinding);
for (IIndexFragmentBinding fb : frags) {
if (fb instanceof ICPPClassType) {
final ICPPClassType[] nested = ((ICPPClassType)fb).getNestedClasses();
if (nested.length > 0) {
for (ICPPClassType ct : nested) {
if (ct instanceof ICPPClassSpecialization &&
!(ct.getCompositeScope() instanceof ICPPClassSpecializationScope)) {
ICPPClassSpecialization cspec= (ICPPClassSpecialization) cf.getCompositeBinding((IIndexFragmentBinding) ct);
newMap.put(cspec.getSpecializedBinding(), cspec);
}
}
if (!newMap.isEmpty())
break;
}
}
}
specializationMap= (ObjectMap) frag.putCachedResult(key, newMap, false);
}
}
synchronized (specializationMap) {
IBinding result= (IBinding) specializationMap.get(original);
if (result != null)
return result;
}
IBinding newSpec= CPPTemplates.createSpecialization(this, original);
synchronized (specializationMap) {
IBinding oldSpec= (IBinding) specializationMap.put(original, newSpec);
if (oldSpec != null) {
specializationMap.put(original, oldSpec);
return oldSpec;
}
}
return newSpec;
}
@Override
public final ICPPBase[] getBases() {
IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getBases();
}
return super.getBases();
}
@Override
public final ICPPConstructor[] getConstructors() {
IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getConstructors();
}
return super.getConstructors();
}
@Override
public final ICPPMethod[] getDeclaredMethods() {
IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getDeclaredMethods();
}
return super.getDeclaredMethods();
}
@Override
public final ICPPField[] getDeclaredFields() {
IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getDeclaredFields();
}
return super.getDeclaredFields();
}
@Override
public final IBinding[] getFriends() {
IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getFriends();
}
return super.getFriends();
}
@Override
public final ICPPClassType[] getNestedClasses() {
IScope scope= getCompositeScope();
if (scope instanceof ICPPClassSpecializationScope) {
return ((ICPPClassSpecializationScope) scope).getNestedClasses();
}
return super.getNestedClasses();
}
@Deprecated
public ObjectMap getArgumentMap() {
return TemplateInstanceUtil.getArgumentMap(cf, rbinding);
}
}