Example #1
0
 public List<? extends TypeMirror> getParameterTypes() {
   MethodBinding binding = (MethodBinding) this._binding;
   TypeBinding[] parameters = binding.parameters;
   int length = parameters.length;
   boolean isEnumConstructor =
       binding.isConstructor()
           && binding.declaringClass.isEnum()
           && binding.declaringClass.isBinaryBinding()
           && ((binding.modifiers & ExtraCompilerModifiers.AccGenericSignature) == 0);
   if (isEnumConstructor) {
     if (length == 2) {
       return Collections.emptyList();
     }
     ArrayList<TypeMirror> list = new ArrayList<TypeMirror>();
     for (int i = 2; i < length; i++) {
       list.add(_env.getFactory().newTypeMirror(parameters[i]));
     }
     return Collections.unmodifiableList(list);
   }
   if (length != 0) {
     ArrayList<TypeMirror> list = new ArrayList<TypeMirror>();
     for (TypeBinding typeBinding : parameters) {
       list.add(_env.getFactory().newTypeMirror(typeBinding));
     }
     return Collections.unmodifiableList(list);
   }
   return Collections.emptyList();
 }
 /**
  * In this case: check match of "replace" and "callin" flags, plus static-ness
  *
  * @param haveBaseMethods have base methods been resolved?
  * @param baseClass the role's bound base class
  */
 @Override
 protected void checkModifiers(boolean haveBaseMethods, ReferenceBinding baseClass) {
   if (this.ignoreFurtherInvestigation) // error was already flagged, i.e. missing replace
   return;
   // replace and callin matching:
   if (isReplaceCallin()) {
     if (!this.roleMethodSpec.resolvedMethod.isCallin()) {
       this.scope
           .problemReporter()
           .replaceMappingToNonCallin(this.roleMethodSpec, this.roleMethodSpec.resolvedMethod);
       this.binding.tagBits |= TagBits.HasMappingIncompatibility;
       return;
     }
   } else {
     if (this.roleMethodSpec.resolvedMethod.isCallin()) {
       this.scope.problemReporter().callinMethodBoundNonReplace(this.roleMethodSpec, this);
       this.binding.tagBits |= TagBits.HasMappingIncompatibility;
       return;
     }
   }
   if (haveBaseMethods) {
     // static non-static consistency:
     if (!this.roleMethodSpec.resolvedMethod.isStatic()) {
       for (int i = 0; i < this.baseMethodSpecs.length; i++) {
         this.baseMethodSpecs[i].checkStaticness(this, false);
       }
     }
     if (isReplaceCallin()) {
       if (this.roleMethodSpec.resolvedMethod.isStatic()) {
         for (int i = 0; i < this.baseMethodSpecs.length; i++) {
           this.baseMethodSpecs[i].checkStaticness(this, true);
         }
       }
     }
     // callin-to-final? respect OTJLD 4.1(f)
     for (int i = 0; i < this.baseMethodSpecs.length; i++) {
       MethodBinding baseMethod = this.baseMethodSpecs[i].resolvedMethod;
       if (baseMethod != null) {
         if (baseMethod.isFinal()) {
           if (TypeBinding.notEquals(baseMethod.declaringClass, baseClass)) {
             this.scope
                 .problemReporter()
                 .bindingToInheritedFinal(this.baseMethodSpecs[i], baseMethod, baseClass);
             this.binding.tagBits |= TagBits.HasMappingIncompatibility;
           }
         }
         if (baseMethod.isConstructor()) {
           if (this.callinModifier != TokenNameafter) {
             this.scope
                 .problemReporter()
                 .callinToCtorMustBeAfter(this.baseMethodSpecs[i], baseMethod);
             this.binding.tagBits |= TagBits.HasMappingIncompatibility;
           }
         }
       }
     }
   }
 }
Example #3
0
    private MethodBinding checkAndResolveMethodRef(
        SourceInfo errorInfo,
        ReferenceBinding clazz,
        JsniRef jsniRef,
        boolean hasQualifier,
        boolean isLvalue) {
      assert jsniRef.isMethod();
      List<MethodBinding> targets = getMatchingMethods(clazz, jsniRef);
      if (targets.size() > 1) {
        emitError(
            ERR_AMBIGUOUS_WILDCARD_MATCH,
            errorInfo,
            jsniRef,
            JdtUtil.formatBinding(targets.get(0)),
            JdtUtil.formatBinding(targets.get(1)));
        return null;
      } else if (targets.isEmpty()) {
        emitError(ERR_UNABLE_TO_RESOLVE_METHOD, errorInfo, jsniRef);
        return null;
      }
      MethodBinding target = targets.get(0);
      resolveJsniRef(jsniRef, target);
      if (target.isDeprecated()
          && !isEnclosingClass(method.binding.declaringClass, target.declaringClass)) {
        emitWarning("deprecation", WARN_DEPRECATED_METHOD, errorInfo, jsniRef);
      }
      if (isLvalue) {
        emitError(ERR_ILLEGAL_ASSIGNMENT_TO_METHOD, errorInfo, jsniRef);
      }
      boolean needsQualifer = !target.isStatic() && !target.isConstructor();
      if (!needsQualifer && hasQualifier) {
        emitError(ERR_UNNECESSARY_QUALIFIER_STATIC_METHOD, errorInfo, jsniRef);
      } else if (needsQualifer && !hasQualifier) {
        emitError(ERR_MISSING_QUALIFIER_INSTANCE_METHOD, errorInfo, jsniRef);
      }

      if (hasUnsafeLongsAnnotation) {
        return target;
      }
      if (containsLong(target.returnType)) {
        emitError(ERR_ILLEGAL_RETURN_TYPE, errorInfo, jsniRef, typeString(target.returnType));
      }

      if (target.parameters != null) {
        int i = 0;
        for (TypeBinding paramType : target.parameters) {
          ++i;
          if (containsLong(paramType)) {
            // It would be nice to print the parameter name, but how to find it?
            emitError(ERR_ILLEGAL_PARAMETER, errorInfo, jsniRef, i, typeString(paramType));
          }
        }
      }
      return target;
    }
 /*
  * @see ITypeBinding#getDeclaredMethods()
  */
 public synchronized IMethodBinding[] getDeclaredMethods() {
   if (this.methods != null) {
     return this.methods;
   }
   try {
     if (isClass() || isInterface() || isEnum()) {
       ReferenceBinding referenceBinding = (ReferenceBinding) this.binding;
       org.eclipse.jdt.internal.compiler.lookup.MethodBinding[] internalMethods =
           referenceBinding.availableMethods(); // be resilient
       int length = internalMethods.length;
       if (length != 0) {
         int convertedMethodCount = 0;
         IMethodBinding[] newMethods = new IMethodBinding[length];
         for (int i = 0; i < length; i++) {
           org.eclipse.jdt.internal.compiler.lookup.MethodBinding methodBinding =
               internalMethods[i];
           if (methodBinding.isDefaultAbstract()
               || methodBinding.isSynthetic()
               || (methodBinding.isConstructor() && isInterface())) {
             continue;
           }
           IMethodBinding methodBinding2 = this.resolver.getMethodBinding(methodBinding);
           if (methodBinding2 != null) {
             newMethods[convertedMethodCount++] = methodBinding2;
           }
         }
         if (convertedMethodCount != length) {
           if (convertedMethodCount == 0) {
             return this.methods = NO_METHOD_BINDINGS;
           }
           System.arraycopy(
               newMethods,
               0,
               (newMethods = new IMethodBinding[convertedMethodCount]),
               0,
               convertedMethodCount);
         }
         return this.methods = newMethods;
       }
     }
   } catch (RuntimeException e) {
     /* in case a method cannot be resolvable due to missing jars on the classpath
      * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=57871
      * https://bugs.eclipse.org/bugs/show_bug.cgi?id=63550
      * https://bugs.eclipse.org/bugs/show_bug.cgi?id=64299
      */
     org.eclipse.jdt.internal.core.util.Util.log(
         e, "Could not retrieve declared methods"); // $NON-NLS-1$
   }
   return this.methods = NO_METHOD_BINDINGS;
 }
  private void searchVisibleLocalMethods(
      MethodBinding[] methods,
      ReferenceBinding receiverType,
      Scope scope,
      InvocationSite invocationSite,
      Scope invocationScope,
      boolean onlyStaticMethods,
      ObjectVector methodsFound) {
    ObjectVector newMethodsFound = new ObjectVector();
    // Inherited methods which are hidden by subclasses are filtered out
    // No visibility checks can be performed without the scope & invocationSite

    next:
    for (int f = methods.length; --f >= 0; ) {
      MethodBinding method = methods[f];

      if (method.isSynthetic()) continue next;

      if (method.isDefaultAbstract()) continue next;

      if (method.isConstructor()) continue next;

      if (onlyStaticMethods && !method.isStatic()) continue next;

      if (!method.canBeSeenBy(receiverType, invocationSite, scope)) continue next;

      for (int i = methodsFound.size; --i >= 0; ) {
        MethodBinding otherMethod = (MethodBinding) methodsFound.elementAt(i);
        if (method == otherMethod) continue next;

        if (CharOperation.equals(method.selector, otherMethod.selector, true)) {
          if (this.lookupEnvironment.methodVerifier().isMethodSubsignature(otherMethod, method)) {
            continue next;
          }
        }
      }

      newMethodsFound.add(method);
    }

    methodsFound.addAll(newMethodsFound);
  }
Example #6
0
  private static void checkAlternateBinding(
      BlockScope scope,
      Expression receiver,
      TypeBinding receiverType,
      MethodBinding binding,
      Expression[] arguments,
      TypeBinding[] originalArgumentTypes,
      TypeBinding[] alternateArgumentTypes,
      final InvocationSite invocationSite) {
    InvocationSite fakeInvocationSite =
        new InvocationSite() {
          public TypeBinding[] genericTypeArguments() {
            return null;
          }

          public boolean isSuperAccess() {
            return invocationSite.isSuperAccess();
          }

          public boolean isTypeAccess() {
            return invocationSite.isTypeAccess();
          }

          public void setActualReceiverType(ReferenceBinding actualReceiverType) {
            /* ignore */
          }

          public void setDepth(int depth) {
            /* ignore */
          }

          public void setFieldIndex(int depth) {
            /* ignore */
          }

          public int sourceStart() {
            return 0;
          }

          public int sourceEnd() {
            return 0;
          }
        };
    MethodBinding bindingIfNoCast;
    if (binding.isConstructor()) {
      bindingIfNoCast =
          scope.getConstructor(
              (ReferenceBinding) receiverType, alternateArgumentTypes, fakeInvocationSite);
    } else {
      bindingIfNoCast =
          receiver.isImplicitThis()
              ? scope.getImplicitMethod(
                  binding.selector, alternateArgumentTypes, fakeInvocationSite)
              : scope.getMethod(
                  receiverType, binding.selector, alternateArgumentTypes, fakeInvocationSite);
    }
    if (bindingIfNoCast == binding) {
      int argumentLength = originalArgumentTypes.length;
      if (binding.isVarargs()) {
        int paramLength = binding.parameters.length;
        if (paramLength == argumentLength) {
          int varargsIndex = paramLength - 1;
          ArrayBinding varargsType = (ArrayBinding) binding.parameters[varargsIndex];
          TypeBinding lastArgType = alternateArgumentTypes[varargsIndex];
          // originalType may be compatible already, but cast mandated
          // to clarify between varargs/non-varargs call
          if (varargsType.dimensions != lastArgType.dimensions()) {
            return;
          }
          if (lastArgType.isCompatibleWith(varargsType.elementsType())
              && lastArgType.isCompatibleWith(varargsType)) {
            return;
          }
        }
      }
      for (int i = 0; i < argumentLength; i++) {
        if (originalArgumentTypes[i] != alternateArgumentTypes[i]) {
          scope.problemReporter().unnecessaryCast((CastExpression) arguments[i]);
        }
      }
    }
  }
  /** Locate declaration in the current class file. This class file is always in a jar. */
  public void locateMatches(MatchLocator locator, ClassFile classFile, IBinaryType info)
      throws CoreException {
    SearchPattern pattern = locator.pattern;

    // check annotations references
    matchAnnotations(pattern, locator, classFile, info);

    // check class definition
    BinaryType binaryType = (BinaryType) classFile.getType();
    if (matchBinary(pattern, info, null)) {
      binaryType =
          new ResolvedBinaryType(
              (JavaElement) binaryType.getParent(),
              binaryType.getElementName(),
              binaryType.getKey());
      locator.reportBinaryMemberDeclaration(null, binaryType, null, info, SearchMatch.A_ACCURATE);
      return;
    }

    // Define arrays to store methods/fields from binary type if necessary
    IBinaryMethod[] binaryMethods = info.getMethods();
    int bMethodsLength = binaryMethods == null ? 0 : binaryMethods.length;
    IBinaryMethod[] unresolvedMethods = null;
    char[][] binaryMethodSignatures = null;
    boolean hasUnresolvedMethods = false;

    // Get fields from binary type info
    IBinaryField[] binaryFields = info.getFields();
    int bFieldsLength = binaryFields == null ? 0 : binaryFields.length;
    IBinaryField[] unresolvedFields = null;
    boolean hasUnresolvedFields = false;

    // Report as many accurate matches as possible
    int accuracy = SearchMatch.A_ACCURATE;
    boolean mustResolve = pattern.mustResolve;
    if (mustResolve) {
      BinaryTypeBinding binding = locator.cacheBinaryType(binaryType, info);
      if (binding != null) {
        // filter out element not in hierarchy scope
        if (!locator.typeInHierarchy(binding)) return;

        // Search matches on resolved methods
        MethodBinding[] availableMethods = binding.availableMethods();
        int aMethodsLength = availableMethods == null ? 0 : availableMethods.length;
        hasUnresolvedMethods = bMethodsLength != aMethodsLength;
        for (int i = 0; i < aMethodsLength; i++) {
          MethodBinding method = availableMethods[i];
          char[] methodSignature = method.genericSignature();
          if (methodSignature == null) methodSignature = method.signature();

          // Report the match if possible
          int level = locator.patternLocator.resolveLevel(method);
          if (level != PatternLocator.IMPOSSIBLE_MATCH) {
            IMethod methodHandle =
                binaryType.getMethod(
                    new String(
                        method.isConstructor()
                            ? binding.compoundName[binding.compoundName.length - 1]
                            : method.selector),
                    CharOperation.toStrings(
                        Signature.getParameterTypes(convertClassFileFormat(methodSignature))));
            accuracy =
                level == PatternLocator.ACCURATE_MATCH
                    ? SearchMatch.A_ACCURATE
                    : SearchMatch.A_INACCURATE;
            locator.reportBinaryMemberDeclaration(null, methodHandle, method, info, accuracy);
          }

          // Remove method from unresolved list
          if (hasUnresolvedMethods) {
            if (binaryMethodSignatures
                == null) { // Store binary method signatures to avoid multiple computation
              binaryMethodSignatures = new char[bMethodsLength][];
              for (int j = 0; j < bMethodsLength; j++) {
                IBinaryMethod binaryMethod = binaryMethods[j];
                char[] signature = binaryMethod.getGenericSignature();
                if (signature == null) signature = binaryMethod.getMethodDescriptor();
                binaryMethodSignatures[j] = signature;
              }
            }
            for (int j = 0; j < bMethodsLength; j++) {
              if (CharOperation.equals(binaryMethods[j].getSelector(), method.selector)
                  && CharOperation.equals(binaryMethodSignatures[j], methodSignature)) {
                if (unresolvedMethods == null) {
                  System.arraycopy(
                      binaryMethods,
                      0,
                      unresolvedMethods = new IBinaryMethod[bMethodsLength],
                      0,
                      bMethodsLength);
                }
                unresolvedMethods[j] = null;
                break;
              }
            }
          }
        }

        // Search matches on resolved fields
        FieldBinding[] availableFields = binding.availableFields();
        int aFieldsLength = availableFields == null ? 0 : availableFields.length;
        hasUnresolvedFields = bFieldsLength != aFieldsLength;
        for (int i = 0; i < aFieldsLength; i++) {
          FieldBinding field = availableFields[i];

          // Report the match if possible
          int level = locator.patternLocator.resolveLevel(field);
          if (level != PatternLocator.IMPOSSIBLE_MATCH) {
            IField fieldHandle = binaryType.getField(new String(field.name));
            accuracy =
                level == PatternLocator.ACCURATE_MATCH
                    ? SearchMatch.A_ACCURATE
                    : SearchMatch.A_INACCURATE;
            locator.reportBinaryMemberDeclaration(null, fieldHandle, field, info, accuracy);
          }

          // Remove the field from unresolved list
          if (hasUnresolvedFields) {
            for (int j = 0; j < bFieldsLength; j++) {
              if (CharOperation.equals(binaryFields[j].getName(), field.name)) {
                if (unresolvedFields == null) {
                  System.arraycopy(
                      binaryFields,
                      0,
                      unresolvedFields = new IBinaryField[bFieldsLength],
                      0,
                      bFieldsLength);
                }
                unresolvedFields[j] = null;
                break;
              }
            }
          }
        }

        // If all methods/fields were accurate then returns now
        if (!hasUnresolvedMethods && !hasUnresolvedFields) {
          return;
        }
      }
      accuracy = SearchMatch.A_INACCURATE;
    }

    // Report inaccurate methods
    if (mustResolve) binaryMethods = unresolvedMethods;
    bMethodsLength = binaryMethods == null ? 0 : binaryMethods.length;
    for (int i = 0; i < bMethodsLength; i++) {
      IBinaryMethod method = binaryMethods[i];
      if (method == null) continue; // impossible match or already reported as accurate
      if (matchBinary(pattern, method, info)) {
        char[] name;
        if (method.isConstructor()) {
          name = info.getName();
          int lastSlash = CharOperation.lastIndexOf('/', name);
          if (lastSlash != -1) {
            name = CharOperation.subarray(name, lastSlash + 1, name.length);
          }
        } else {
          name = method.getSelector();
        }
        String selector = new String(name);
        char[] methodSignature = binaryMethodSignatures == null ? null : binaryMethodSignatures[i];
        if (methodSignature == null) {
          methodSignature = method.getGenericSignature();
          if (methodSignature == null) methodSignature = method.getMethodDescriptor();
        }
        String[] parameterTypes =
            CharOperation.toStrings(
                Signature.getParameterTypes(convertClassFileFormat(methodSignature)));
        IMethod methodHandle = binaryType.getMethod(selector, parameterTypes);
        methodHandle =
            new ResolvedBinaryMethod(binaryType, selector, parameterTypes, methodHandle.getKey());
        locator.reportBinaryMemberDeclaration(null, methodHandle, null, info, accuracy);
      }
    }

    // Report inaccurate fields
    if (mustResolve) binaryFields = unresolvedFields;
    bFieldsLength = binaryFields == null ? 0 : binaryFields.length;
    for (int i = 0; i < bFieldsLength; i++) {
      IBinaryField field = binaryFields[i];
      if (field == null) continue; // impossible match or already reported as accurate
      if (matchBinary(pattern, field, info)) {
        String fieldName = new String(field.getName());
        IField fieldHandle = binaryType.getField(fieldName);
        fieldHandle = new ResolvedBinaryField(binaryType, fieldName, fieldHandle.getKey());
        locator.reportBinaryMemberDeclaration(null, fieldHandle, null, info, accuracy);
      }
    }
  }
Example #8
0
 private JavaElement getUnresolvedJavaElement() {
   IType declaringType = (IType) getDeclaringClass().getJavaElement();
   if (declaringType == null) return null;
   if (!(this.resolver instanceof DefaultBindingResolver)) return null;
   ASTNode node = (ASTNode) ((DefaultBindingResolver) this.resolver).bindingsToAstNodes.get(this);
   if (node != null && declaringType.getParent().getElementType() != IJavaElement.CLASS_FILE) {
     if (node instanceof MethodDeclaration) {
       MethodDeclaration methodDeclaration = (MethodDeclaration) node;
       ArrayList parameterSignatures = new ArrayList();
       Iterator iterator = methodDeclaration.parameters().iterator();
       while (iterator.hasNext()) {
         SingleVariableDeclaration parameter = (SingleVariableDeclaration) iterator.next();
         Type type = parameter.getType();
         String typeSig = Util.getSignature(type);
         int arrayDim = parameter.getExtraDimensions();
         if (parameter.getAST().apiLevel() >= AST.JLS3 && parameter.isVarargs()) {
           arrayDim++;
         }
         if (arrayDim > 0) {
           typeSig = Signature.createArraySignature(typeSig, arrayDim);
         }
         parameterSignatures.add(typeSig);
       }
       int parameterCount = parameterSignatures.size();
       String[] parameters = new String[parameterCount];
       parameterSignatures.toArray(parameters);
       return (JavaElement) declaringType.getMethod(getName(), parameters);
     } else {
       // annotation type member declaration
       AnnotationTypeMemberDeclaration typeMemberDeclaration =
           (AnnotationTypeMemberDeclaration) node;
       return (JavaElement)
           declaringType.getMethod(
               typeMemberDeclaration.getName().getIdentifier(),
               new String[0]); // annotation type members don't have parameters
     }
   } else {
     // case of method not in the created AST, or a binary method
     org.eclipse.jdt.internal.compiler.lookup.MethodBinding original = this.binding.original();
     String selector =
         original.isConstructor() ? declaringType.getElementName() : new String(original.selector);
     TypeBinding[] parameters = original.parameters;
     int length = parameters == null ? 0 : parameters.length;
     String[] parameterSignatures = new String[length];
     for (int i = 0; i < length; i++) {
       parameterSignatures[i] = new String(parameters[i].genericTypeSignature()).replace('/', '.');
     }
     IMethod result = declaringType.getMethod(selector, parameterSignatures);
     if (declaringType.isBinary()) return (JavaElement) result;
     IMethod[] methods = null;
     try {
       methods = declaringType.getMethods();
     } catch (JavaModelException e) {
       // declaring type doesn't exist
       return null;
     }
     IMethod[] candidates = Member.findMethods(result, methods);
     if (candidates == null || candidates.length == 0) return null;
     return (JavaElement) candidates[0];
   }
 }