/******************************************************************************* * Copyright (c) 2006-2014 * Software Technology Group, Dresden University of Technology * DevBoost GmbH, Berlin, Amtsgericht Charlottenburg, HRB 140026 * * 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: * Software Technology Group - TU Dresden, Germany; * DevBoost GmbH - Berlin, Germany * - initial API and implementation ******************************************************************************/ package org.emftext.language.java.extensions.references; import org.emftext.language.java.classifiers.AnonymousClass; import org.emftext.language.java.classifiers.Enumeration; import org.emftext.language.java.expressions.NestedExpression; import org.emftext.language.java.literals.Literal; import org.emftext.language.java.literals.Super; import org.emftext.language.java.members.AdditionalField; import org.emftext.language.java.members.EnumConstant; import org.emftext.language.java.references.ElementReference; import org.emftext.language.java.references.PrimitiveTypeReference; import org.emftext.language.java.references.Reference; import org.emftext.language.java.references.ReferenceableElement; import org.emftext.language.java.references.ReflectiveClassReference; import org.emftext.language.java.references.SelfReference; import org.emftext.language.java.references.StringReference; import org.emftext.language.java.types.Type; import org.emftext.language.java.types.TypeReference; import org.emftext.language.java.types.TypedElement; import org.emftext.language.java.variables.AdditionalLocalVariable; public class ReferenceExtension { public static Reference getPrevious(Reference me) { if (me.eContainer() instanceof Reference) { Reference container = (Reference) me.eContainer(); if (me.equals(container.getNext())) { return container; } } return null; } /** * Determines the {@link Type} of the reference. That is, either the type to * which the reference points directly, or the type of the element to which * the reference points. * * @return the determined type */ public static Type getReferencedType(Reference me) { if (me instanceof Literal) { return ((Literal) me).getType(); } Type type = null; // Referenced element points to a type if (me instanceof TypedElement) { TypeReference typeRef = ((TypedElement) me).getTypeReference(); type = typeRef.getBoundTarget(me); } // Element points to this or super else if (me instanceof SelfReference) { Type thisClass = null; if (me.getPrevious() != null) { thisClass = me.getPrevious().getReferencedType(); } else { AnonymousClass anonymousContainer = me.getContainingAnonymousClass(); if (anonymousContainer != null) { thisClass = anonymousContainer; } else { thisClass = me.getContainingConcreteClassifier(); } } // Find super class if "self" is "super" if (((SelfReference) me).getSelf() instanceof Super) { if (thisClass instanceof org.emftext.language.java.classifiers.Class) { return ((org.emftext.language.java.classifiers.Class) thisClass).getSuperClass(); } if (thisClass instanceof AnonymousClass) { return ((AnonymousClass)thisClass).getSuperClassifier(); } } return thisClass; } // Element points to the object's class object else if (me instanceof ReflectiveClassReference) { return me.getClassClass(); } // Referenced element points to an element with a type else if (me instanceof ElementReference) { ReferenceableElement target = (ReferenceableElement) ((ElementReference) me).getTarget(); if (target.eIsProxy()) { type = null; } // Navigate through AdditionalLocalVariable or Field if (target instanceof AdditionalLocalVariable) { target = (ReferenceableElement) target.eContainer(); } if (target instanceof AdditionalField) { target = (ReferenceableElement) target.eContainer(); } if (target instanceof TypedElement) { TypeReference typeRef = ((TypedElement) target).getTypeReference(); if (typeRef != null) { type = typeRef.getBoundTarget(me); } } else if (target instanceof Type /*e.g. Annotation*/ ) { return (Type) target; } else if (target instanceof EnumConstant) { type = (Enumeration)target.eContainer(); } } //Strings may also appear as reference else if (me instanceof StringReference) { return me.getStringClass(); } else if (me instanceof NestedExpression) { type = ((NestedExpression) me).getExpression().getType(); } else if (me instanceof PrimitiveTypeReference) { type = ((PrimitiveTypeReference) me).getPrimitiveType(); } else { assert(false); } return type; } }