/** * Copyright (c) 2010, 2011 Darmstadt University of Technology. * 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: * Marcel Bruch - initial API and implementation. */ package org.eclipse.recommenders.internal.chain.rcp; import static org.eclipse.recommenders.internal.chain.rcp.l10n.LogMessages.WARNING_CANNOT_HANDLE_RETURN_TYPE; import static org.eclipse.recommenders.utils.Checks.ensureIsNotNull; import static org.eclipse.recommenders.utils.Logs.log; import org.eclipse.jdt.core.IField; import org.eclipse.jdt.core.ILocalVariable; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.FieldBinding; import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding; import org.eclipse.jdt.internal.compiler.lookup.MethodBinding; import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; /** * Represents a transition from Type A to Type B by some chain element ( {@link IField} access, {@link IMethod} call, or * {@link ILocalVariable} (as entrypoints only)). * * @see ChainFinder */ @SuppressWarnings("restriction") public class ChainElement { public enum ElementType { METHOD, FIELD, LOCAL_VARIABLE } private final Binding element; private TypeBinding returnType; private int dimension; private ElementType elementType; private final boolean requireThis; public ChainElement(final Binding binding, final boolean requireThis) { element = ensureIsNotNull(binding); this.requireThis = requireThis; initializeReturnType(); } private void initializeReturnType() { switch (element.kind()) { case Binding.FIELD: returnType = ((FieldBinding) element).type; elementType = ElementType.FIELD; break; case Binding.LOCAL: returnType = ((LocalVariableBinding) element).type; elementType = ElementType.LOCAL_VARIABLE; break; case Binding.METHOD: returnType = ((MethodBinding) element).returnType; elementType = ElementType.METHOD; break; default: log(WARNING_CANNOT_HANDLE_RETURN_TYPE, element); } dimension = returnType.dimensions(); } @SuppressWarnings("unchecked") public <T extends Binding> T getElementBinding() { return (T) element; } public ElementType getElementType() { return elementType; } public TypeBinding getReturnType() { return returnType; } public int getReturnTypeDimension() { return dimension; } public boolean requiresThisForQualification() { return requireThis; } @Override public int hashCode() { return element.hashCode(); } @Override public boolean equals(final Object obj) { if (obj instanceof ChainElement) { final ChainElement other = (ChainElement) obj; return element.equals(other.element); } return false; } @Override public String toString() { if (elementType == ElementType.METHOD) { final MethodBinding m = (MethodBinding) element; return new StringBuilder().append(m.selector).append(m.signature()).toString(); } return element.toString(); } }