| /******************************************************************************* |
| * Copyright (c) 2000, 2006 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 |
| * $Id: MethodMapping.java 23401 2010-02-02 23:56:05Z stephan $ |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| * Fraunhofer FIRST - extended API and implementation |
| * Technical University Berlin - extended API and implementation |
| *******************************************************************************/ |
| package org.eclipse.objectteams.otdt.internal.core; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.jdt.core.IBuffer; |
| import org.eclipse.jdt.core.IClassFile; |
| import org.eclipse.jdt.core.ICompilationUnit; |
| import org.eclipse.jdt.core.IJavaElement; |
| import org.eclipse.jdt.core.IMember; |
| import org.eclipse.jdt.core.IMethod; |
| import org.eclipse.jdt.core.IOpenable; |
| import org.eclipse.jdt.core.ISourceRange; |
| import org.eclipse.jdt.core.ISourceReference; |
| import org.eclipse.jdt.core.IType; |
| import org.eclipse.jdt.core.ITypeHierarchy; |
| import org.eclipse.jdt.core.ITypeParameter; |
| import org.eclipse.jdt.core.ITypeRoot; |
| import org.eclipse.jdt.core.JavaModelException; |
| import org.eclipse.jdt.core.Signature; |
| import org.eclipse.jdt.core.SourceRange; |
| import org.eclipse.jdt.core.ToolFactory; |
| import org.eclipse.jdt.core.compiler.CharOperation; |
| import org.eclipse.jdt.core.compiler.IScanner; |
| import org.eclipse.jdt.core.compiler.ITerminalSymbols; |
| import org.eclipse.jdt.core.compiler.InvalidInputException; |
| import org.eclipse.jdt.internal.compiler.lookup.Binding; |
| import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; |
| import org.eclipse.jdt.internal.core.JavaElement; |
| import org.eclipse.jdt.internal.core.SourceMethod; |
| import org.eclipse.jdt.internal.core.SourceType; |
| import org.eclipse.jdt.internal.core.SourceTypeElementInfo; |
| import org.eclipse.jdt.internal.core.TypeParameter; |
| import org.eclipse.jdt.internal.core.util.MementoTokenizer; |
| import org.eclipse.jdt.internal.core.util.Util; |
| import org.eclipse.objectteams.otdt.core.IMethodMapping; |
| import org.eclipse.objectteams.otdt.core.IMethodSpec; |
| import org.eclipse.objectteams.otdt.core.IOTJavaElement; |
| import org.eclipse.objectteams.otdt.core.IOTType; |
| import org.eclipse.objectteams.otdt.core.IRoleType; |
| import org.eclipse.objectteams.otdt.core.OTModelManager; |
| import org.eclipse.objectteams.otdt.core.TypeHelper; |
| import org.eclipse.objectteams.otdt.internal.core.util.MethodData; |
| |
| |
| /** |
| * OT_COPY_PASTE from Member.getCategories() |
| * from Member.getJavadocRange() |
| * from SourceRefElement.getOpenableParent() |
| * |
| * Generic Method Mapping, needs to be subclassed to add missing behaviour |
| * for IMethodMapping.getMappingKind() |
| * |
| * @author jwloka |
| */ |
| public abstract class MethodMapping extends OTJavaElement implements IMethodMapping |
| { |
| protected static final String[] EMPTY_STRING_ARRAY = new String[0]; |
| protected static final ITypeParameter[] NO_TYPE_PARAMETERS = new ITypeParameter[0]; |
| |
| private int declarationSourceStart; |
| private int sourceStart; |
| private int sourceEnd; |
| private int declarationSourceEnd; |
| private IMethod roleMethod; |
| protected MethodData roleMethodHandle; |
| private boolean hasSignature; |
| |
| public MethodMapping(int declarationSourceStart, |
| int sourceStart, |
| int sourceEnd, |
| int declarationSourceEnd, |
| int type, |
| IMethod correspondingJavaElem, |
| IType parent, |
| MethodData roleMethodHandle, |
| boolean hasSignature) |
| { |
| super(type, correspondingJavaElem, parent); |
| this.roleMethodHandle = roleMethodHandle; |
| this.declarationSourceStart = declarationSourceStart; |
| this.sourceStart = sourceStart; |
| this.sourceEnd = sourceEnd; |
| this.declarationSourceEnd = declarationSourceEnd; |
| this.hasSignature = hasSignature; |
| } |
| |
| public MethodMapping(int declarationSourceStart, |
| int sourceStart, |
| int sourceEnd, |
| int declarationSourceEnd, |
| int type, |
| IMethod correspondingJavaElem, |
| IType parent, |
| MethodData roleMethodHandle, |
| boolean hasSignature, |
| boolean addAsChild) |
| { |
| super(type, correspondingJavaElem, parent, addAsChild); |
| this.roleMethodHandle = roleMethodHandle; |
| this.declarationSourceStart = declarationSourceStart; |
| this.sourceStart = sourceStart; |
| this.sourceEnd = sourceEnd; |
| this.declarationSourceEnd = declarationSourceEnd; |
| this.hasSignature = hasSignature; |
| } |
| |
| // ==== memento generation: ==== |
| @Override |
| public String getHandleIdentifier() { |
| StringBuffer buff = new StringBuffer(); |
| IJavaElement myParent = getParent(); |
| if (myParent instanceof IOTJavaElement) |
| myParent = ((IOTJavaElement)myParent).getCorrespondingJavaElement(); |
| // prefix |
| buff.append(((JavaElement)myParent).getHandleMemento()); |
| char delimiter = OTJavaElement.OTEM_METHODMAPPING; |
| // start: |
| buff.append(delimiter); |
| // mapping kind: |
| buff.append(getMappingKindChar()); |
| // long or short? |
| buff.append(this.hasSignature ? 'l' : 's'); |
| buff.append(delimiter); |
| // mapping name (if any); |
| getNameForHandle(buff); |
| // role method: |
| getMethodForHandle(this.roleMethodHandle, buff); |
| // base methods: |
| getBaseMethodsForHandle(buff); |
| buff.append(delimiter); |
| return buff.toString(); |
| } |
| protected void getNameForHandle(StringBuffer buff) { /* default: mapping has no name. */ } |
| /** |
| * Answer a char encoding the mapping kind with this information: |
| * callin: a=after, b=before, r=replace; |
| * callout: o=regular, g=getter, s=setter [capital=isOverride]. |
| */ |
| abstract protected char getMappingKindChar(); |
| abstract protected void getBaseMethodsForHandle(StringBuffer buff); |
| |
| protected void getMethodForHandle(IMethodSpec method, StringBuffer buff) { |
| escapeMementoName(buff, method.getSelector()); |
| if (this.hasSignature) { |
| for (String argType : method.getArgumentTypes()) { |
| buff.append(JavaElement.JEM_METHOD); |
| escapeMementoName(buff, argType); |
| } |
| buff.append(JavaElement.JEM_METHOD); |
| escapeMementoName(buff, method.getReturnType()); |
| } |
| buff.append(OTJavaElement.OTEM_METHODMAPPING); |
| } |
| // ==== retreive method spec from memento: === |
| public static MethodData createMethodData(MementoTokenizer memento, String selector) { |
| String cur = memento.nextToken(); |
| if (cur.charAt(0) == JavaElement.JEM_METHOD) |
| cur = memento.nextToken(); // skip initial separator |
| List<String> argTypes = new ArrayList<String>(); |
| while (cur.charAt(0) != OTJavaElement.OTEM_METHODMAPPING) { |
| StringBuffer buffer = new StringBuffer(); |
| while (cur.length() == 1 && Signature.C_ARRAY == cur.charAt(0)) { // backward compatible with 3.0 mementos |
| buffer.append(Signature.C_ARRAY); |
| if (!memento.hasMoreTokens()) |
| break; |
| cur = memento.nextToken(); |
| } |
| buffer.append(cur); |
| argTypes.add(buffer.toString()); |
| if (memento.nextToken().charAt(0) != JavaElement.JEM_METHOD) |
| break; |
| cur = memento.nextToken(); |
| } |
| String returnType = null; |
| if (argTypes.size() > 0) |
| returnType = argTypes.remove(argTypes.size()-1); |
| return new MethodData(selector, argTypes.toArray(new String[argTypes.size()]), null, returnType, false); |
| } |
| // ==== |
| |
| public IMethod getRoleMethod() |
| { |
| if (this.roleMethod == null) |
| { |
| try |
| { |
| this.roleMethod = findRoleMethod(); |
| assert (this.roleMethod != null); |
| } |
| catch (JavaModelException ex) |
| { |
| Util.log(ex, "Failed to lookup original role method element!"); //$NON-NLS-1$ |
| } |
| } |
| |
| return this.roleMethod; |
| } |
| |
| // added for the SourceTypeConverter |
| public MethodData getRoleMethodHandle() |
| { |
| return this.roleMethodHandle; |
| } |
| |
| public IMethod getRoleMethodThrowingException() throws JavaModelException |
| { |
| if (this.roleMethod == null) |
| { |
| this.roleMethod = findRoleMethod(); |
| } |
| |
| return this.roleMethod; |
| } |
| |
| public void setRoleMethod(IMethod meth) |
| { |
| this.roleMethod = meth; |
| } |
| |
| public IType getRoleClass() |
| { |
| // TODO(jwl): simplify later |
| IOTType owningType = (IOTType)getParent(); |
| |
| return (IType)owningType.getCorrespondingJavaElement(); |
| } |
| |
| /** |
| * Only returns the role-methods part -- subclasses must override and |
| * construct the whole element name! |
| */ |
| public String getElementName() |
| { |
| if (this.hasSignature) |
| { |
| return this.roleMethodHandle.toString(); |
| } |
| |
| return this.roleMethodHandle.getSelector(); |
| } |
| |
| public int getDeclarationSourceStart() |
| { |
| return this.declarationSourceStart; |
| } |
| |
| public int getSourceStart() |
| { |
| return this.sourceStart; |
| } |
| |
| public int getSourceEnd() |
| { |
| return this.sourceEnd; |
| } |
| |
| public int getDeclarationSourceEnd() |
| { |
| return this.declarationSourceEnd; |
| } |
| |
| public boolean equals(Object obj) |
| { |
| MethodMapping other = (MethodMapping)obj; |
| |
| return super.equals(other) |
| // && declarationSourceStart == other.getDeclarationSourceStart() |
| // && _declarationSourceEnd == other.getDeclarationSourceEnd() |
| && getElementName().equals(other.getElementName()); |
| } |
| |
| @SuppressWarnings("nls") |
| public String toString() |
| { |
| return "methodmapping: " + getElementName(); |
| } |
| |
| /** |
| * Tries to find JavaElement method on demand for a given method from |
| * current binding. Lookup is using role hierarchy (implicit and explicit). |
| */ |
| protected IMethod findRoleMethod() throws JavaModelException |
| { |
| IType[] implicitParents = TypeHelper.getImplicitSuperTypes((IRoleType)getParent()); |
| HashSet<IType> allParents = new HashSet<IType>(); |
| |
| // collect all parents in role type hierarchy |
| for (int idx = 0; idx < implicitParents.length; idx++) |
| { |
| IType elem = implicitParents[idx]; |
| |
| // build super class hierarchy for element |
| ITypeHierarchy hierarchy = |
| elem.newSupertypeHierarchy( new NullProgressMonitor() ); |
| IType[] superTypes = hierarchy.getAllSuperclasses(elem); |
| |
| // add implicit parent... |
| allParents.add(elem); |
| // ...and all "extends" parents |
| if (superTypes.length > 0) |
| { |
| allParents.addAll(Arrays.asList(superTypes)); |
| } |
| } |
| return findMethod(allParents.toArray(new IType[allParents.size()]), |
| this.roleMethodHandle); |
| } |
| |
| /** |
| * Tries to find an IMethod matching the given methodHandle in a set |
| * of types. |
| * @return the first matching IMethod in the set of types or null if |
| * nothing found |
| */ |
| protected IMethod findMethod(IType[] types, IMethodSpec methodHandle) |
| throws JavaModelException |
| { |
| // cycle through types... |
| for (int parIdx = 0; parIdx < types.length; parIdx++) |
| { |
| IMethod[] methods = types[parIdx].getMethods(); |
| // ... and compare with each method defined in current type |
| for (int methIdx = 0; methIdx < methods.length; methIdx++) |
| { |
| IMethod tmpMethod = methods[methIdx]; |
| // check for equal method name and signature |
| String selector = tmpMethod.getElementName(); |
| if (isEqualMethod(methodHandle, tmpMethod, selector)) |
| // return immediately on first match |
| return tmpMethod; |
| } |
| IOTType otType = OTModelManager.getOTElement(types[parIdx]); |
| if (otType != null && otType.isRole()) { |
| for (IMethodMapping mapping : ((IRoleType)otType).getMethodMappings(IRoleType.CALLOUTS)) { |
| AbstractCalloutMapping tmpMethod = (AbstractCalloutMapping)mapping; |
| if (tmpMethod == this) |
| continue; // callout fakes its own role method, but don't take it for real here! |
| // check for equal method name and signature |
| String selector = tmpMethod.getCorrespondingJavaElement().getElementName(); |
| if (isEqualMethod(methodHandle, tmpMethod, selector)) |
| // return immediately on first match |
| return tmpMethod; |
| } |
| } |
| } |
| IMethod methodReference= SourceMethod.createHandle((JavaElement)types[0], methodHandle); |
| // failure might be due to mismatching qualified/simple types |
| // this variant only uses the simple types: |
| for (int parIdx = 0; parIdx < types.length; parIdx++) { |
| IMethod[] methods= types[parIdx].findMethods(methodReference); |
| if (methods != null && methods.length == 1) |
| return methods[0]; |
| } |
| return null; |
| } |
| |
| // helper for above to generalize over real methods and callouts: |
| private boolean isEqualMethod(IMethodSpec baseMethodHandle, IMethod foundMethodOrCallout, String foundSelector) { |
| if (!foundSelector.equals(baseMethodHandle.getSelector())) |
| return false; |
| if (!baseMethodHandle.hasSignature()) |
| return true; |
| return Util.equalArraysOrNull(foundMethodOrCallout.getParameterTypes(), baseMethodHandle.getArgumentTypes()); |
| } |
| |
| //{OT_COPY_PASTE: SourceRefElement, STATE: 3.4 M7 |
| /** |
| * Return the first instance of IOpenable in the hierarchy of this |
| * type (going up the hierarchy from this type); |
| */ |
| public IOpenable getOpenableParent() |
| { |
| IJavaElement current = getParent(); |
| while (current != null){ |
| if (current instanceof IOpenable) |
| { |
| return (IOpenable) current; |
| } |
| //{ObjectTeams : Teams have no parents in the ot-hierarchy. |
| if(current.getElementType() == IOTJavaElement.TEAM) |
| { |
| IOTType otElement = (IOTType) current; |
| current = otElement.getCorrespondingJavaElement(); |
| } |
| //haebor} |
| current = current.getParent(); |
| } |
| return null; |
| } |
| |
| //{OTModelUpdate : many of this methods shouldn't be delegated |
| // to the corresponding method. Started with these three. |
| // public String getSource() throws JavaModelException |
| // { |
| // return getIMethod().getSource(); |
| // } |
| // |
| // public ISourceRange getSourceRange() throws JavaModelException |
| // { |
| // return getIMethod().getSourceRange(); |
| // } |
| // public ISourceRange getNameRange() throws JavaModelException |
| // { |
| // return getIMethod().getNameRange(); |
| // } |
| |
| //haebor} |
| /** |
| * @see ISourceReference |
| */ |
| public String getSource() throws JavaModelException |
| { |
| IOpenable openable = getOpenableParent(); |
| IBuffer buffer = openable.getBuffer(); |
| if (buffer == null) |
| { |
| return null; |
| } |
| ISourceRange range = getSourceRange(); |
| int offset = range.getOffset(); |
| int length = range.getLength(); |
| if (offset == -1 || length == 0 ) |
| { |
| return null; |
| } |
| try |
| { |
| return buffer.getText(offset, length); |
| } |
| catch(RuntimeException ex) |
| { |
| return null; |
| } |
| } |
| /** |
| * @see ISourceReference |
| */ |
| public ISourceRange getSourceRange() throws JavaModelException |
| { |
| //{ObjectTeams: we don't have an ElementInfo but we know sourcestart, sourceend |
| return new SourceRange(this.declarationSourceStart, this.declarationSourceEnd - this.declarationSourceStart + 1); |
| //haebor} |
| //orig: |
| // SourceRefElementInfo info = (SourceRefElementInfo) getElementInfo(); |
| // return info.getSourceRange(); |
| } |
| |
| //haebor} |
| public ISourceRange getNameRange() throws JavaModelException |
| { |
| ISourceRange range = new SourceRange(this.sourceStart, this.sourceEnd-this.sourceStart+1); |
| return range; |
| } |
| /** Answer the name that represents this mapping. */ |
| protected String getSourceName() { |
| return super.getElementName(); |
| } |
| |
| //delegates |
| IMethod getIMethod() |
| { |
| return (IMethod) getCorrespondingJavaElement(); |
| } |
| |
| public String[] getExceptionTypes() throws JavaModelException |
| { |
| return getIMethod().getExceptionTypes(); |
| } |
| |
| /** |
| * @deprecated (cf. IMethod.getTypeParameterSignatures()) |
| */ |
| public String[] getTypeParameterSignatures() throws JavaModelException |
| { |
| return getIMethod().getTypeParameterSignatures(); |
| } |
| |
| public int getNumberOfParameters() |
| { |
| return getIMethod().getNumberOfParameters(); |
| } |
| |
| public String[] getParameterNames() throws JavaModelException |
| { |
| if ( this.roleMethodHandle != null |
| && this.roleMethodHandle.hasSignature()) |
| return this.roleMethodHandle.getArgumentNames(); |
| return getIMethod().getParameterNames(); |
| } |
| |
| public String[] getParameterTypes() |
| { |
| return getIMethod().getParameterTypes(); |
| } |
| |
| public String getReturnType() throws JavaModelException |
| { |
| if ( this.roleMethodHandle != null |
| && this.roleMethodHandle.hasSignature()) |
| return this.roleMethodHandle.getReturnType(); |
| return getIMethod().getReturnType(); |
| } |
| |
| public String getSignature() throws JavaModelException |
| { |
| return getIMethod().getSignature(); |
| } |
| |
| public boolean isConstructor() throws JavaModelException |
| { |
| return getIMethod().isConstructor(); |
| } |
| |
| public boolean isMainMethod() throws JavaModelException |
| { |
| return getIMethod().isMainMethod(); |
| } |
| |
| public boolean isSimilar(IMethod method) |
| { |
| return getIMethod().isSimilar(method); |
| } |
| |
| public IClassFile getClassFile() |
| { |
| return getIMethod().getClassFile(); |
| } |
| |
| public ICompilationUnit getCompilationUnit() |
| { |
| return getIMethod().getCompilationUnit(); |
| } |
| |
| public IType getDeclaringType() |
| { |
| return getIMethod().getDeclaringType(); |
| } |
| |
| public int getFlags() throws JavaModelException |
| { |
| return 0; // SH: method mappings have no regular flags. orig: getIMethod().getFlags(); |
| } |
| |
| public IType getType(String name, int count) |
| { |
| return getIMethod().getType(name, count); |
| } |
| |
| public boolean isBinary() |
| { |
| return getIMethod().isBinary(); |
| } |
| public void copy(IJavaElement container, IJavaElement sibling, String rename, boolean replace, IProgressMonitor monitor) throws JavaModelException |
| { |
| getIMethod().copy(container, sibling, rename, replace, monitor); |
| } |
| |
| public void delete(boolean force, IProgressMonitor monitor) throws JavaModelException |
| { |
| getIMethod().delete(force, monitor); |
| } |
| |
| public void move(IJavaElement container, IJavaElement sibling, String rename, boolean replace, IProgressMonitor monitor) throws JavaModelException |
| { |
| getIMethod().move(container, sibling, rename, replace, monitor); |
| } |
| |
| public void rename(String name, boolean replace, IProgressMonitor monitor) throws JavaModelException |
| { |
| getIMethod().rename(name, replace, monitor); |
| } |
| |
| public boolean hasSignature() |
| { |
| return this.hasSignature; |
| } |
| |
| public boolean exists() |
| { |
| IJavaElement myParent = getParent(); |
| if (!myParent.exists()) |
| return false; |
| try { |
| for (IJavaElement child : ((IType)myParent).getChildren()) |
| if (this.equals(child)) { |
| // side-effect: fetch source range: |
| if (this != child && this.declarationSourceStart == 0) { |
| MethodMapping other = (MethodMapping) child; |
| this.declarationSourceStart = other.declarationSourceStart; |
| this.declarationSourceEnd = other.declarationSourceEnd; |
| this.sourceStart = other.sourceStart; |
| this.sourceEnd = other.sourceEnd; |
| } |
| return true; |
| } |
| } catch (JavaModelException e) { /* nop, will return false */ } |
| return false; |
| } |
| |
| public boolean isStructureKnown() throws JavaModelException |
| { |
| // See exists() |
| return getParent().isStructureKnown(); |
| } |
| |
| public String getKey() { |
| // km: perhaps: calculating own key would be better |
| return getIMethod().getKey(); |
| } |
| |
| public ITypeParameter[] getTypeParameters() throws JavaModelException { |
| return NO_TYPE_PARAMETERS; // must not return null! |
| } |
| |
| public String[] getRawParameterNames() throws JavaModelException { |
| return EMPTY_STRING_ARRAY; |
| } |
| |
| public ITypeParameter getTypeParameter(String name) { |
| return new TypeParameter((JavaElement) getCorrespondingJavaElement(), name); |
| } |
| |
| public boolean isResolved() { |
| return false; |
| } |
| |
| public String getAttachedJavadoc(IProgressMonitor monitor) throws JavaModelException { |
| return null; |
| } |
| |
| //OT_COPY_PASTE from Member.getCategories(). STATE: 3.4 M7, checked at 3.5 M7 |
| @SuppressWarnings("rawtypes") |
| public String[] getCategories() throws JavaModelException { |
| IType type = (IType) getAncestor(IJavaElement.TYPE); |
| if (type == null) return CharOperation.NO_STRINGS; |
| if (type.isBinary()) { |
| return CharOperation.NO_STRINGS; |
| } else { |
| SourceTypeElementInfo info = (SourceTypeElementInfo) ((SourceType) type).getElementInfo(); |
| HashMap map = info.getCategories(); |
| if (map == null) return CharOperation.NO_STRINGS; |
| String[] categories = (String[]) map.get(this); |
| if (categories == null) return CharOperation.NO_STRINGS; |
| return categories; |
| } |
| } |
| |
| //OT_COPY_PASTE from Member.getJavadocRange(). STATE: 3.4 M7 |
| public ISourceRange getJavadocRange() throws JavaModelException { |
| ISourceRange range= this.getSourceRange(); |
| if (range == null) return null; |
| IBuffer buf= null; |
| if (this.isBinary()) { |
| buf = this.getClassFile().getBuffer(); |
| } else { |
| ICompilationUnit compilationUnit = this.getCompilationUnit(); |
| if (!compilationUnit.isConsistent()) { |
| return null; |
| } |
| buf = compilationUnit.getBuffer(); |
| } |
| final int start= range.getOffset(); |
| final int length= range.getLength(); |
| if (length > 0 && buf.getChar(start) == '/') { |
| IScanner scanner= ToolFactory.createScanner(true, false, false, false); |
| scanner.setSource(buf.getText(start, length).toCharArray()); |
| try { |
| int docOffset= -1; |
| int docEnd= -1; |
| |
| int terminal= scanner.getNextToken(); |
| loop: while (true) { |
| switch(terminal) { |
| case ITerminalSymbols.TokenNameCOMMENT_JAVADOC : |
| docOffset= scanner.getCurrentTokenStartPosition(); |
| docEnd= scanner.getCurrentTokenEndPosition() + 1; |
| terminal= scanner.getNextToken(); |
| break; |
| case ITerminalSymbols.TokenNameCOMMENT_LINE : |
| case ITerminalSymbols.TokenNameCOMMENT_BLOCK : |
| terminal= scanner.getNextToken(); |
| continue loop; |
| default : |
| break loop; |
| } |
| } |
| if (docOffset != -1) { |
| return new SourceRange(docOffset + start, docEnd - docOffset + 1); |
| } |
| } catch (InvalidInputException ex) { |
| // try if there is inherited Javadoc |
| } |
| } |
| return null; |
| } |
| |
| //{CRIPPLE: |
| public int getOccurrenceCount() { |
| // TODO Auto-generated method stub |
| return 0; |
| } |
| // km} |
| |
| @Override |
| public IJavaElement getParent() { |
| // the parent of a method mapping must be a role. |
| IJavaElement myParent = super.getParent(); |
| if (myParent instanceof IRoleType) |
| return myParent; |
| return OTModelManager.getOTElement((IType)myParent); |
| } |
| |
| /** |
| * Copied from Member. |
| * @see IMember#getTypeRoot() |
| */ |
| public ITypeRoot getTypeRoot() { |
| IJavaElement element = getParent(); |
| while (element instanceof IMember) { |
| element= element.getParent(); |
| } |
| return (ITypeRoot) element; |
| } |
| |
| public OTJavaElement resolved(Binding binding) { |
| char[] uniqueKey = binding.computeUniqueKey(); |
| if (uniqueKey == null) |
| throw new AbortCompilation(); // better than NPE below |
| return resolved(uniqueKey); |
| } |
| |
| public abstract OTJavaElement resolved(char[] uniqueKey); |
| |
| @Override |
| protected char getHandleMementoDelimiter() { |
| return OTEM_METHODMAPPING; |
| } |
| } |