/******************************************************************************* * Copyright (c) 2006, 2009 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.ui.callhierarchy; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.IEnumerator; import org.eclipse.cdt.core.model.IMacro; import org.eclipse.cdt.core.model.ITranslationUnit; import org.eclipse.cdt.core.model.IVariableDeclaration; import org.eclipse.cdt.internal.ui.util.CoreUtility; /** * Represents a node in the include browser */ public class CHNode implements IAdaptable { private CHNode fParent; private ICElement fRepresentedDecl; private ITranslationUnit fFileOfReferences; private List<CHReferenceInfo> fReferences; protected int fHashCode; private long fTimestamp; private boolean fIsRecursive; private boolean fIsInitializer; private boolean fIsReadAccess; private boolean fIsWriteAccess; private final int fLinkageID; /** * Creates a new node for the include browser */ public CHNode(CHNode parent, ITranslationUnit fileOfReferences, long timestamp, ICElement decl, int linkageID) { fParent= parent; fFileOfReferences= fileOfReferences; fReferences= Collections.emptyList(); fRepresentedDecl= decl; fIsRecursive= computeIsRecursive(fParent, decl); fHashCode= computeHashCode(); fTimestamp= timestamp; fLinkageID= linkageID; } private int computeHashCode() { int hashCode= 1; if (fParent != null) { hashCode= fParent.hashCode() * 31; } if (fRepresentedDecl != null) { hashCode+= fRepresentedDecl.hashCode(); } return hashCode; } @Override public int hashCode() { return fHashCode; } @Override public boolean equals(Object o) { if (!(o instanceof CHNode)) { return false; } CHNode rhs = (CHNode) o; if (fHashCode != rhs.fHashCode) { return false; } return CoreUtility.safeEquals(fRepresentedDecl, rhs.fRepresentedDecl); } private boolean computeIsRecursive(CHNode parent, ICElement decl) { if (parent == null || decl == null) { return false; } if (decl.equals(parent.fRepresentedDecl)) { return true; } return computeIsRecursive(parent.fParent, decl); } /** * Returns the parent node or <code>null</code> for the root node. */ public CHNode getParent() { return fParent; } public int getLinkageID() { return fLinkageID; } public boolean isRecursive() { return fIsRecursive; } public int getReferenceCount() { return fReferences.size(); } public CHReferenceInfo getReference(int idx) { return fReferences.get(idx); } public ICElement getRepresentedDeclaration() { return fRepresentedDecl; } public long getTimestamp() { return fTimestamp; } public boolean isMacro() { return fRepresentedDecl instanceof IMacro; } public boolean isVariableOrEnumerator() { return fRepresentedDecl instanceof IVariableDeclaration || fRepresentedDecl instanceof IEnumerator; } public int getFirstReferenceOffset() { return fReferences.isEmpty() ? -1 : getReference(0).getOffset(); } public void addReference(CHReferenceInfo info) { switch (fReferences.size()) { case 0: fReferences= Collections.singletonList(info); return; case 1: fReferences= new ArrayList<CHReferenceInfo>(fReferences); break; } fReferences.add(info); } public ITranslationUnit getFileOfReferences() { return fFileOfReferences; } @SuppressWarnings({ "unchecked", "rawtypes" }) public Object getAdapter(Class adapter) { if (adapter.isAssignableFrom(ICElement.class)) { return getRepresentedDeclaration(); } return null; } public boolean isMultiDef() { return false; } public ICElement getOneRepresentedDeclaration() { return getRepresentedDeclaration(); } public boolean isInitializer() { return fIsInitializer; } public void setInitializer(boolean isInitializer) { fIsInitializer = isInitializer; } public void sortReferencesByOffset() { if (fReferences.size() > 1) { Collections.sort(fReferences, CHReferenceInfo.COMPARE_OFFSET); } } public void setRWAccess(boolean readAccess, boolean writeAccess) { fIsReadAccess= readAccess; fIsWriteAccess= writeAccess; } public boolean isReadAccess() { return fIsReadAccess; } public boolean isWriteAccess() { return fIsWriteAccess; } }