/******************************************************************************* * Copyright (c) 2000, 2009 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 * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.internal.core; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.jdt.core.CompletionRequestor; import org.eclipse.jdt.core.IAnnotation; import org.eclipse.jdt.core.IClassFile; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.ICompletionRequestor; import org.eclipse.jdt.core.IField; import org.eclipse.jdt.core.IInitializer; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IJavaModelStatusConstants; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IPackageFragment; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.ITypeHierarchy; import org.eclipse.jdt.core.ITypeParameter; import org.eclipse.jdt.core.IWorkingCopy; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.Signature; import org.eclipse.jdt.core.WorkingCopyOwner; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.core.search.SearchEngine; import org.eclipse.jdt.internal.codeassist.CompletionEngine; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation; import org.eclipse.jdt.internal.compiler.env.IBinaryType; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.util.SuffixConstants; import org.eclipse.jdt.internal.core.JavaModelManager.PerProjectInfo; import org.eclipse.jdt.internal.core.hierarchy.TypeHierarchy; import org.eclipse.jdt.internal.core.util.MementoTokenizer; import org.eclipse.jdt.internal.core.util.Messages; import org.eclipse.jdt.internal.core.util.Util; /** * Parent is an IClassFile. * * @see IType */ public class BinaryType extends BinaryMember implements IType, SuffixConstants { private static final IField[] NO_FIELDS= new IField[0]; private static final IMethod[] NO_METHODS= new IMethod[0]; private static final IType[] NO_TYPES= new IType[0]; private static final IInitializer[] NO_INITIALIZERS= new IInitializer[0]; public static final JavadocContents EMPTY_JAVADOC= new JavadocContents(null, org.eclipse.jdt.internal.compiler.util.Util.EMPTY_STRING); protected BinaryType(JavaElement parent, String name) { super(parent, name); } /* * Remove my cached children from the Java Model */ protected void closing(Object info) throws JavaModelException { ClassFileInfo cfi= getClassFileInfo(); cfi.removeBinaryChildren(); } /** * @see IType#codeComplete(char[], int, int, char[][], char[][], int[], boolean, * ICompletionRequestor) * @deprecated */ public void codeComplete(char[] snippet, int insertion, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic, ICompletionRequestor requestor) throws JavaModelException { codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, requestor, DefaultWorkingCopyOwner.PRIMARY); } /** * @see IType#codeComplete(char[], int, int, char[][], char[][], int[], boolean, * ICompletionRequestor, WorkingCopyOwner) * @deprecated */ public void codeComplete(char[] snippet, int insertion, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic, ICompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException { if (requestor == null) { throw new IllegalArgumentException("Completion requestor cannot be null"); //$NON-NLS-1$ } codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, new org.eclipse.jdt.internal.codeassist.CompletionRequestorWrapper( requestor), owner); } /* * @see IType#codeComplete(char[], int, int, char[][], char[][], int[], boolean, ICompletionRequestor) */ public void codeComplete(char[] snippet, int insertion, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic, CompletionRequestor requestor) throws JavaModelException { codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, requestor, DefaultWorkingCopyOwner.PRIMARY); } /* * @see IType#codeComplete(char[], int, int, char[][], char[][], int[], boolean, ICompletionRequestor, IProgressMonitor) */ public void codeComplete(char[] snippet, int insertion, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic, CompletionRequestor requestor, IProgressMonitor monitor) throws JavaModelException { codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, requestor, DefaultWorkingCopyOwner.PRIMARY, monitor); } /* * @see IType#codeComplete(char[], int, int, char[][], char[][], int[], boolean, ICompletionRequestor, WorkingCopyOwner) */ public void codeComplete(char[] snippet, int insertion, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic, CompletionRequestor requestor, WorkingCopyOwner owner) throws JavaModelException { codeComplete(snippet, insertion, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic, requestor, owner, null); } /* * @see IType#codeComplete(char[], int, int, char[][], char[][], int[], boolean, ICompletionRequestor, WorkingCopyOwner, IProgressMonitor) */ public void codeComplete( char[] snippet, int insertion, int position, char[][] localVariableTypeNames, char[][] localVariableNames, int[] localVariableModifiers, boolean isStatic, CompletionRequestor requestor, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException { if (requestor == null) { throw new IllegalArgumentException("Completion requestor cannot be null"); //$NON-NLS-1$ } JavaProject project= (JavaProject)getJavaProject(); SearchableEnvironment environment= project.newSearchableNameEnvironment(owner); CompletionEngine engine= new CompletionEngine(environment, requestor, project.getOptions(true), project, owner, monitor); String source= getClassFile().getSource(); if (source != null && insertion > -1 && insertion < source.length()) { // code complete char[] prefix= CharOperation.concat(source.substring(0, insertion).toCharArray(), new char[] { '{' }); char[] suffix= CharOperation.concat(new char[] { '}' }, source.substring(insertion).toCharArray()); char[] fakeSource= CharOperation.concat(prefix, snippet, suffix); BasicCompilationUnit cu= new BasicCompilationUnit( fakeSource, null, getElementName(), project); // use project to retrieve corresponding .java IFile engine.complete(cu, prefix.length + position, prefix.length, null/*extended context isn't computed*/); } else { engine.complete(this, snippet, position, localVariableTypeNames, localVariableNames, localVariableModifiers, isStatic); } if (NameLookup.VERBOSE) { System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInSourcePackage: " + environment.nameLookup.timeSpentInSeekTypesInSourcePackage + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ System.out.println(Thread.currentThread() + " TIME SPENT in NameLoopkup#seekTypesInBinaryPackage: " + environment.nameLookup.timeSpentInSeekTypesInBinaryPackage + "ms"); //$NON-NLS-1$ //$NON-NLS-2$ } } /* * @see IType#createField(String, IJavaElement, boolean, IProgressMonitor) */ public IField createField(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws JavaModelException { throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this)); } /* * @see IType#createInitializer(String, IJavaElement, IProgressMonitor) */ public IInitializer createInitializer(String contents, IJavaElement sibling, IProgressMonitor monitor) throws JavaModelException { throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this)); } /* * @see IType#createMethod(String, IJavaElement, boolean, IProgressMonitor) */ public IMethod createMethod(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws JavaModelException { throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this)); } /* * @see IType#createType(String, IJavaElement, boolean, IProgressMonitor) */ public IType createType(String contents, IJavaElement sibling, boolean force, IProgressMonitor monitor) throws JavaModelException { throw new JavaModelException(new JavaModelStatus(IJavaModelStatusConstants.READ_ONLY, this)); } public boolean equals(Object o) { if (!(o instanceof BinaryType)) return false; return super.equals(o); } /* * @see IType#findMethods(IMethod) */ public IMethod[] findMethods(IMethod method) { try { return findMethods(method, getMethods()); } catch (JavaModelException e) { // if type doesn't exist, no matching method can exist return null; } } public IAnnotation[] getAnnotations() throws JavaModelException { IBinaryType info= (IBinaryType)getElementInfo(); IBinaryAnnotation[] binaryAnnotations= info.getAnnotations(); return getAnnotations(binaryAnnotations, info.getTagBits()); } /* * @see IParent#getChildren() */ public IJavaElement[] getChildren() throws JavaModelException { ClassFileInfo cfi= getClassFileInfo(); return cfi.binaryChildren; } public IJavaElement[] getChildrenForCategory(String category) throws JavaModelException { IJavaElement[] children= getChildren(); int length= children.length; if (length == 0) return children; SourceMapper mapper= getSourceMapper(); if (mapper != null) { // ensure the class file's buffer is open so that categories are computed ((ClassFile)getClassFile()).getBuffer(); HashMap categories= mapper.categories; IJavaElement[] result= new IJavaElement[length]; int index= 0; if (categories != null) { for (int i= 0; i < length; i++) { IJavaElement child= children[i]; String[] cats= (String[])categories.get(child); if (cats != null) { for (int j= 0, length2= cats.length; j < length2; j++) { if (cats[j].equals(category)) { result[index++]= child; break; } } } } } if (index < length) System.arraycopy(result, 0, result= new IJavaElement[index], 0, index); return result; } return NO_ELEMENTS; } protected ClassFileInfo getClassFileInfo() throws JavaModelException { ClassFile cf= (ClassFile)this.parent; return (ClassFileInfo)cf.getElementInfo(); } /* * @see IMember#getDeclaringType() */ public IType getDeclaringType() { IClassFile classFile= getClassFile(); if (classFile.isOpen()) { try { char[] enclosingTypeName= ((IBinaryType)getElementInfo()).getEnclosingTypeName(); if (enclosingTypeName == null) { return null; } enclosingTypeName= ClassFile.unqualifiedName(enclosingTypeName); // workaround problem with class files compiled with javac 1.1.* // that return a non-null enclosing type name for local types defined in anonymous (e.g. A$1$B) if (classFile.getElementName().length() > enclosingTypeName.length + 1 && Character.isDigit(classFile.getElementName().charAt(enclosingTypeName.length + 1))) { return null; } return getPackageFragment().getClassFile(new String(enclosingTypeName) + SUFFIX_STRING_class).getType(); } catch (JavaModelException npe) { return null; } } else { // cannot access .class file without opening it // and getDeclaringType() is supposed to be a handle-only method, // so default to assuming $ is an enclosing type separator String classFileName= classFile.getElementName(); int lastDollar= -1; for (int i= 0, length= classFileName.length(); i < length; i++) { char c= classFileName.charAt(i); if (Character.isDigit(c) && lastDollar == i - 1) { // anonymous or local type return null; } else if (c == '$') { lastDollar= i; } } if (lastDollar == -1) { return null; } else { String enclosingName= classFileName.substring(0, lastDollar); String enclosingClassFileName= enclosingName + SUFFIX_STRING_class; return new BinaryType( (JavaElement)getPackageFragment().getClassFile(enclosingClassFileName), Util.localTypeName(enclosingName, enclosingName.lastIndexOf('$'), enclosingName.length())); } } } public Object getElementInfo(IProgressMonitor monitor) throws JavaModelException { JavaModelManager manager= JavaModelManager.getJavaModelManager(); Object info= manager.getInfo(this); if (info != null && info != JavaModelCache.NON_EXISTING_JAR_TYPE_INFO) return info; return openWhenClosed(createElementInfo(), monitor); } /* * @see IJavaElement */ public int getElementType() { return TYPE; } /* * @see IType#getField(String name) */ public IField getField(String fieldName) { return new BinaryField(this, fieldName); } /* * @see IType#getFields() */ public IField[] getFields() throws JavaModelException { ArrayList list= getChildrenOfType(FIELD); int size; if ((size= list.size()) == 0) { return NO_FIELDS; } else { IField[] array= new IField[size]; list.toArray(array); return array; } } /* * @see IMember#getFlags() */ public int getFlags() throws JavaModelException { IBinaryType info= (IBinaryType)getElementInfo(); return info.getModifiers() & ~ClassFileConstants.AccSuper; } /* * @see IType#getFullyQualifiedName() */ public String getFullyQualifiedName() { return this.getFullyQualifiedName('$'); } /* * @see IType#getFullyQualifiedName(char enclosingTypeSeparator) */ public String getFullyQualifiedName(char enclosingTypeSeparator) { try { return getFullyQualifiedName(enclosingTypeSeparator, false/*don't show parameters*/); } catch (JavaModelException e) { // exception thrown only when showing parameters return null; } } /* * @see IType#getFullyQualifiedParameterizedName() */ public String getFullyQualifiedParameterizedName() throws JavaModelException { return getFullyQualifiedName('.', true/*show parameters*/); } /* * @see JavaElement */ public IJavaElement getHandleFromMemento(String token, MementoTokenizer memento, WorkingCopyOwner workingCopyOwner) { switch (token.charAt(0)) { case JEM_COUNT: return getHandleUpdatingCountFromMemento(memento, workingCopyOwner); case JEM_FIELD: if (!memento.hasMoreTokens()) return this; String fieldName= memento.nextToken(); JavaElement field= (JavaElement)getField(fieldName); return field.getHandleFromMemento(memento, workingCopyOwner); case JEM_INITIALIZER: if (!memento.hasMoreTokens()) return this; String count= memento.nextToken(); JavaElement initializer= (JavaElement)getInitializer(Integer.parseInt(count)); return initializer.getHandleFromMemento(memento, workingCopyOwner); case JEM_METHOD: if (!memento.hasMoreTokens()) return this; String selector= memento.nextToken(); ArrayList params= new ArrayList(); nextParam: while (memento.hasMoreTokens()) { token= memento.nextToken(); switch (token.charAt(0)) { case JEM_TYPE: case JEM_TYPE_PARAMETER: case JEM_ANNOTATION: break nextParam; case JEM_METHOD: if (!memento.hasMoreTokens()) return this; String param= memento.nextToken(); StringBuffer buffer= new StringBuffer(); while (param.length() == 1 && Signature.C_ARRAY == param.charAt(0)) { // backward compatible with 3.0 mementos buffer.append(Signature.C_ARRAY); if (!memento.hasMoreTokens()) return this; param= memento.nextToken(); } params.add(buffer.toString() + param); break; default: break nextParam; } } String[] parameters= new String[params.size()]; params.toArray(parameters); JavaElement method= (JavaElement)getMethod(selector, parameters); switch (token.charAt(0)) { case JEM_TYPE: case JEM_TYPE_PARAMETER: case JEM_LOCALVARIABLE: case JEM_ANNOTATION: return method.getHandleFromMemento(token, memento, workingCopyOwner); default: return method; } case JEM_TYPE: String typeName; if (memento.hasMoreTokens()) { typeName= memento.nextToken(); char firstChar= typeName.charAt(0); if (firstChar == JEM_FIELD || firstChar == JEM_INITIALIZER || firstChar == JEM_METHOD || firstChar == JEM_TYPE || firstChar == JEM_COUNT) { token= typeName; typeName= ""; //$NON-NLS-1$ } else { token= null; } } else { typeName= ""; //$NON-NLS-1$ token= null; } JavaElement type= (JavaElement)getType(typeName); if (token == null) { return type.getHandleFromMemento(memento, workingCopyOwner); } else { return type.getHandleFromMemento(token, memento, workingCopyOwner); } case JEM_TYPE_PARAMETER: if (!memento.hasMoreTokens()) return this; String typeParameterName= memento.nextToken(); JavaElement typeParameter= new TypeParameter(this, typeParameterName); return typeParameter.getHandleFromMemento(memento, workingCopyOwner); case JEM_ANNOTATION: if (!memento.hasMoreTokens()) return this; String annotationName= memento.nextToken(); JavaElement annotation= new Annotation(this, annotationName); return annotation.getHandleFromMemento(memento, workingCopyOwner); } return null; } /* * @see IType#getInitializer(int occurrenceCount) */ public IInitializer getInitializer(int count) { return new Initializer(this, count); } /* * @see IType#getInitializers() */ public IInitializer[] getInitializers() { return NO_INITIALIZERS; } public String getKey(boolean forceOpen) throws JavaModelException { return getKey(this, forceOpen); } /* * @see IType#getMethod(String name, String[] parameterTypeSignatures) */ public IMethod getMethod(String selector, String[] parameterTypeSignatures) { return new BinaryMethod(this, selector, parameterTypeSignatures); } /* * @see IType#getMethods() */ public IMethod[] getMethods() throws JavaModelException { ArrayList list= getChildrenOfType(METHOD); int size; if ((size= list.size()) == 0) { return NO_METHODS; } else { IMethod[] array= new IMethod[size]; list.toArray(array); return array; } } /* * @see IType#getPackageFragment() */ public IPackageFragment getPackageFragment() { IJavaElement parentElement= this.parent; while (parentElement != null) { if (parentElement.getElementType() == IJavaElement.PACKAGE_FRAGMENT) { return (IPackageFragment)parentElement; } else { parentElement= parentElement.getParent(); } } Assert.isTrue(false); // should not happen return null; } /** * @see IType#getSuperclassTypeSignature() * @since 3.0 */ public String getSuperclassTypeSignature() throws JavaModelException { IBinaryType info= (IBinaryType)getElementInfo(); char[] genericSignature= info.getGenericSignature(); if (genericSignature != null) { int signatureLength= genericSignature.length; // skip type parameters int index= 0; if (genericSignature[0] == '<') { int count= 1; while (count > 0 && ++index < signatureLength) { switch (genericSignature[index]) { case '<': count++; break; case '>': count--; break; } } index++; } int start= index; index= Util.scanClassTypeSignature(genericSignature, start) + 1; char[] superclassSig= CharOperation.subarray(genericSignature, start, index); return new String(ClassFile.translatedName(superclassSig)); } else { char[] superclassName= info.getSuperclassName(); if (superclassName == null) { return null; } return new String(Signature.createTypeSignature(ClassFile.translatedName(superclassName), true)); } } public String getSourceFileName(IBinaryType info) { if (info == null) { try { info= (IBinaryType)getElementInfo(); } catch (JavaModelException e) { // default to using the outer most declaring type name IType type= this; IType enclosingType= getDeclaringType(); while (enclosingType != null) { type= enclosingType; enclosingType= type.getDeclaringType(); } return type.getElementName() + Util.defaultJavaExtension(); } } return sourceFileName(info); } /* * @see IType#getSuperclassName() */ public String getSuperclassName() throws JavaModelException { IBinaryType info= (IBinaryType)getElementInfo(); char[] superclassName= info.getSuperclassName(); if (superclassName == null) { return null; } return new String(ClassFile.translatedName(superclassName)); } /* * @see IType#getSuperInterfaceNames() */ public String[] getSuperInterfaceNames() throws JavaModelException { IBinaryType info= (IBinaryType)getElementInfo(); char[][] names= info.getInterfaceNames(); int length; if (names == null || (length= names.length) == 0) { return CharOperation.NO_STRINGS; } names= ClassFile.translatedNames(names); String[] strings= new String[length]; for (int i= 0; i < length; i++) { strings[i]= new String(names[i]); } return strings; } /** * @see IType#getSuperInterfaceTypeSignatures() * @since 3.0 */ public String[] getSuperInterfaceTypeSignatures() throws JavaModelException { IBinaryType info= (IBinaryType)getElementInfo(); char[] genericSignature= info.getGenericSignature(); if (genericSignature != null) { ArrayList interfaces= new ArrayList(); int signatureLength= genericSignature.length; // skip type parameters int index= 0; if (genericSignature[0] == '<') { int count= 1; while (count > 0 && ++index < signatureLength) { switch (genericSignature[index]) { case '<': count++; break; case '>': count--; break; } } index++; } // skip superclass index= Util.scanClassTypeSignature(genericSignature, index) + 1; while (index < signatureLength) { int start= index; index= Util.scanClassTypeSignature(genericSignature, start) + 1; char[] interfaceSig= CharOperation.subarray(genericSignature, start, index); interfaces.add(new String(ClassFile.translatedName(interfaceSig))); } int size= interfaces.size(); String[] result= new String[size]; interfaces.toArray(result); return result; } else { char[][] names= info.getInterfaceNames(); int length; if (names == null || (length= names.length) == 0) { return CharOperation.NO_STRINGS; } names= ClassFile.translatedNames(names); String[] strings= new String[length]; for (int i= 0; i < length; i++) { strings[i]= new String(Signature.createTypeSignature(names[i], true)); } return strings; } } public ITypeParameter[] getTypeParameters() throws JavaModelException { String[] typeParameterSignatures= getTypeParameterSignatures(); int length= typeParameterSignatures.length; if (length == 0) return TypeParameter.NO_TYPE_PARAMETERS; ITypeParameter[] typeParameters= new ITypeParameter[length]; for (int i= 0; i < typeParameterSignatures.length; i++) { String typeParameterName= Signature.getTypeVariable(typeParameterSignatures[i]); typeParameters[i]= new TypeParameter(this, typeParameterName); } return typeParameters; } /** * @see IType#getTypeParameterSignatures() * @since 3.0 */ public String[] getTypeParameterSignatures() throws JavaModelException { IBinaryType info= (IBinaryType)getElementInfo(); char[] genericSignature= info.getGenericSignature(); if (genericSignature == null) return CharOperation.NO_STRINGS; char[] dotBaseSignature= CharOperation.replaceOnCopy(genericSignature, '/', '.'); char[][] typeParams= Signature.getTypeParameters(dotBaseSignature); return CharOperation.toStrings(typeParams); } /* * @see IType#getType(String) */ public IType getType(String typeName) { IClassFile classFile= getPackageFragment().getClassFile(getTypeQualifiedName() + "$" + typeName + SUFFIX_STRING_class); //$NON-NLS-1$ return new BinaryType((JavaElement)classFile, typeName); } public ITypeParameter getTypeParameter(String typeParameterName) { return new TypeParameter(this, typeParameterName); } /* * @see IType#getTypeQualifiedName() */ public String getTypeQualifiedName() { return this.getTypeQualifiedName('$'); } /* * @see IType#getTypeQualifiedName(char) */ public String getTypeQualifiedName(char enclosingTypeSeparator) { try { return getTypeQualifiedName(enclosingTypeSeparator, false/*don't show parameters*/); } catch (JavaModelException e) { // exception thrown only when showing parameters return null; } } /* * @see IType#getTypes() */ public IType[] getTypes() throws JavaModelException { ArrayList list= getChildrenOfType(TYPE); int size; if ((size= list.size()) == 0) { return NO_TYPES; } else { IType[] array= new IType[size]; list.toArray(array); return array; } } /* * @see IType#isAnonymous() */ public boolean isAnonymous() throws JavaModelException { IBinaryType info= (IBinaryType)getElementInfo(); return info.isAnonymous(); } /* * @see IType#isClass() */ public boolean isClass() throws JavaModelException { IBinaryType info= (IBinaryType)getElementInfo(); return TypeDeclaration.kind(info.getModifiers()) == TypeDeclaration.CLASS_DECL; } /** * @see IType#isEnum() * @since 3.0 */ public boolean isEnum() throws JavaModelException { IBinaryType info= (IBinaryType)getElementInfo(); return TypeDeclaration.kind(info.getModifiers()) == TypeDeclaration.ENUM_DECL; } /* * @see IType#isInterface() */ public boolean isInterface() throws JavaModelException { IBinaryType info= (IBinaryType)getElementInfo(); switch (TypeDeclaration.kind(info.getModifiers())) { case TypeDeclaration.INTERFACE_DECL: case TypeDeclaration.ANNOTATION_TYPE_DECL: // annotation is interface too return true; } return false; } /** * @see IType#isAnnotation() * @since 3.0 */ public boolean isAnnotation() throws JavaModelException { IBinaryType info= (IBinaryType)getElementInfo(); return TypeDeclaration.kind(info.getModifiers()) == TypeDeclaration.ANNOTATION_TYPE_DECL; } /* * @see IType#isLocal() */ public boolean isLocal() throws JavaModelException { IBinaryType info= (IBinaryType)getElementInfo(); return info.isLocal(); } /* * @see IType#isMember() */ public boolean isMember() throws JavaModelException { IBinaryType info= (IBinaryType)getElementInfo(); return info.isMember(); } /* (non-Javadoc) * @see org.eclipse.jdt.core.IType#isResolved() */ public boolean isResolved() { return false; } /* * @see IType */ public ITypeHierarchy loadTypeHierachy(InputStream input, IProgressMonitor monitor) throws JavaModelException { return loadTypeHierachy(input, DefaultWorkingCopyOwner.PRIMARY, monitor); } /* * @see IType */ public ITypeHierarchy loadTypeHierachy(InputStream input, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException { return TypeHierarchy.load(this, input, owner); } /* * @see IType#newSupertypeHierarchy(IProgressMonitor monitor) */ public ITypeHierarchy newSupertypeHierarchy(IProgressMonitor monitor) throws JavaModelException { return this.newSupertypeHierarchy(DefaultWorkingCopyOwner.PRIMARY, monitor); } /* *@see IType#newSupertypeHierarchy(ICompilationUnit[], IProgressMonitor monitor) */ public ITypeHierarchy newSupertypeHierarchy( ICompilationUnit[] workingCopies, IProgressMonitor monitor) throws JavaModelException { CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), false); op.runOperation(monitor); return op.getResult(); } /** * @param workingCopies the working copies that take precedence over their original compilation * units * @param monitor the given progress monitor * @return a type hierarchy for this type containing this type and all of its supertypes * @exception JavaModelException if this element does not exist or if an exception occurs while * accessing its corresponding resource. * * @see IType#newSupertypeHierarchy(IWorkingCopy[], IProgressMonitor) * @deprecated */ public ITypeHierarchy newSupertypeHierarchy( IWorkingCopy[] workingCopies, IProgressMonitor monitor) throws JavaModelException { ICompilationUnit[] copies; if (workingCopies == null) { copies= null; } else { int length= workingCopies.length; System.arraycopy(workingCopies, 0, copies= new ICompilationUnit[length], 0, length); } return newSupertypeHierarchy(copies, monitor); } /* * @see IType#newSupertypeHierarchy(WorkingCopyOwner, IProgressMonitor) */ public ITypeHierarchy newSupertypeHierarchy( WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException { ICompilationUnit[] workingCopies= JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/); CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), false); op.runOperation(monitor); return op.getResult(); } /* * @see IType#newTypeHierarchy(IJavaProject, IProgressMonitor) */ public ITypeHierarchy newTypeHierarchy(IJavaProject project, IProgressMonitor monitor) throws JavaModelException { return newTypeHierarchy(project, DefaultWorkingCopyOwner.PRIMARY, monitor); } /* * @see IType#newTypeHierarchy(IJavaProject, WorkingCopyOwner, IProgressMonitor) */ public ITypeHierarchy newTypeHierarchy(IJavaProject project, WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException { if (project == null) { throw new IllegalArgumentException(Messages.hierarchy_nullProject); } ICompilationUnit[] workingCopies= JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/); ICompilationUnit[] projectWCs= null; if (workingCopies != null) { int length= workingCopies.length; projectWCs= new ICompilationUnit[length]; int index= 0; for (int i= 0; i < length; i++) { ICompilationUnit wc= workingCopies[i]; if (project.equals(wc.getJavaProject())) { projectWCs[index++]= wc; } } if (index != length) { System.arraycopy(projectWCs, 0, projectWCs= new ICompilationUnit[index], 0, index); } } CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation( this, projectWCs, project, true); op.runOperation(monitor); return op.getResult(); } /** * @param monitor the given progress monitor * @exception JavaModelException if this element does not exist or if an exception occurs while * accessing its corresponding resource. * @return a type hierarchy for this type containing * * @see IType#newTypeHierarchy(IProgressMonitor monitor) * @deprecated */ public ITypeHierarchy newTypeHierarchy(IProgressMonitor monitor) throws JavaModelException { // https://bugs.eclipse.org/bugs/show_bug.cgi?id=228845, consider any // changes that may exist on primary working copies. return newTypeHierarchy(DefaultWorkingCopyOwner.PRIMARY, monitor); } /* * @see IType#newTypeHierarchy(ICompilationUnit[], IProgressMonitor) */ public ITypeHierarchy newTypeHierarchy( ICompilationUnit[] workingCopies, IProgressMonitor monitor) throws JavaModelException { CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), true); op.runOperation(monitor); return op.getResult(); } /** * @see IType#newTypeHierarchy(IWorkingCopy[], IProgressMonitor) * @deprecated */ public ITypeHierarchy newTypeHierarchy( IWorkingCopy[] workingCopies, IProgressMonitor monitor) throws JavaModelException { ICompilationUnit[] copies; if (workingCopies == null) { copies= null; } else { int length= workingCopies.length; System.arraycopy(workingCopies, 0, copies= new ICompilationUnit[length], 0, length); } return newTypeHierarchy(copies, monitor); } /* * @see IType#newTypeHierarchy(WorkingCopyOwner, IProgressMonitor) */ public ITypeHierarchy newTypeHierarchy( WorkingCopyOwner owner, IProgressMonitor monitor) throws JavaModelException { ICompilationUnit[] workingCopies= JavaModelManager.getJavaModelManager().getWorkingCopies(owner, true/*add primary working copies*/); CreateTypeHierarchyOperation op= new CreateTypeHierarchyOperation(this, workingCopies, SearchEngine.createWorkspaceScope(), true); op.runOperation(monitor); return op.getResult(); } public JavaElement resolved(Binding binding) { SourceRefElement resolvedHandle= new ResolvedBinaryType(this.parent, this.name, new String(binding.computeUniqueKey())); resolvedHandle.occurrenceCount= this.occurrenceCount; return resolvedHandle; } /* * Returns the source file name as defined in the given info. * If not present in the info, infers it from this type. */ public String sourceFileName(IBinaryType info) { char[] sourceFileName= info.sourceFileName(); if (sourceFileName == null) { /* * We assume that this type has been compiled from a file with its name * For example, A.class comes from A.java and p.A.class comes from a file A.java * in the folder p. */ if (info.isMember()) { IType enclosingType= getDeclaringType(); if (enclosingType == null) return null; // play it safe while (enclosingType.getDeclaringType() != null) { enclosingType= enclosingType.getDeclaringType(); } return enclosingType.getElementName() + Util.defaultJavaExtension(); } else if (info.isLocal() || info.isAnonymous()) { String typeQualifiedName= getTypeQualifiedName(); int dollar= typeQualifiedName.indexOf('$'); if (dollar == -1) { // malformed inner type: name doesn't contain a dollar return getElementName() + Util.defaultJavaExtension(); } return typeQualifiedName.substring(0, dollar) + Util.defaultJavaExtension(); } else { return getElementName() + Util.defaultJavaExtension(); } } else { int index= CharOperation.lastIndexOf('/', sourceFileName); return new String(sourceFileName, index + 1, sourceFileName.length - index - 1); } } /* * @private Debugging purposes */ protected void toStringInfo(int tab, StringBuffer buffer, Object info, boolean showResolvedInfo) { buffer.append(tabString(tab)); if (info == null) { toStringName(buffer); buffer.append(" (not open)"); //$NON-NLS-1$ } else if (info == NO_INFO) { toStringName(buffer); } else { try { if (isAnnotation()) { buffer.append("@interface "); //$NON-NLS-1$ } else if (isEnum()) { buffer.append("enum "); //$NON-NLS-1$ } else if (isInterface()) { buffer.append("interface "); //$NON-NLS-1$ } else { buffer.append("class "); //$NON-NLS-1$ } toStringName(buffer); } catch (JavaModelException e) { buffer.append("<JavaModelException in toString of " + getElementName()); //$NON-NLS-1$ } } } protected void toStringName(StringBuffer buffer) { if (getElementName().length() > 0) super.toStringName(buffer); else buffer.append("<anonymous>"); //$NON-NLS-1$ } public String getAttachedJavadoc(IProgressMonitor monitor) throws JavaModelException { JavadocContents javadocContents= getJavadocContents(monitor); if (javadocContents == null) return null; return javadocContents.getTypeDoc(); } public JavadocContents getJavadocContents(IProgressMonitor monitor) throws JavaModelException { PerProjectInfo projectInfo= JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(getJavaProject().getProject()); JavadocContents cachedJavadoc= null; synchronized (projectInfo.javadocCache) { cachedJavadoc= (JavadocContents)projectInfo.javadocCache.get(this); } if (cachedJavadoc != null && cachedJavadoc != EMPTY_JAVADOC) { return cachedJavadoc; } URL baseLocation= getJavadocBaseLocation(); if (baseLocation == null) { return null; } StringBuffer pathBuffer= new StringBuffer(baseLocation.toExternalForm()); if (!(pathBuffer.charAt(pathBuffer.length() - 1) == '/')) { pathBuffer.append('/'); } IPackageFragment pack= getPackageFragment(); String typeQualifiedName= null; if (isMember()) { IType currentType= this; StringBuffer typeName= new StringBuffer(); while (currentType != null) { typeName.insert(0, currentType.getElementName()); currentType= currentType.getDeclaringType(); if (currentType != null) { typeName.insert(0, '.'); } } typeQualifiedName= new String(typeName.toString()); } else { typeQualifiedName= getElementName(); } pathBuffer.append(pack.getElementName().replace('.', '/')).append('/').append(typeQualifiedName).append(JavadocConstants.HTML_EXTENSION); if (monitor != null && monitor.isCanceled()) throw new OperationCanceledException(); final String contents= getURLContents(String.valueOf(pathBuffer)); JavadocContents javadocContents= new JavadocContents(this, contents); synchronized (projectInfo.javadocCache) { projectInfo.javadocCache.put(this, javadocContents); } return javadocContents; } }