Java Code Examples for org.eclipse.jdt.core.dom.ITypeBinding#getFunctionalInterfaceMethod()

The following examples show how to use org.eclipse.jdt.core.dom.ITypeBinding#getFunctionalInterfaceMethod() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: JdtUtils.java    From j2cl with Apache License 2.0 5 votes vote down vote up
private static boolean isOrOverridesJsFunctionMethod(IMethodBinding methodBinding) {
  ITypeBinding declaringType = methodBinding.getDeclaringClass();
  if (JsInteropUtils.isJsFunction(declaringType)
      && declaringType.getFunctionalInterfaceMethod() != null
      && methodBinding.getMethodDeclaration()
          == declaringType.getFunctionalInterfaceMethod().getMethodDeclaration()) {
    return true;
  }
  for (IMethodBinding overriddenMethodBinding : getOverriddenMethods(methodBinding)) {
    if (isOrOverridesJsFunctionMethod(overriddenMethodBinding)) {
      return true;
    }
  }
  return false;
}
 
Example 2
Source File: JdtUtils.java    From j2cl with Apache License 2.0 5 votes vote down vote up
/** Returns the MethodDescriptor for the JsFunction method. */
private static MethodDescriptor getJsFunctionMethodDescriptor(ITypeBinding typeBinding) {
  if (JsInteropUtils.isJsFunction(typeBinding)
      && typeBinding.getFunctionalInterfaceMethod() != null) {
    // typeBinding.getFunctionalInterfaceMethod returns in some cases the method declaration
    // instead of the method with the corresponding parameterization. Note: this is observed in
    // the case when a type is parameterized with a wildcard, e.g. JsFunction<?>.
    IMethodBinding jsFunctionMethodBinding =
        Arrays.stream(typeBinding.getDeclaredMethods())
            .filter(
                methodBinding ->
                    methodBinding.getMethodDeclaration()
                        == typeBinding.getFunctionalInterfaceMethod().getMethodDeclaration())
            .findFirst()
            .get();
    return createMethodDescriptor(jsFunctionMethodBinding).withoutTypeParameters();
  }

  // Find implementation method that corresponds to JsFunction.
  Optional<ITypeBinding> jsFunctionInterface =
      Arrays.stream(typeBinding.getInterfaces()).filter(JsInteropUtils::isJsFunction).findFirst();

  return jsFunctionInterface
      .map(ITypeBinding::getFunctionalInterfaceMethod)
      .flatMap(jsFunctionMethod -> getOverrideInType(typeBinding, jsFunctionMethod))
      .map(MethodDescriptor::withoutTypeParameters)
      .orElse(null);
}
 
Example 3
Source File: QuickAssistProcessor.java    From eclipse.jdt.ls with Eclipse Public License 2.0 5 votes vote down vote up
/**
 * Returns the functional interface method being implemented by the given method
 * reference.
 *
 * @param methodReference
 *            the method reference to get the functional method
 * @return the functional interface method being implemented by
 *         <code>methodReference</code> or <code>null</code> if it could not be
 *         derived
 */
public static IMethodBinding getFunctionalMethodForMethodReference(MethodReference methodReference) {
	ITypeBinding targetTypeBinding = ASTNodes.getTargetType(methodReference);
	if (targetTypeBinding == null) {
		return null;
	}

	IMethodBinding functionalMethod = targetTypeBinding.getFunctionalInterfaceMethod();
	if (functionalMethod.isSynthetic()) {
		functionalMethod = Bindings.findOverriddenMethodInType(functionalMethod.getDeclaringClass(), functionalMethod);
	}
	return functionalMethod;
}
 
Example 4
Source File: LambdaExpressionsFix.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 5 votes vote down vote up
@Override
public boolean visit(LambdaExpression node) {
	ITypeBinding typeBinding= node.resolveTypeBinding();
	if (typeBinding != null && typeBinding.getFunctionalInterfaceMethod() != null) {
		fNodes.add(node);
	}
	return true;
}
 
Example 5
Source File: LambdaExpressionsFix.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 5 votes vote down vote up
private static boolean isInTargetTypeContext(ClassInstanceCreation node) {
	ITypeBinding targetType= ASTNodes.getTargetType(node);
	return targetType != null && targetType.getFunctionalInterfaceMethod() != null;

	/*
	//TODO: probably incomplete, should reuse https://bugs.eclipse.org/bugs/show_bug.cgi?id=408966#c6
	StructuralPropertyDescriptor locationInParent= node.getLocationInParent();
	
	if (locationInParent == ReturnStatement.EXPRESSION_PROPERTY) {
		MethodDeclaration methodDeclaration= ASTResolving.findParentMethodDeclaration(node);
		if (methodDeclaration == null)
			return false;
		IMethodBinding methodBinding= methodDeclaration.resolveBinding();
		if (methodBinding == null)
			return false;
		//TODO: could also cast to the CIC type instead of aborting...
		return methodBinding.getReturnType().getFunctionalInterfaceMethod() != null;
	}
	
	//TODO: should also check whether variable is of a functional type 
	return locationInParent == SingleVariableDeclaration.INITIALIZER_PROPERTY
			|| locationInParent == VariableDeclarationFragment.INITIALIZER_PROPERTY
			|| locationInParent == Assignment.RIGHT_HAND_SIDE_PROPERTY
			|| locationInParent == ArrayInitializer.EXPRESSIONS_PROPERTY
			
			|| locationInParent == MethodInvocation.ARGUMENTS_PROPERTY
			|| locationInParent == SuperMethodInvocation.ARGUMENTS_PROPERTY
			|| locationInParent == ConstructorInvocation.ARGUMENTS_PROPERTY
			|| locationInParent == SuperConstructorInvocation.ARGUMENTS_PROPERTY
			|| locationInParent == ClassInstanceCreation.ARGUMENTS_PROPERTY
			|| locationInParent == EnumConstantDeclaration.ARGUMENTS_PROPERTY
			
			|| locationInParent == LambdaExpression.BODY_PROPERTY
			|| locationInParent == ConditionalExpression.THEN_EXPRESSION_PROPERTY
			|| locationInParent == ConditionalExpression.ELSE_EXPRESSION_PROPERTY
			|| locationInParent == CastExpression.EXPRESSION_PROPERTY;
	*/
}
 
Example 6
Source File: ASTNodes.java    From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 4 votes vote down vote up
public boolean visit(ITypeBinding type) {
	IMethodBinding[] methods= type.getDeclaredMethods();
	for (int i= 0; i < methods.length; i++) {
		IMethodBinding candidate= methods[i];
		if (candidate.getMethodDeclaration() == fOriginalMethod.getMethodDeclaration()) {
			continue;
		}
		ITypeBinding candidateDeclaringType= candidate.getDeclaringClass();
		if (fDeclaringType != candidateDeclaringType) {
			int modifiers= candidate.getModifiers();
			if (candidateDeclaringType.isInterface() && Modifier.isStatic(modifiers)) {
				continue;
			}
			if (Modifier.isPrivate(modifiers)) {
				continue;
			}
		}
		if (fOriginalMethod.getName().equals(candidate.getName()) && !fOriginalMethod.overrides(candidate)) {
			ITypeBinding[] originalParameterTypes= fOriginalMethod.getParameterTypes();
			ITypeBinding[] candidateParameterTypes= candidate.getParameterTypes();
			
			boolean couldBeAmbiguous;
			if (originalParameterTypes.length == candidateParameterTypes.length) {
				couldBeAmbiguous= true;
			} else if (fOriginalMethod.isVarargs() || candidate.isVarargs() ) {
				int candidateMinArgumentCount= candidateParameterTypes.length;
				if (candidate.isVarargs())
					candidateMinArgumentCount--;
				couldBeAmbiguous= fArgumentCount >= candidateMinArgumentCount;
			} else {
				couldBeAmbiguous= false;
			}
			if (couldBeAmbiguous) {
				ITypeBinding parameterType= ASTResolving.getParameterTypeBinding(candidate, fArgIndex);
				if (parameterType != null && parameterType.getFunctionalInterfaceMethod() != null) {
					if (!fExpressionIsExplicitlyTyped) {
						/* According to JLS8 15.12.2.2, implicitly typed lambda expressions are not "pertinent to applicability"
						 * and hence potentially applicable methods are always "applicable by strict invocation",
						 * regardless of whether argument expressions are compatible with the method's parameter types or not.
						 * If there are multiple such methods, 15.12.2.5 results in an ambiguous method invocation.
						 */
						return false;
					}
					/* Explicitly typed lambda expressions are pertinent to applicability, and hence
					 * compatibility with the corresponding method parameter type is checked. And since this check
					 * separates functional interface methods by their void-compatibility state, functional interfaces
					 * with a different void compatibility are not applicable any more and hence can't cause
					 * an ambiguous method invocation.
					 */
					ITypeBinding origParamType= ASTResolving.getParameterTypeBinding(fOriginalMethod, fArgIndex);
					boolean originalIsVoidCompatible=  Bindings.isVoidType(origParamType.getFunctionalInterfaceMethod().getReturnType());
					boolean candidateIsVoidCompatible= Bindings.isVoidType(parameterType.getFunctionalInterfaceMethod().getReturnType());
					if (originalIsVoidCompatible == candidateIsVoidCompatible) {
						return false;
					}
				}
			}
		}
	}
	return true;
}