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 ? '-' : ')');
  }
Example #2
0
    /**
     * 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;
      }
    }