private static void appendMethodReference(IMethod meth, StringBuffer buf) throws JavaModelException { buf.append(meth.getElementName()); /* * The Javadoc tool for Java SE 8 changed the anchor syntax and now tries to avoid "strange" characters in URLs. * This breaks all clients that directly create such URLs. * We can't know what format is required, so we just guess by the project's compiler compliance. */ boolean is18OrHigher = JavaModelUtil.is18OrHigher(meth.getJavaProject()); buf.append(is18OrHigher ? '-' : '('); String[] params = meth.getParameterTypes(); IType declaringType = meth.getDeclaringType(); boolean isVararg = Flags.isVarargs(meth.getFlags()); int lastParam = params.length - 1; for (int i = 0; i <= lastParam; i++) { if (i != 0) { buf.append(is18OrHigher ? "-" : ", "); // $NON-NLS-1$ //$NON-NLS-2$ } String curr = Signature.getTypeErasure(params[i]); String fullName = JavaModelUtil.getResolvedTypeName(curr, declaringType); if (fullName == null) { // e.g. a type parameter "QE;" fullName = Signature.toString(Signature.getElementType(curr)); } if (fullName != null) { buf.append(fullName); int dim = Signature.getArrayCount(curr); if (i == lastParam && isVararg) { dim--; } while (dim > 0) { buf.append(is18OrHigher ? ":A" : "[]"); // $NON-NLS-1$ //$NON-NLS-2$ dim--; } if (i == lastParam && isVararg) { buf.append("..."); // $NON-NLS-1$ } } } buf.append(is18OrHigher ? '-' : ')'); }
/** * Resolves a type name in the context of the declaring type. * * @param refTypeSig the type name in signature notation (for example 'QVector') this can also * be an array type, but dimensions will be ignored. * @param declaringType the context for resolving (type where the reference was made in) * @return returns the fully qualified type name or build-in-type name. if a unresolved type * couldn't be resolved null is returned * @throws JavaModelException thrown when the type can not be accessed */ public IType resolveType(String refTypeSig, IType declaringType) throws JavaModelException { IJavaProject javaProject = declaringType.getJavaProject(); int arrayCount = Signature.getArrayCount(refTypeSig); char type = refTypeSig.charAt(arrayCount); if (type == Signature.C_UNRESOLVED) { String name = ""; // $NON-NLS-1$ int bracket = refTypeSig.indexOf(Signature.C_GENERIC_START, arrayCount + 1); if (bracket > 0) name = refTypeSig.substring(arrayCount + 1, bracket); else { int semi = refTypeSig.indexOf(Signature.C_SEMICOLON, arrayCount + 1); if (semi == -1) { throw new IllegalArgumentException(); } name = refTypeSig.substring(arrayCount + 1, semi); } String dotTypeName = "." + name; String dotBaseTypeName = null; String dotExtensionTypeName = null; int dotIndex = name.indexOf('.'); if (dotIndex != -1) { // We might get a fully qualified type name -- Qcom.apple.jingle.eo.MZProgramNodeType; IType resolvedType = javaProject.findType(name); if (resolvedType != null) { return resolvedType; } // If not, then this might be a nested type reference on another type, so let's split it // to look for that in our imports later dotBaseTypeName = "." + name.substring(0, dotIndex); dotExtensionTypeName = name.substring(dotIndex); } IImportDeclaration[] importDeclarations = declaringType.getCompilationUnit().getImports(); // Loop over the imports and look for the import of our symbol for (IImportDeclaration declaration : importDeclarations) { String importName = declaration.getElementName(); // If it's a .* import, then pop off the package name and lookup the type if (declaration.isOnDemand()) { String packageName = importName.substring(0, importName.lastIndexOf('.')); String possibleTypeName = packageName + dotTypeName; IType onDemandPackageType = javaProject.findType(possibleTypeName); if (onDemandPackageType != null) { return onDemandPackageType; } } // If it's not a .* import, then does the import end with our type name? else if (importName.endsWith(dotTypeName)) { IType importType = javaProject.findType(importName); if (importType != null) { return importType; } } // If it doesn't, check to see if we were a dotted type ("Outer.Inner") and check to see // if Outer is imported else if (dotBaseTypeName != null && importName.endsWith(dotBaseTypeName)) { // ... then look for Outer.Inner IType importNestedType = javaProject.findType(importName + dotExtensionTypeName); if (importNestedType != null) { return importNestedType; } } } // Is this a java.lang.Xxx class that we get for free? String javaLangTypeName = "java.lang" + dotTypeName; IType javaLangType = javaProject.findType(javaLangTypeName); if (javaLangType != null) { return javaLangType; } // What about an inner type of our own class? String innerTypeName = declaringType.getFullyQualifiedName('.') + dotTypeName; IType innerType = javaProject.findType(innerTypeName); if (innerType != null) { return innerType; } // Are we declared in a package? IPackageFragment declaringTypePackageFragment = declaringType.getPackageFragment(); if (declaringTypePackageFragment != null) { // ... if so, is this name in our package, so it didn't need an import? String samePackageTypeName = declaringTypePackageFragment.getElementName() + dotTypeName; IType samePackageType = javaProject.findType(samePackageTypeName); if (samePackageType != null) { return samePackageType; } } else { // If we were in the default package, is that class in the default package too? IType defaultPackageType = javaProject.findType(name); if (defaultPackageType != null) { return defaultPackageType; } } String slowResolvedTypeName = JavaModelUtil.getResolvedTypeName(refTypeSig, _type); if (slowResolvedTypeName != null) { IType slowResolvedType = javaProject.findType(slowResolvedTypeName); if (slowResolvedType != null) { return slowResolvedType; } } return null; } else { // We were given an Lxxx; signature ... just look it up String resolvedTypeName = Signature.toString(refTypeSig.substring(arrayCount)); IType resolvedType = javaProject.findType(resolvedTypeName); return resolvedType; } }