public static boolean areSignaturesEqualLightweight(
      @NotNull MethodSignature sig1, @NotNull MethodSignature sig2) {
    final boolean isConstructor1 = sig1.isConstructor();
    final boolean isConstructor2 = sig2.isConstructor();
    if (isConstructor1 != isConstructor2) return false;

    if (!isConstructor1
        || !(sig1 instanceof HierarchicalMethodSignature
            || sig2 instanceof HierarchicalMethodSignature)) {
      final String name1 = sig1.getName();
      final String name2 = sig2.getName();
      if (!name1.equals(name2)) return false;
    }

    final PsiType[] parameterTypes1 = sig1.getParameterTypes();
    final PsiType[] parameterTypes2 = sig2.getParameterTypes();
    if (parameterTypes1.length != parameterTypes2.length) return false;

    // optimization: check for really different types in method parameters
    for (int i = 0; i < parameterTypes1.length; i++) {
      final PsiType type1 = parameterTypes1[i];
      final PsiType type2 = parameterTypes2[i];
      if (type1 instanceof PsiPrimitiveType != type2 instanceof PsiPrimitiveType) return false;
      if (type1 instanceof PsiPrimitiveType && !type1.equals(type2)) return false;
    }

    return true;
  }
  @Nullable
  private static PsiMethod doFindMethodInSuperClassBySignatureInDerived(
      @NotNull PsiClass superClass,
      @NotNull PsiSubstitutor superSubstitutor,
      @NotNull MethodSignature signature,
      final boolean checkDeep) {
    final String name = signature.getName();
    final PsiMethod[] methods = superClass.findMethodsByName(name, false);
    for (final PsiMethod method : methods) {
      if (isSubsignature(method.getSignature(superSubstitutor), signature)) {
        return method;
      }
    }

    if (checkDeep) {
      final PsiClass clazz = superClass.getSuperClass();
      if (clazz != null && clazz != superClass) {
        PsiSubstitutor substitutor1 =
            TypeConversionUtil.getSuperClassSubstitutor(clazz, superClass, superSubstitutor);
        return doFindMethodInSuperClassBySignatureInDerived(clazz, substitutor1, signature, true);
      }
    }

    return null;
  }
 @Nullable
 private static PsiMethod getMethod(PsiClass psiClass, MethodSignature methodSignature) {
   final PsiMethod[] methodsByName = psiClass.findMethodsByName(methodSignature.getName(), true);
   for (PsiMethod psiMethod : methodsByName) {
     if (MethodSignatureUtil.areSignaturesEqual(
         getMethodSignature(psiMethod, psiClass, psiMethod.getContainingClass()),
         methodSignature)) {
       return psiMethod;
     }
   }
   return null;
 }
 @Nullable
 public static PsiMethod findMethodBySignature(
     @NotNull PsiClass aClass, @NotNull MethodSignature methodSignature, boolean checkBases) {
   String name = methodSignature.isConstructor() ? aClass.getName() : methodSignature.getName();
   List<Pair<PsiMethod, PsiSubstitutor>> pairs =
       aClass.findMethodsAndTheirSubstitutorsByName(name, checkBases);
   for (Pair<PsiMethod, PsiSubstitutor> pair : pairs) {
     PsiMethod method = pair.first;
     PsiSubstitutor substitutor = pair.second;
     MethodSignature foundMethodSignature = method.getSignature(substitutor);
     if (methodSignature.equals(foundMethodSignature)) return method;
   }
   return null;
 }
        @Override
        public int computeHashCode(final MethodSignature signature) {
          int result = signature.isConstructor() ? 0 : signature.getName().hashCode();

          PsiType[] parameterTypes = signature.getParameterTypes();
          result += 37 * parameterTypes.length;
          PsiType firstParamType = parameterTypes.length == 0 ? null : parameterTypes[0];
          if (firstParamType != null) {
            firstParamType = TypeConversionUtil.erasure(firstParamType, signature.getSubstitutor());
            assert firstParamType != null : parameterTypes[0];
            result = 31 * result + firstParamType.hashCode();
          }
          return result;
        }
示例#6
0
  /**
   * Adds a method to the class which bridges from the service method to the corresponding method in
   * the filter interface. The next service (either another Bridge, or the terminator at the end of
   * the pipeline) is passed to the filter).
   */
  private void addBridgeMethod(int position, MethodSignature ms, MethodSignature fms) {
    StringBuffer buffer = new StringBuffer(100);

    if (ms.getReturnType() != void.class) buffer.append("return ");

    buffer.append("_filter.");
    buffer.append(ms.getName());
    buffer.append("(");

    boolean comma = false;
    int filterParameterCount = fms.getParameterTypes().length;

    for (int i = 0; i < position; i++) {
      if (comma) buffer.append(", ");

      buffer.append("$");
      // Add one to the index to get the parameter symbol ($0 is the implicit
      // this parameter).
      buffer.append(i + 1);

      comma = true;
    }

    if (comma) buffer.append(", ");

    // _next is the variable in -this- Bridge that points to the -next- Bridge
    // or the terminator for the pipeline. The filter is expected to reinvoke the
    // method on the _next that's passed to it.

    buffer.append("_next");

    for (int i = position + 1; i < filterParameterCount; i++) {
      buffer.append(", $");
      buffer.append(i);
    }

    buffer.append(");");

    // This should work, unless the exception types turn out to not be compatble. We still
    // don't do a check on that, and not sure that Javassist does either!

    _classFab.addMethod(Modifier.PUBLIC, ms, buffer.toString());
  }