/** {@inheritDoc} */
  @Override
  public Object invoke(final Object proxy, final Method method, final Object[] args)
      throws Throwable {
    unwrapArgs(method.getParameterTypes(), args);
    if (!mixinHandlers.isEmpty()) {
      MethodSignature methodSignature = MethodSignature.forMethod(method);
      if (mixinHandlers.containsKey(methodSignature)) {
        return mixinHandlers.get(methodSignature).invoke(proxy, method, args);
      }
    }

    final InvocationHandler invocationHandler = handlers.get(MethodSignature.forMethod(method));
    if (invocationHandler != null) {
      try {
        return invocationHandler.invoke(proxy, method, args);
      } catch (XPathExpressionException e) {
        throw new XBPathException(e, method, "??");
      }
    }

    throw new IllegalArgumentException(
        "I don't known how to invoke method "
            + method
            + ". Did you forget to add a XB*-annotation or to register a mixin?");
  }
 public static boolean isReceiverType(
     PsiType functionalInterfaceType,
     PsiClass containingClass,
     @Nullable PsiMethod referencedMethod) {
   final PsiClassType.ClassResolveResult resolveResult =
       PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
   final MethodSignature function = LambdaUtil.getFunction(resolveResult.getElement());
   if (function != null) {
     final int interfaceMethodParamsLength = function.getParameterTypes().length;
     if (interfaceMethodParamsLength > 0) {
       final PsiType firstParamType =
           resolveResult.getSubstitutor().substitute(function.getParameterTypes()[0]);
       boolean isReceiver =
           isReceiverType(
               firstParamType,
               containingClass,
               PsiUtil.resolveGenericsClassInType(firstParamType).getSubstitutor());
       if (isReceiver) {
         if (referencedMethod == null) {
           if (interfaceMethodParamsLength == 1) return true;
           return false;
         }
         if (referencedMethod.getParameterList().getParametersCount()
             != interfaceMethodParamsLength - 1) {
           return false;
         }
         return true;
       }
     }
   }
   return false;
 }
 @NotNull
 private static List<PsiMethod> findMethodsBySignature(
     @NotNull PsiClass aClass,
     @NotNull PsiMethod patternMethod,
     boolean checkBases,
     boolean stopOnFirst) {
   final PsiMethod[] methodsByName = aClass.findMethodsByName(patternMethod.getName(), checkBases);
   if (methodsByName.length == 0) return Collections.emptyList();
   final List<PsiMethod> methods = new SmartList<PsiMethod>();
   final MethodSignature patternSignature = patternMethod.getSignature(PsiSubstitutor.EMPTY);
   for (final PsiMethod method : methodsByName) {
     final PsiClass superClass = method.getContainingClass();
     final PsiSubstitutor substitutor;
     if (checkBases && !aClass.equals(superClass)) {
       substitutor =
           TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY);
     } else {
       substitutor = PsiSubstitutor.EMPTY;
     }
     final MethodSignature signature = method.getSignature(substitutor);
     if (signature.equals(patternSignature)) {
       methods.add(method);
       if (stopOnFirst) {
         break;
       }
     }
   }
   return methods;
 }
 @Override
 public final boolean permitsStaticMethod(Method method, Object[] args) {
   for (MethodSignature s : staticMethodSignatures()) {
     if (s.matches(method)) {
       return true;
     }
   }
   return false;
 }
  @Nullable
  public static PsiMethod findMethodBySignature(
      GrTypeDefinition grType, PsiMethod patternMethod, boolean checkBases) {
    final MethodSignature patternSignature = patternMethod.getSignature(PsiSubstitutor.EMPTY);
    for (PsiMethod method : findMethodsByName(grType, patternMethod.getName(), checkBases, false)) {
      MethodSignature signature = getSignatureForInheritor(method, grType);
      if (patternSignature.equals(signature)) return method;
    }

    return null;
  }
예제 #6
0
 private <T> Cursor<T> executeForCursor(SqlSession sqlSession, Object[] args) {
   Cursor<T> result;
   Object param = method.convertArgsToSqlCommandParam(args);
   if (method.hasRowBounds()) {
     RowBounds rowBounds = method.extractRowBounds(args);
     result = sqlSession.<T>selectCursor(command.getName(), param, rowBounds);
   } else {
     result = sqlSession.<T>selectCursor(command.getName(), param);
   }
   return result;
 }
예제 #7
0
 private <K, V> Map<K, V> executeForMap(SqlSession sqlSession, Object[] args) {
   Map<K, V> result;
   Object param = method.convertArgsToSqlCommandParam(args);
   if (method.hasRowBounds()) {
     RowBounds rowBounds = method.extractRowBounds(args);
     result = sqlSession.<K, V>selectMap(command.getName(), param, method.getMapKey(), rowBounds);
   } else {
     result = sqlSession.<K, V>selectMap(command.getName(), param, method.getMapKey());
   }
   return result;
 }
  public static PsiType[] getErasedParameterTypes(MethodSignature signature) {
    PsiType[] parameterTypes = signature.getParameterTypes();
    if (parameterTypes.length == 0) return PsiType.EMPTY_ARRAY;

    PsiSubstitutor substitutor = signature.getSubstitutor();
    PsiType[] erasedTypes = new PsiType[parameterTypes.length];
    for (int i = 0; i < parameterTypes.length; i++) {
      erasedTypes[i] =
          TypeConversionUtil.erasure(substitutor.substitute(parameterTypes[i]), substitutor);
    }
    return erasedTypes;
  }
 @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;
        }
  private Map<MethodSignature, InvocationHandler> getDefaultInvokers(
      final Object defaultInvokerObject) {
    final ReflectionInvoker reflectionInvoker = new ReflectionInvoker(defaultInvokerObject);
    final Map<MethodSignature, InvocationHandler> invokers =
        new HashMap<MethodSignature, InvocationHandler>();
    for (Method m : DOMAccess.class.getMethods()) {
      if (m.getAnnotation(XBWrite.class) == null) {
        invokers.put(MethodSignature.forMethod(m), reflectionInvoker);
      }
    }

    invokers.put(MethodSignature.forVoidMethod("toString"), reflectionInvoker);
    invokers.put(MethodSignature.forSingleParam("equals", Object.class), reflectionInvoker);
    invokers.put(MethodSignature.forVoidMethod("hashCode"), reflectionInvoker);
    return invokers; // Collections.unmodifiableMap(invokers);
  }
예제 #12
0
 @Nullable
 private static List<MethodSignature> hasSubsignature(List<MethodSignature> signatures) {
   for (MethodSignature signature : signatures) {
     boolean subsignature = true;
     for (MethodSignature methodSignature : signatures) {
       if (!signature.equals(methodSignature)) {
         if (!MethodSignatureUtil.isSubsignature(signature, methodSignature)) {
           subsignature = false;
           break;
         }
       }
     }
     if (subsignature) return Collections.singletonList(signature);
   }
   return signatures;
 }
  @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;
  }
 private static PsiMethod[] findMethodsBySignature(
     GrTypeDefinition grType,
     PsiMethod patternMethod,
     boolean checkBases,
     boolean includeSynthetic) {
   ArrayList<PsiMethod> result = new ArrayList<PsiMethod>();
   final MethodSignature patternSignature = patternMethod.getSignature(PsiSubstitutor.EMPTY);
   for (PsiMethod method :
       findMethodsByName(grType, patternMethod.getName(), checkBases, includeSynthetic)) {
     MethodSignature signature = getSignatureForInheritor(method, grType);
     if (patternSignature.equals(signature)) {
       result.add(method);
     }
   }
   return result.toArray(new PsiMethod[result.size()]);
 }
예제 #15
0
 private void executeWithResultHandler(SqlSession sqlSession, Object[] args) {
   MappedStatement ms = sqlSession.getConfiguration().getMappedStatement(command.getName());
   if (void.class.equals(ms.getResultMaps().get(0).getType())) {
     throw new BindingException(
         "method "
             + command.getName()
             + " needs either a @ResultMap annotation, a @ResultType annotation,"
             + " or a resultType attribute in XML so a ResultHandler can be used as a parameter.");
   }
   Object param = method.convertArgsToSqlCommandParam(args);
   if (method.hasRowBounds()) {
     RowBounds rowBounds = method.extractRowBounds(args);
     sqlSession.select(command.getName(), param, rowBounds, method.extractResultHandler(args));
   } else {
     sqlSession.select(command.getName(), param, method.extractResultHandler(args));
   }
 }
  @Test
  public void getInterceptionHandler_whenCallIsNotRecognized_shouldReturnDoNothingHandler()
      throws Exception {
    MethodSignature methodSignature = MethodSignature.parse("java/lang/Object/unknownMethod()V");
    Function<Object, Object> handler = shadowWrangler.getInterceptionHandler(methodSignature);

    assertThat(handler).isNotNull().isSameAs(ShadowWrangler.DO_NOTHING_HANDLER);
    assertThat(handler.call(null)).isNull();
  }
  public static boolean isSubsignature(
      MethodSignature superSignature, MethodSignature subSignature) {
    if (subSignature == superSignature) return true;
    if (!areSignaturesEqualLightweight(superSignature, subSignature)) return false;
    PsiSubstitutor unifyingSubstitutor =
        getSuperMethodSignatureSubstitutor(subSignature, superSignature);
    if (checkSignaturesEqualInner(superSignature, subSignature, unifyingSubstitutor)) return true;

    if (subSignature.getTypeParameters().length > 0) return false;
    final PsiType[] subParameterTypes = subSignature.getParameterTypes();
    final PsiType[] superParameterTypes = superSignature.getParameterTypes();
    for (int i = 0; i < subParameterTypes.length; i++) {
      PsiType type1 = subParameterTypes[i];
      PsiType type2 = TypeConversionUtil.erasure(superParameterTypes[i]);
      if (!Comparing.equal(type1, type2)) return false;
    }
    return true;
  }
예제 #18
0
 private <E> Object executeForMany(SqlSession sqlSession, Object[] args) {
   List<E> result;
   Object param = method.convertArgsToSqlCommandParam(args);
   if (method.hasRowBounds()) {
     RowBounds rowBounds = method.extractRowBounds(args);
     result = sqlSession.<E>selectList(command.getName(), param, rowBounds);
   } else {
     result = sqlSession.<E>selectList(command.getName(), param);
   }
   // issue #510 Collections & arrays support
   if (!method.getReturnType().isAssignableFrom(result.getClass())) {
     if (method.getReturnType().isArray()) {
       return convertToArray(result);
     } else {
       return convertToDeclaredCollection(sqlSession.getConfiguration(), result);
     }
   }
   return result;
 }
예제 #19
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());
  }
  private static boolean checkSignaturesEqualInner(
      @NotNull MethodSignature subSignature,
      @NotNull MethodSignature superSignature,
      final PsiSubstitutor unifyingSubstitutor) {
    if (unifyingSubstitutor == null) return false;
    if (!areErasedParametersEqual(subSignature, superSignature)) return false;

    final PsiType[] subParameterTypes = subSignature.getParameterTypes();
    final PsiType[] superParameterTypes = superSignature.getParameterTypes();
    for (int i = 0; i < subParameterTypes.length; i++) {
      final PsiType type1 = unifyingSubstitutor.substitute(subParameterTypes[i]);
      final PsiType type2 = unifyingSubstitutor.substitute(superParameterTypes[i]);
      if (!Comparing.equal(type1, type2)) {
        return false;
      }
    }

    return true;
  }
  @Test
  public void
      getInterceptionHandler_whenInterceptingElderOnLinkedHashMap_shouldReturnNonDoNothingHandler()
          throws Exception {
    MethodSignature methodSignature =
        MethodSignature.parse("java/util/LinkedHashMap/eldest()Ljava/lang/Object");
    Function<Object, Object> handler = shadowWrangler.getInterceptionHandler(methodSignature);

    assertThat(handler).isNotSameAs(ShadowWrangler.DO_NOTHING_HANDLER);
  }
예제 #22
0
  @Override
  public void genCyan(
      PWInterface pw, boolean printInMoreThanOneLine, CyanEnv cyanEnv, boolean genFunctions) {
    if (cyanEnv.getCreatingInstanceGenericPrototype()) {
      pw.print(cyanEnv.formalGenericParamToRealParam(methodName.getSymbolString()));
    } else {
      pw.print(methodName.getSymbolString());
    }

    super.genCyan(pw, printInMoreThanOneLine, cyanEnv, genFunctions);
  }
  @Nullable
  private static PsiSubstitutor getSuperMethodSignatureSubstitutorImpl(
      @NotNull MethodSignature methodSignature, @NotNull MethodSignature superSignature) {
    // normalize generic method declarations: correlate type parameters
    // todo: correlate type params by name?
    PsiTypeParameter[] methodTypeParameters = methodSignature.getTypeParameters();
    PsiTypeParameter[] superTypeParameters = superSignature.getTypeParameters();

    // both methods are parameterized and number of parameters mismatch
    if (methodTypeParameters.length != superTypeParameters.length) return null;

    PsiSubstitutor result = superSignature.getSubstitutor();
    for (int i = 0; i < methodTypeParameters.length; i++) {
      PsiTypeParameter methodTypeParameter = methodTypeParameters[i];
      PsiElementFactory factory =
          JavaPsiFacade.getInstance(methodTypeParameter.getProject()).getElementFactory();
      result = result.put(superTypeParameters[i], factory.createType(methodTypeParameter));
    }

    return result;
  }
예제 #24
0
 @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;
 }
  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;
  }
  /**
   * @param methodSignature method signature
   * @param superMethodSignature super method signature
   * @return null if signatures do not match
   */
  @Nullable
  public static PsiSubstitutor getSuperMethodSignatureSubstitutor(
      @NotNull MethodSignature methodSignature, @NotNull MethodSignature superMethodSignature) {
    PsiSubstitutor result =
        getSuperMethodSignatureSubstitutorImpl(methodSignature, superMethodSignature);
    if (result == null) return null;

    PsiTypeParameter[] methodTypeParameters = methodSignature.getTypeParameters();
    PsiTypeParameter[] superTypeParameters = superMethodSignature.getTypeParameters();
    PsiSubstitutor methodSubstitutor = methodSignature.getSubstitutor();

    // check bounds
    for (int i = 0; i < methodTypeParameters.length; i++) {
      PsiTypeParameter methodTypeParameter = methodTypeParameters[i];
      PsiTypeParameter superTypeParameter = superTypeParameters[i];
      final Set<PsiType> methodSupers = new HashSet<PsiType>();
      for (PsiClassType methodSuper : methodTypeParameter.getSuperTypes()) {
        methodSupers.add(methodSubstitutor.substitute(methodSuper));
      }

      final Set<PsiType> superSupers = new HashSet<PsiType>();
      for (PsiClassType superSuper : superTypeParameter.getSuperTypes()) {
        superSupers.add(
            methodSubstitutor.substitute(
                PsiUtil.captureToplevelWildcards(
                    result.substitute(superSuper), methodTypeParameter)));
      }
      methodSupers.remove(
          PsiType.getJavaLangObject(
              methodTypeParameter.getManager(), methodTypeParameter.getResolveScope()));
      superSupers.remove(
          PsiType.getJavaLangObject(
              superTypeParameter.getManager(), superTypeParameter.getResolveScope()));
      if (!methodSupers.equals(superSupers)) return null;
    }

    return result;
  }
 private static boolean hasReceiver(
     @NotNull PsiMethodReferenceExpression methodRef,
     @NotNull PsiMethod method,
     PsiType functionalInterfaceType) {
   final PsiClassType.ClassResolveResult resolveResult =
       PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
   final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(resolveResult);
   final MethodSignature signature =
       interfaceMethod != null
           ? interfaceMethod.getSignature(
               LambdaUtil.getSubstitutor(interfaceMethod, resolveResult))
           : null;
   if (signature == null) {
     return false;
   }
   final PsiType[] parameterTypes = signature.getParameterTypes();
   final QualifierResolveResult qualifierResolveResult = getQualifierResolveResult(methodRef);
   return (method.getParameterList().getParametersCount() + 1 == parameterTypes.length
           || method.isVarArgs()
               && parameterTypes.length > 0
               && !method.hasModifierProperty(PsiModifier.STATIC))
       && hasReceiver(parameterTypes, qualifierResolveResult, methodRef);
 }
  private void fixupSignature(MethodSignature signature) throws IOException {
    int classNameIndex = signature.getClassNameIndex();
    String dottedName = constantPool.getUtf8(classNameIndex).getString().replace("/", ".");
    signature.setClassNameIndex(getOrInsertUtf8(dottedName));

    signature.setMethodNameIndex(
        getOrInsertString(signature.getMethodNameIndex())); // will be a String resource now
    signature.setClassNameIndex(
        getOrInsertString(signature.getClassNameIndex())); // will be a String resource now
  }
  private Map<String, Integer> getOrInsertPrimitiveWrapperMethods(MethodSignature signature)
      throws IOException {
    Map<String, Integer> methodRefs = new HashMap<String, Integer>();

    int valueOfString = getOrInsertUtf8("valueOf");

    for (String paramType : signature.getParamTypes()) {
      char baseType = paramType.charAt(0);
      Class wrapperClass = getWrapperClass(baseType);
      if (wrapperClass != null) {
        int wrapperMethod = getOrInsertPrimitiveWrappeMethod(wrapperClass, baseType, valueOfString);
        methodRefs.put(paramType, wrapperMethod);
      }
    }

    return methodRefs;
  }
예제 #30
0
 private Object rowCountResult(int rowCount) {
   final Object result;
   if (method.returnsVoid()) {
     result = null;
   } else if (Integer.class.equals(method.getReturnType())
       || Integer.TYPE.equals(method.getReturnType())) {
     result = Integer.valueOf(rowCount);
   } else if (Long.class.equals(method.getReturnType())
       || Long.TYPE.equals(method.getReturnType())) {
     result = Long.valueOf(rowCount);
   } else if (Boolean.class.equals(method.getReturnType())
       || Boolean.TYPE.equals(method.getReturnType())) {
     result = Boolean.valueOf(rowCount > 0);
   } else {
     throw new BindingException(
         "Mapper method '"
             + command.getName()
             + "' has an unsupported return type: "
             + method.getReturnType());
   }
   return result;
 }