/*******************************************************************************
* Copyright (c) 2005, 2013 IBM Corporation 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:
* IBM Corporation - initial API and implementation
* Sergey Prigogin (Google)
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
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.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableType;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
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.pdom.dom.cpp.PDOMCPPDeferredClassInstance;
import org.eclipse.core.runtime.CoreException;
/**
* Represents a instantiation that cannot be performed because of dependent arguments or an unknown template.
*/
public class CPPDeferredClassInstance extends CPPUnknownBinding implements ICPPDeferredClassInstance, ISerializableType {
private final ICPPTemplateArgument[] fArguments;
private final ICPPClassTemplate fClassTemplate;
private final ICPPScope fLookupScope;
public CPPDeferredClassInstance(ICPPClassTemplate template, ICPPTemplateArgument[] arguments,
ICPPScope lookupScope) {
// With template template parameters the owner must not be calculated, it'd lead to an infinite loop.
// Rather than that we override getOwner().
super(template.getNameCharArray());
fArguments= arguments;
fClassTemplate= template;
fLookupScope= lookupScope;
}
public CPPDeferredClassInstance(ICPPClassTemplate template, ICPPTemplateArgument[] arguments) {
this(template, arguments, null);
}
@Override
public IBinding getOwner() {
return fClassTemplate.getOwner();
}
@Override
public ICPPClassTemplate getClassTemplate() {
return (ICPPClassTemplate) getSpecializedBinding();
}
@Override
public boolean isExplicitSpecialization() {
return false;
}
@Override
public CPPDeferredClassInstance clone() {
return (CPPDeferredClassInstance) super.clone();
}
@Override
public boolean isSameType(IType type) {
if (type == this)
return true;
if (type instanceof ITypedef)
return type.isSameType(this);
// allow some fuzziness here.
ICPPClassTemplate classTemplate = getClassTemplate();
if (type instanceof ICPPDeferredClassInstance) {
final ICPPDeferredClassInstance rhs = (ICPPDeferredClassInstance) type;
if (!classTemplate.isSameType((IType) rhs.getSpecializedBinding()))
return false;
return CPPTemplates.haveSameArguments(this, rhs);
}
return false;
}
@Override
public int getKey() {
return getClassTemplate().getKey();
}
@Override
public ICPPBase[] getBases() {
return ICPPBase.EMPTY_BASE_ARRAY;
}
@Override
public IField[] getFields() {
return IField.EMPTY_FIELD_ARRAY;
}
@Override
public IField findField(String name) {
return null;
}
@Override
public ICPPField[] getDeclaredFields() {
return ICPPField.EMPTY_CPPFIELD_ARRAY;
}
@Override
public ICPPMethod[] getMethods() {
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
}
@Override
public ICPPMethod[] getAllDeclaredMethods() {
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
}
@Override
public ICPPMethod[] getDeclaredMethods() {
return ICPPMethod.EMPTY_CPPMETHOD_ARRAY;
}
@Override
public ICPPConstructor[] getConstructors() {
return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY;
}
@Override
public IBinding[] getFriends() {
return IBinding.EMPTY_BINDING_ARRAY;
}
@Override
public final IScope getCompositeScope() {
return asScope();
}
@Override
public ICPPClassType[] getNestedClasses() {
return ICPPClassType.EMPTY_CLASS_ARRAY;
}
@Override
public boolean isAnonymous() {
return false;
}
@Override
public boolean isFinal() {
return false;
}
@Override
public ICPPTemplateArgument[] getTemplateArguments() {
return fArguments;
}
@Override
public ICPPTemplateDefinition getTemplateDefinition() {
return fClassTemplate;
}
@Override
public CPPTemplateParameterMap getTemplateParameterMap() {
ICPPTemplateParameter[] params = fClassTemplate.getTemplateParameters();
int size = Math.min(fArguments.length, params.length);
CPPTemplateParameterMap map = new CPPTemplateParameterMap(size);
for (int i = 0; i < size; i++) {
map.put(params[i], fArguments[i]);
}
return map;
}
@Override
public IBinding getSpecializedBinding() {
return getTemplateDefinition();
}
@Override
public IScope getScope() throws DOMException {
return fClassTemplate.getScope();
}
@Override
public ICPPScope asScope() {
if (fLookupScope != null)
return fLookupScope;
return super.asScope();
}
@Override
public String toString() {
return ASTTypeUtil.getType(this, true);
}
@Override
public void marshal(ITypeMarshalBuffer buffer) throws CoreException {
short firstBytes= ITypeMarshalBuffer.DEFERRED_CLASS_INSTANCE;
buffer.putShort(firstBytes);
buffer.marshalBinding(fClassTemplate);
buffer.putInt(fArguments.length);
for (ICPPTemplateArgument arg : fArguments) {
buffer.marshalTemplateArgument(arg);
}
}
public static ICPPDeferredClassInstance unmarshal(IIndexFragment fragment, short firstBytes,
ITypeMarshalBuffer buffer) throws CoreException {
IBinding template= buffer.unmarshalBinding();
int argcount= buffer.getInt();
ICPPTemplateArgument[] args = new ICPPTemplateArgument[argcount];
for (int i = 0; i < argcount; i++) {
args[i]= buffer.unmarshalTemplateArgument();
}
return new PDOMCPPDeferredClassInstance(fragment, (ICPPClassTemplate) template, args);
}
@Override
public int getVisibility(IBinding member) {
throw new IllegalArgumentException(member.getName() + " is not a member of " + getName()); //$NON-NLS-1$
}
}