/*******************************************************************************
* Copyright (c) 2007, 2011 Wind River Systems, 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:
* Markus Schorn - initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.ExpansionOverlapsBoundaryException;
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorIncludeStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IEnumerator;
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.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
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.ICPPEnumeration;
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.ICPPTemplateParameter;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.parser.IToken;
public class PDOMASTAdapter {
private static class AnonymousASTName implements IASTName {
private IASTName fDelegate;
private IASTFileLocation fLocation;
public AnonymousASTName(IASTName name, final IASTFileLocation loc) {
fDelegate= name;
fLocation= new IASTFileLocation() {
public int getEndingLineNumber() {
return loc.getStartingLineNumber();
}
public String getFileName() {
return loc.getFileName();
}
public int getStartingLineNumber() {
return loc.getStartingLineNumber();
}
public IASTFileLocation asFileLocation() {
return loc.asFileLocation();
}
public int getNodeLength() {
return 0;
}
public int getNodeOffset() {
return loc.getNodeOffset();
}
public IASTPreprocessorIncludeStatement getContextInclusionStatement() {
return loc.getContextInclusionStatement();
}
};
}
public boolean accept(ASTVisitor visitor) {
return fDelegate.accept(visitor);
}
public boolean contains(IASTNode node) {
return fDelegate.contains(node);
}
public IBinding getBinding() {
return fDelegate.getBinding();
}
public IBinding getPreBinding() {
return fDelegate.getPreBinding();
}
public String getContainingFilename() {
return fLocation.getFileName();
}
public IASTFileLocation getFileLocation() {
return fLocation;
}
public ILinkage getLinkage() {
return fDelegate.getLinkage();
}
public IASTNodeLocation[] getNodeLocations() {
return fDelegate.getNodeLocations();
}
public IASTNode getParent() {
return fDelegate.getParent();
}
public IASTNode[] getChildren() {
return fDelegate.getChildren();
}
public ASTNodeProperty getPropertyInParent() {
return fDelegate.getPropertyInParent();
}
public String getRawSignature() {
return fDelegate.getRawSignature();
}
public IASTTranslationUnit getTranslationUnit() {
return fDelegate.getTranslationUnit();
}
public int getRoleOfName(boolean allowResolution) {
return fDelegate.getRoleOfName(allowResolution);
}
public boolean isDeclaration() {
return fDelegate.isDeclaration();
}
public boolean isDefinition() {
return fDelegate.isDefinition();
}
public boolean isReference() {
return fDelegate.isReference();
}
public IBinding resolveBinding() {
return fDelegate.resolveBinding();
}
public IBinding resolvePreBinding() {
return fDelegate.resolvePreBinding();
}
public IASTCompletionContext getCompletionContext() {
return fDelegate.getCompletionContext();
}
public void setBinding(IBinding binding) {
fDelegate.setBinding(binding);
}
public void setParent(IASTNode node) {
fDelegate.setParent(node);
}
public void setPropertyInParent(ASTNodeProperty property) {
fDelegate.setPropertyInParent(property);
}
public char[] toCharArray() {
return fDelegate.toCharArray();
}
public char[] getSimpleID() {
return fDelegate.getSimpleID();
}
public char[] getLookupKey() {
return fDelegate.getLookupKey();
}
public IASTImageLocation getImageLocation() {
return null;
}
public boolean isPartOfTranslationUnitFile() {
return fLocation.getFileName().equals(fDelegate.getTranslationUnit().getFilePath());
}
@Override
public String toString() {
return fDelegate.toString();
}
public IASTName getLastName() {
return this;
}
public IToken getSyntax() throws ExpansionOverlapsBoundaryException,
UnsupportedOperationException {
return fDelegate.getSyntax();
}
public IToken getLeadingSyntax() throws ExpansionOverlapsBoundaryException,
UnsupportedOperationException {
return fDelegate.getLeadingSyntax();
}
public IToken getTrailingSyntax() throws ExpansionOverlapsBoundaryException,
UnsupportedOperationException {
return fDelegate.getTrailingSyntax();
}
public boolean isFrozen() {
return fDelegate.isFrozen();
}
public boolean isActive() {
return fDelegate.isFrozen();
}
public IASTName copy() {
throw new UnsupportedOperationException();
}
public IASTName copy(CopyStyle style) {
throw new UnsupportedOperationException();
}
}
private static class AnonymousEnumeration implements IEnumeration {
private IEnumeration fDelegate;
private char[] fName;
public AnonymousEnumeration(char[] name, IEnumeration delegate) {
fName= name;
fDelegate= delegate;
}
@Override
public Object clone() {
throw new UnsupportedOperationException();
}
@SuppressWarnings("rawtypes")
public Object getAdapter(Class adapter) {
return fDelegate.getAdapter(adapter);
}
public IEnumerator[] getEnumerators() throws DOMException {
return fDelegate.getEnumerators();
}
public ILinkage getLinkage() {
return fDelegate.getLinkage();
}
public String getName() {
return new String(fName);
}
public char[] getNameCharArray() {
return fName;
}
public IScope getScope() throws DOMException {
return fDelegate.getScope();
}
public boolean isSameType(IType type) {
return fDelegate.isSameType(type);
}
public IBinding getOwner() {
return fDelegate.getOwner();
}
public long getMinValue() {
return fDelegate.getMinValue();
}
public long getMaxValue() {
return fDelegate.getMaxValue();
}
}
private static class AnonymousCompositeType implements ICompositeType {
protected ICompositeType fDelegate;
private char[] fName;
public AnonymousCompositeType(char[] name, ICompositeType delegate) {
fName= name;
fDelegate= delegate;
}
@Override
public Object clone() {
throw new UnsupportedOperationException();
}
public IField findField(String name) {
return fDelegate.findField(name);
}
@SuppressWarnings("rawtypes")
public Object getAdapter(Class adapter) {
return fDelegate.getAdapter(adapter);
}
public IScope getCompositeScope() {
return fDelegate.getCompositeScope();
}
public IField[] getFields() {
return fDelegate.getFields();
}
public int getKey() {
return fDelegate.getKey();
}
public ILinkage getLinkage() {
return fDelegate.getLinkage();
}
public String getName() {
return new String(fName);
}
public char[] getNameCharArray() {
return fName;
}
public IScope getScope() throws DOMException {
return fDelegate.getScope();
}
public boolean isSameType(IType type) {
return fDelegate.isSameType(type);
}
public IBinding getOwner() {
return fDelegate.getOwner();
}
public boolean isAnonymous() {
return fDelegate.isAnonymous();
}
}
private static class AnonymousCPPBinding implements ICPPBinding {
protected ICPPBinding fDelegate;
private char[] fName;
public AnonymousCPPBinding(char[] name, ICPPBinding delegate) {
fName= name;
fDelegate= delegate;
}
@Override
public Object clone() {
throw new UnsupportedOperationException();
}
public String getName() {
return new String(fName);
}
public char[] getNameCharArray() {
return fName;
}
public String[] getQualifiedName() throws DOMException {
String[] qn= fDelegate.getQualifiedName();
if (qn.length < 1) {
qn= new String[]{null};
}
qn[qn.length - 1]= new String(fName);
return qn;
}
public char[][] getQualifiedNameCharArray() throws DOMException {
char[][] qn= fDelegate.getQualifiedNameCharArray();
if (qn.length < 1) {
qn= new char[][]{null};
}
qn[qn.length - 1]= fName;
return qn;
}
@SuppressWarnings("rawtypes")
public Object getAdapter(Class adapter) {
return fDelegate.getAdapter(adapter);
}
public ILinkage getLinkage() {
return fDelegate.getLinkage();
}
public IScope getScope() throws DOMException {
return fDelegate.getScope();
}
public boolean isGloballyQualified() throws DOMException {
return fDelegate.isGloballyQualified();
}
public IBinding getOwner() {
return fDelegate.getOwner();
}
}
private static class AnonymousCPPEnumeration extends AnonymousCPPBinding implements ICPPEnumeration {
public AnonymousCPPEnumeration(char[] name, IEnumeration delegate) {
super(name, (ICPPBinding) delegate);
}
public IEnumerator[] getEnumerators() throws DOMException {
return ((IEnumeration) fDelegate).getEnumerators();
}
public boolean isSameType(IType type) {
return ((IEnumeration) fDelegate).isSameType(type);
}
public long getMinValue() {
return ((IEnumeration)fDelegate).getMinValue();
}
public long getMaxValue() {
return ((IEnumeration)fDelegate).getMaxValue();
}
public boolean isScoped() {
return ((ICPPEnumeration)fDelegate).isScoped();
}
public IType getFixedType() {
return ((ICPPEnumeration)fDelegate).getFixedType();
}
public ICPPScope asScope() {
return ((ICPPEnumeration)fDelegate).asScope();
}
}
private static class AnonymousClassType extends AnonymousCPPBinding implements ICPPClassType {
public AnonymousClassType(char[] name, ICPPClassType delegate) {
super(name, delegate);
}
public IField findField(String name) {
return ((ICPPClassType) fDelegate).findField(name);
}
public ICPPMethod[] getAllDeclaredMethods() {
return ((ICPPClassType) fDelegate).getAllDeclaredMethods();
}
public ICPPBase[] getBases() {
return ((ICPPClassType) fDelegate).getBases();
}
public IScope getCompositeScope() {
return ((ICPPClassType) fDelegate).getCompositeScope();
}
public ICPPConstructor[] getConstructors() {
return ((ICPPClassType) fDelegate).getConstructors();
}
public ICPPField[] getDeclaredFields() {
return ((ICPPClassType) fDelegate).getDeclaredFields();
}
public ICPPMethod[] getDeclaredMethods() {
return ((ICPPClassType) fDelegate).getDeclaredMethods();
}
public IField[] getFields() {
return ((ICPPClassType) fDelegate).getFields();
}
public IBinding[] getFriends() {
return ((ICPPClassType) fDelegate).getFriends();
}
public int getKey() {
return ((ICPPClassType) fDelegate).getKey();
}
public ICPPMethod[] getMethods() {
return ((ICPPClassType) fDelegate).getMethods();
}
public ICPPClassType[] getNestedClasses() {
return ((ICPPClassType) fDelegate).getNestedClasses();
}
public boolean isSameType(IType type) {
return ((ICPPClassType) fDelegate).isSameType(type);
}
public boolean isAnonymous() {
return ((ICPPClassType) fDelegate).isAnonymous();
}
}
/**
* If the provided binding is anonymous, either an adapter is returned
* that computes a name for the binding, or <code>null</code> if that
* is not appropriate (e.g. binding is not a type).
* Otherwise, if the binding has a name it is returned unchanged.
*/
public static IBinding getAdapterForAnonymousASTBinding(IBinding binding) {
if (binding != null && !(binding instanceof IIndexBinding)) {
char[] name= binding.getNameCharArray();
if (name.length == 0) {
if (binding instanceof IEnumeration) {
name = ASTTypeUtil.createNameForAnonymous(binding);
if (name != null) {
if (binding instanceof ICPPBinding) {
return new AnonymousCPPEnumeration(name, (IEnumeration) binding);
}
return new AnonymousEnumeration(name, (IEnumeration) binding);
}
} else if (binding instanceof ICPPClassType) {
name = ASTTypeUtil.createNameForAnonymous(binding);
if (name != null) {
return new AnonymousClassType(name, (ICPPClassType) binding);
}
} else if (binding instanceof ICompositeType) {
name = ASTTypeUtil.createNameForAnonymous(binding);
if (name != null) {
return new AnonymousCompositeType(name, (ICompositeType) binding);
}
} else if (binding instanceof ICPPTemplateParameter) {
return binding;
} else if (binding instanceof ICPPConstructor) {
return binding;
}
return null;
}
}
return binding;
}
/**
* If the name is empty and has no file location, either an adapter
* that has a file location is returned, or <code>null</code> if that
* is not possible (no parent with a file location).
* Otherwise if the provided name is not empty or has a file location,
* it is returned unchanged.
*/
public static IASTName getAdapterIfAnonymous(IASTName name) {
if (name.getLookupKey().length == 0) {
if (name.getFileLocation() == null) {
IASTNode parent= name.getParent();
if (parent != null) {
IASTFileLocation loc= parent.getFileLocation();
if (loc != null) {
return new AnonymousASTName(name, loc);
}
}
return null;
}
}
return name;
}
}