Java Code Examples for org.codehaus.groovy.ast.MethodNode#getDeclaringClass()
The following examples show how to use
org.codehaus.groovy.ast.MethodNode#getDeclaringClass() .
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: SynchronizedASTTransformation.java From groovy with Apache License 2.0 | 6 votes |
public void visit(ASTNode[] nodes, SourceUnit source) { init(nodes, source); AnnotatedNode parent = (AnnotatedNode) nodes[1]; AnnotationNode node = (AnnotationNode) nodes[0]; if (!MY_TYPE.equals(node.getClassNode())) return; String value = getMemberStringValue(node, "value"); if (parent instanceof MethodNode) { MethodNode mNode = (MethodNode) parent; if (mNode.isAbstract()) { addError("Error during " + MY_TYPE_NAME + " processing: annotation not allowed on abstract method '" + mNode.getName() + "'", mNode); return; } ClassNode cNode = mNode.getDeclaringClass(); String lockExpr = determineLock(value, cNode, mNode); if (lockExpr == null) return; Statement origCode = mNode.getCode(); Statement newCode = new SynchronizedStatement(varX(lockExpr), origCode); mNode.setCode(newCode); } }
Example 2
Source File: ExtendedVerifier.java From groovy with Apache License 2.0 | 6 votes |
private void visitOverride(AnnotatedNode node, AnnotationNode visited) { ClassNode annotationType = visited.getClassNode(); if (annotationType.isResolved() && annotationType.getName().equals("java.lang.Override")) { if (node instanceof MethodNode && !Boolean.TRUE.equals(node.getNodeMetaData(Verifier.DEFAULT_PARAMETER_GENERATED))) { boolean override = false; MethodNode origMethod = (MethodNode) node; ClassNode cNode = origMethod.getDeclaringClass(); if (origMethod.hasDefaultValue()) { List<MethodNode> variants = cNode.getDeclaredMethods(origMethod.getName()); for (MethodNode m : variants) { if (m.getAnnotations().contains(visited) && isOverrideMethod(m)) { override = true; break; } } } else { override = isOverrideMethod(origMethod); } if (!override) { addError("Method '" + origMethod.getName() + "' from class '" + cNode.getName() + "' does not override " + "method from its superclass or interfaces but is annotated with @Override.", visited); } } } }
Example 3
Source File: Verifier.java From groovy with Apache License 2.0 | 6 votes |
private static ASTNode sourceOf(MethodNode methodNode) { if (methodNode.getLineNumber() < 1) { ClassNode declaringClass = methodNode.getDeclaringClass(); if (methodNode.isSynthetic()) { String propertyName = getPropertyName(methodNode); if (propertyName != null) { PropertyNode propertyNode = declaringClass.getProperty(propertyName); if (propertyNode != null && propertyNode.getLineNumber() > 0) { return propertyNode; } } } return declaringClass; } return methodNode; }
Example 4
Source File: MethodCallExpressionTransformer.java From groovy with Apache License 2.0 | 6 votes |
/** * Identifies a method call expression on {@link DefaultGroovyMethods#is(Object, Object)} and if recognized, transforms it into a {@link CompareIdentityExpression}. * @param call a method call to be transformed * @return null if the method call is not DGM#is, or {@link CompareIdentityExpression} */ private static Expression tryTransformIsToCompareIdentity(MethodCallExpression call) { if (call.isSafe()) return null; MethodNode methodTarget = call.getMethodTarget(); if (methodTarget instanceof ExtensionMethodNode && "is".equals(methodTarget.getName()) && methodTarget.getParameters().length==1) { methodTarget = ((ExtensionMethodNode) methodTarget).getExtensionMethodNode(); ClassNode owner = methodTarget.getDeclaringClass(); if (DGM_CLASSNODE.equals(owner)) { Expression args = call.getArguments(); if (args instanceof ArgumentListExpression) { ArgumentListExpression arguments = (ArgumentListExpression) args; List<Expression> exprs = arguments.getExpressions(); if (exprs.size() == 1) { CompareIdentityExpression cid = new CompareIdentityExpression(call.getObjectExpression(), exprs.get(0)); cid.setSourcePosition(call); return cid; } } } } return null; }
Example 5
Source File: ReadWriteLockASTTransformation.java From groovy with Apache License 2.0 | 5 votes |
public void visit(ASTNode[] nodes, SourceUnit source) { init(nodes, source); AnnotatedNode parent = (AnnotatedNode) nodes[1]; AnnotationNode node = (AnnotationNode) nodes[0]; final boolean isWriteLock; if (READ_LOCK_TYPE.equals(node.getClassNode())) { isWriteLock = false; } else if (WRITE_LOCK_TYPE.equals(node.getClassNode())) { isWriteLock = true; } else { throw new GroovyBugError("Internal error: expecting [" + READ_LOCK_TYPE.getName() + ", " + WRITE_LOCK_TYPE.getName() + "]" + " but got: " + node.getClassNode().getName()); } String myTypeName = "@" + node.getClassNode().getNameWithoutPackage(); String value = getMemberStringValue(node, "value"); if (parent instanceof MethodNode) { MethodNode mNode = (MethodNode) parent; ClassNode cNode = mNode.getDeclaringClass(); FieldNode lockExpr = determineLock(value, cNode, mNode.isStatic(), myTypeName); if (lockExpr == null) return; // get lock type final MethodCallExpression lockType = callX(varX(lockExpr), isWriteLock ? "writeLock" : "readLock"); lockType.setImplicitThis(false); MethodCallExpression acquireLock = callX(lockType, "lock"); acquireLock.setImplicitThis(false); MethodCallExpression releaseLock = callX(lockType, "unlock"); releaseLock.setImplicitThis(false); Statement originalCode = mNode.getCode(); mNode.setCode(block( stmt(acquireLock), new TryCatchStatement(originalCode, stmt(releaseLock)))); } }
Example 6
Source File: ExtendedVerifier.java From groovy with Apache License 2.0 | 5 votes |
private static boolean isOverrideMethod(MethodNode method) { ClassNode cNode = method.getDeclaringClass(); ClassNode next = cNode; outer: while (next != null) { Map<String, ClassNode> genericsSpec = createGenericsSpec(next); MethodNode mn = correctToGenericsSpec(genericsSpec, method); if (next != cNode) { ClassNode correctedNext = correctToGenericsSpecRecurse(genericsSpec, next); MethodNode found = getDeclaredMethodCorrected(genericsSpec, mn, correctedNext); if (found != null) break; } List<ClassNode> ifaces = new ArrayList<>(Arrays.asList(next.getInterfaces())); while (!ifaces.isEmpty()) { ClassNode origInterface = ifaces.remove(0); if (!origInterface.equals(ClassHelper.OBJECT_TYPE)) { genericsSpec = createGenericsSpec(origInterface, genericsSpec); ClassNode iNode = correctToGenericsSpecRecurse(genericsSpec, origInterface); MethodNode found2 = getDeclaredMethodCorrected(genericsSpec, mn, iNode); if (found2 != null) break outer; Collections.addAll(ifaces, iNode.getInterfaces()); } } ClassNode superClass = next.getUnresolvedSuperClass(); if (superClass != null) { next = correctToGenericsSpecRecurse(genericsSpec, superClass); } else { next = null; } } return next != null; }
Example 7
Source File: MopWriter.java From groovy with Apache License 2.0 | 5 votes |
/** * Creates a MOP method name from a method. * * @param method the method to be called by the mop method * @param useThis if true, then it is a call on "this", "super" else * @return the mop method name */ public static String getMopMethodName(MethodNode method, boolean useThis) { ClassNode declaringNode = method.getDeclaringClass(); int distance = 0; for (; declaringNode != null; declaringNode = declaringNode.getSuperClass()) { distance += 1; } return (useThis ? "this" : "super") + "$" + distance + "$" + method.getName(); }
Example 8
Source File: InitializerStrategy.java From groovy with Apache License 2.0 | 5 votes |
private void createBuilderForAnnotatedMethod(BuilderASTTransformation transform, MethodNode mNode, AnnotationNode anno, boolean useSetters) { if (transform.getMemberValue(anno, "includes") != null || transform.getMemberValue(anno, "excludes") != null) { transform.addError("Error during " + BuilderASTTransformation.MY_TYPE_NAME + " processing: includes/excludes only allowed on classes", anno); } if (mNode instanceof ConstructorNode) { mNode.setModifiers(ACC_PRIVATE); } else { if (!mNode.isStatic()) { transform.addError("Error during " + BuilderASTTransformation.MY_TYPE_NAME + " processing: method builders only allowed on static methods", anno); } mNode.setModifiers(ACC_SYNTHETIC | ACC_PRIVATE | ACC_STATIC); } ClassNode buildee = mNode.getDeclaringClass(); Parameter[] parameters = mNode.getParameters(); if (parameters.length == 0) { transform.addError("Error during " + BuilderASTTransformation.MY_TYPE_NAME + " processing: at least one parameter is required for this strategy", anno); } ClassNode builder = createInnerHelperClass(buildee, getBuilderClassName(buildee, anno), parameters.length); List<FieldNode> convertedFields = convertParamsToFields(builder, parameters); buildCommon(buildee, anno, convertedFields, builder); if (mNode instanceof ConstructorNode) { createBuildeeConstructors(transform, buildee, builder, convertedFields, false, useSetters); } else { createBuildeeMethods(buildee, mNode, builder, convertedFields); } }
Example 9
Source File: TraitASTTransformation.java From groovy with Apache License 2.0 | 5 votes |
private static boolean methodNeedsReplacement(ClassNode classNode, MethodNode m) { // no method found, we need to replace if (m == null) return true; // method is in current class, nothing to be done if (m.getDeclaringClass() == classNode) return false; // do not overwrite final if ((m.getModifiers() & ACC_FINAL) != 0) return false; return true; }
Example 10
Source File: StaticCompilationVisitor.java From groovy with Apache License 2.0 | 5 votes |
@Override public void visitMethod(final MethodNode node) { if (isSkipMode(node)) { node.putNodeMetaData(STATIC_COMPILE_NODE, Boolean.FALSE); } super.visitMethod(node); checkForConstructorWithCSButClassWithout(node); if (isStaticallyCompiled(node)) { ClassNode declaringClass = node.getDeclaringClass(); addDynamicOuterClassAccessorsCallback(declaringClass); } }
Example 11
Source File: DefaultTypeCheckingExtension.java From groovy with Apache License 2.0 | 5 votes |
public List<MethodNode> handleMissingMethod(final ClassNode receiver, final String name, final ArgumentListExpression argumentList, final ClassNode[] argumentTypes, final MethodCall call) { List<MethodNode> result = new LinkedList<MethodNode>(); for (TypeCheckingExtension handler : handlers) { List<MethodNode> handlerResult = handler.handleMissingMethod(receiver, name, argumentList, argumentTypes, call); for (MethodNode mn : handlerResult) { if (mn.getDeclaringClass()==null) { mn.setDeclaringClass(ClassHelper.OBJECT_TYPE); } } result.addAll(handlerResult); } return result; }
Example 12
Source File: StaticTypeCheckingSupport.java From groovy with Apache License 2.0 | 5 votes |
private static void removeMethodInSuperInterface(final List<MethodNode> toBeRemoved, final MethodNode one, final MethodNode two) { ClassNode oneDC = one.getDeclaringClass(); ClassNode twoDC = two.getDeclaringClass(); if (oneDC.implementsInterface(twoDC)) { toBeRemoved.add(two); } else { toBeRemoved.add(one); } }
Example 13
Source File: StaticInvocationWriter.java From groovy with Apache License 2.0 | 5 votes |
private boolean tryPrivateMethod(final MethodNode target, final boolean implicitThis, final Expression receiver, final TupleExpression args, final ClassNode classNode) { ClassNode declaringClass = target.getDeclaringClass(); if ((isPrivateBridgeMethodsCallAllowed(declaringClass, classNode) || isPrivateBridgeMethodsCallAllowed(classNode, declaringClass)) && declaringClass.getNodeMetaData(StaticCompilationMetadataKeys.PRIVATE_BRIDGE_METHODS) != null && !declaringClass.equals(classNode)) { if (tryBridgeMethod(target, receiver, implicitThis, args, classNode)) { return true; } else { checkAndAddCannotCallPrivateMethodError(target, receiver, classNode, declaringClass); } } checkAndAddCannotCallPrivateMethodError(target, receiver, classNode, declaringClass); return false; }
Example 14
Source File: InvocationWriter.java From groovy with Apache License 2.0 | 4 votes |
protected boolean writeDirectMethodCall(final MethodNode target, final boolean implicitThis, final Expression receiver, final TupleExpression args) { if (target == null) return false; String methodName = target.getName(); CompileStack compileStack = controller.getCompileStack(); OperandStack operandStack = controller.getOperandStack(); ClassNode declaringClass = target.getDeclaringClass(); ClassNode classNode = controller.getClassNode(); MethodVisitor mv = controller.getMethodVisitor(); int opcode = INVOKEVIRTUAL; if (target.isStatic()) { opcode = INVOKESTATIC; } else if (declaringClass.isInterface()) { opcode = INVOKEINTERFACE; } else if (target.isPrivate() || AsmClassGenerator.isSuperExpression(receiver)) { opcode = INVOKESPECIAL; } // handle receiver int argumentsToRemove = 0; if (opcode != INVOKESTATIC) { if (receiver != null) { // load receiver if not static invocation // todo: fix inner class case if (implicitThis && classNode.getOuterClass() != null && !classNode.isDerivedFrom(declaringClass) && !classNode.implementsInterface(declaringClass)) { // we are calling an outer class method compileStack.pushImplicitThis(false); if (controller.isInGeneratedFunction()) { new VariableExpression("thisObject").visit(controller.getAcg()); } else { Expression expr = new PropertyExpression(new ClassExpression(declaringClass), "this"); expr.visit(controller.getAcg()); } } else { compileStack.pushImplicitThis(implicitThis); receiver.visit(controller.getAcg()); } operandStack.doGroovyCast(declaringClass); compileStack.popImplicitThis(); argumentsToRemove += 1; } else { mv.visitIntInsn(ALOAD,0); operandStack.push(classNode); argumentsToRemove += 1; } } int stackSize = operandStack.getStackLength(); String owner = BytecodeHelper.getClassInternalName(declaringClass); ClassNode receiverType = receiver != null ? controller.getTypeChooser().resolveType(receiver, classNode) : declaringClass; if (opcode == INVOKEVIRTUAL && ClassHelper.OBJECT_TYPE.equals(declaringClass)) { // avoid using a narrowed type if the method is defined on object because it can interfere // with delegate type inference in static compilation mode and trigger a ClassCastException receiverType = declaringClass; } if (opcode == INVOKEVIRTUAL) { if (!receiverType.equals(declaringClass) && !ClassHelper.OBJECT_TYPE.equals(declaringClass) && !receiverType.isArray() && !receiverType.isInterface() && !ClassHelper.isPrimitiveType(receiverType) // e.g int.getClass() && receiverType.isDerivedFrom(declaringClass)) { owner = BytecodeHelper.getClassInternalName(receiverType); ClassNode top = operandStack.getTopOperand(); if (!receiverType.equals(top)) { mv.visitTypeInsn(CHECKCAST, owner); } } else if (target.isPublic() && (!receiverType.equals(declaringClass) && !Modifier.isPublic(declaringClass.getModifiers())) && receiverType.isDerivedFrom(declaringClass) && !Objects.equals(receiverType.getPackageName(), classNode.getPackageName())) { // GROOVY-6962: package private class, public method owner = BytecodeHelper.getClassInternalName(receiverType); } } loadArguments(args.getExpressions(), target.getParameters()); String desc = BytecodeHelper.getMethodDescriptor(target.getReturnType(), target.getParameters()); mv.visitMethodInsn(opcode, owner, methodName, desc, declaringClass.isInterface()); ClassNode ret = target.getReturnType().redirect(); if (ret == ClassHelper.VOID_TYPE) { ret = ClassHelper.OBJECT_TYPE; mv.visitInsn(ACONST_NULL); } argumentsToRemove += (operandStack.getStackLength()-stackSize); controller.getOperandStack().remove(argumentsToRemove); controller.getOperandStack().push(ret); return true; }
Example 15
Source File: StaticCompileTransformation.java From groovy with Apache License 2.0 | 4 votes |
@Override public void visit(final ASTNode[] nodes, final SourceUnit source) { AnnotationNode annotationInformation = (AnnotationNode) nodes[0]; AnnotatedNode node = (AnnotatedNode) nodes[1]; StaticTypeCheckingVisitor visitor = null; Map<String,Expression> members = annotationInformation.getMembers(); Expression extensions = members.get("extensions"); if (node instanceof ClassNode) { ClassNode classNode = (ClassNode) node; visitor = newVisitor(source, classNode); visitor.setCompilationUnit(compilationUnit); addTypeCheckingExtensions(visitor, extensions); classNode.putNodeMetaData(WriterControllerFactory.class, factory); node.putNodeMetaData(STATIC_COMPILE_NODE, !visitor.isSkipMode(node)); visitor.initialize(); visitor.visitClass(classNode); } else if (node instanceof MethodNode) { MethodNode methodNode = (MethodNode) node; ClassNode declaringClass = methodNode.getDeclaringClass(); visitor = newVisitor(source, declaringClass); visitor.setCompilationUnit(compilationUnit); addTypeCheckingExtensions(visitor, extensions); methodNode.putNodeMetaData(STATIC_COMPILE_NODE, !visitor.isSkipMode(node)); if (declaringClass.getNodeMetaData(WriterControllerFactory.class) == null) { declaringClass.putNodeMetaData(WriterControllerFactory.class, factory); } visitor.setMethodsToBeVisited(Collections.singleton(methodNode)); visitor.initialize(); visitor.visitMethod(methodNode); } else { source.addError(new SyntaxException(STATIC_ERROR_PREFIX + "Unimplemented node type", node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber())); } if (visitor != null) { visitor.performSecondPass(); } StaticCompilationTransformer transformer = new StaticCompilationTransformer(source, visitor); if (node instanceof ClassNode) { transformer.visitClass((ClassNode) node); } else if (node instanceof MethodNode) { transformer.visitMethod((MethodNode) node); } }
Example 16
Source File: MemoizedASTTransformation.java From groovy with Apache License 2.0 | 4 votes |
public void visit(ASTNode[] nodes, final SourceUnit source) { init(nodes, source); AnnotationNode annotationNode = (AnnotationNode) nodes[0]; AnnotatedNode annotatedNode = (AnnotatedNode) nodes[1]; if (MY_TYPE.equals(annotationNode.getClassNode()) && annotatedNode instanceof MethodNode) { MethodNode methodNode = (MethodNode) annotatedNode; if (methodNode.isAbstract()) { addError("Annotation " + MY_TYPE_NAME + " cannot be used for abstract methods.", methodNode); return; } if (methodNode.isVoidMethod()) { addError("Annotation " + MY_TYPE_NAME + " cannot be used for void methods.", methodNode); return; } ClassNode ownerClassNode = methodNode.getDeclaringClass(); MethodNode delegatingMethod = buildDelegatingMethod(methodNode, ownerClassNode); addGeneratedMethod(ownerClassNode, delegatingMethod); int modifiers = FieldNode.ACC_PRIVATE | FieldNode.ACC_FINAL; if (methodNode.isStatic()) { modifiers = modifiers | FieldNode.ACC_STATIC; } int protectedCacheSize = getMemberIntValue(annotationNode, PROTECTED_CACHE_SIZE_NAME); int maxCacheSize = getMemberIntValue(annotationNode, MAX_CACHE_SIZE_NAME); MethodCallExpression memoizeClosureCallExpression = buildMemoizeClosureCallExpression(delegatingMethod, protectedCacheSize, maxCacheSize); String memoizedClosureFieldName = buildUniqueName(ownerClassNode, CLOSURE_LABEL, methodNode); FieldNode memoizedClosureField = new FieldNode(memoizedClosureFieldName, modifiers, newClass(ClassHelper.CLOSURE_TYPE), null, memoizeClosureCallExpression); ownerClassNode.addField(memoizedClosureField); BlockStatement newCode = new BlockStatement(); MethodCallExpression closureCallExpression = callX( fieldX(memoizedClosureField), CLOSURE_CALL_METHOD_NAME, args(methodNode.getParameters())); closureCallExpression.setImplicitThis(false); newCode.addStatement(returnS(closureCallExpression)); methodNode.setCode(newCode); VariableScopeVisitor visitor = new VariableScopeVisitor(source, ownerClassNode instanceof InnerClassNode); if (ownerClassNode instanceof InnerClassNode) { visitor.visitClass(((InnerClassNode) ownerClassNode).getOuterMostClass()); } else { visitor.visitClass(ownerClassNode); } } }
Example 17
Source File: StaticTypeCheckingSupport.java From groovy with Apache License 2.0 | 4 votes |
/** * Filter methods according to visibility * * @param methodNodeList method nodes to filter * @param enclosingClassNode the enclosing class * @return filtered method nodes * @since 3.0.0 */ public static List<MethodNode> filterMethodsByVisibility(final List<MethodNode> methodNodeList, final ClassNode enclosingClassNode) { if (!asBoolean(methodNodeList)) { return StaticTypeCheckingVisitor.EMPTY_METHODNODE_LIST; } List<MethodNode> result = new LinkedList<>(); boolean isEnclosingInnerClass = enclosingClassNode instanceof InnerClassNode; List<ClassNode> outerClasses = enclosingClassNode.getOuterClasses(); outer: for (MethodNode methodNode : methodNodeList) { if (methodNode instanceof ExtensionMethodNode) { result.add(methodNode); continue; } ClassNode declaringClass = methodNode.getDeclaringClass(); if (isEnclosingInnerClass) { for (ClassNode outerClass : outerClasses) { if (outerClass.isDerivedFrom(declaringClass)) { if (outerClass.equals(declaringClass)) { result.add(methodNode); continue outer; } else { if (methodNode.isPublic() || methodNode.isProtected()) { result.add(methodNode); continue outer; } } } } } if (declaringClass instanceof InnerClassNode) { if (declaringClass.getOuterClasses().contains(enclosingClassNode)) { result.add(methodNode); continue; } } if (methodNode.isPrivate() && !enclosingClassNode.equals(declaringClass)) { continue; } if (methodNode.isProtected() && !enclosingClassNode.isDerivedFrom(declaringClass) && !samePackageName(enclosingClassNode, declaringClass)) { continue; } if (methodNode.isPackageScope() && !samePackageName(enclosingClassNode, declaringClass)) { continue; } result.add(methodNode); } return result; }
Example 18
Source File: ClassCompletionVerifier.java From groovy with Apache License 2.0 | 4 votes |
private void checkNoStaticMethodWithSameSignatureAsNonStatic(final ClassNode node) { ClassNode parent = node.getSuperClass(); Map<String, MethodNode> result; // start with methods from the parent if any if (parent != null) { result = parent.getDeclaredMethodsMap(); } else { result = new HashMap<String, MethodNode>(); } // add in unimplemented abstract methods from the interfaces ClassNodeUtils.addDeclaredMethodsFromInterfaces(node, result); for (MethodNode methodNode : node.getMethods()) { MethodNode mn = result.get(methodNode.getTypeDescriptor()); if (mn != null && (mn.isStatic() ^ methodNode.isStatic()) && !methodNode.isStaticConstructor()) { if (!mn.isAbstract()) continue; ClassNode declaringClass = mn.getDeclaringClass(); ClassNode cn = declaringClass.getOuterClass(); if (cn == null && declaringClass.isResolved()) { // in case of a precompiled class, the outerclass is unknown Class typeClass = declaringClass.getTypeClass(); typeClass = typeClass.getEnclosingClass(); if (typeClass != null) { cn = ClassHelper.make(typeClass); } } if (!Traits.isTrait(cn)) { ASTNode errorNode = methodNode; String name = mn.getName(); if (errorNode.getLineNumber() == -1) { // try to get a better error message location based on the property for (PropertyNode propertyNode : node.getProperties()) { if (name.startsWith("set") || name.startsWith("get") || name.startsWith("is")) { String propName = Verifier.capitalize(propertyNode.getField().getName()); String shortName = name.substring(name.startsWith("is") ? 2 : 3); if (propName.equals(shortName)) { errorNode = propertyNode; break; } } } } addError("The " + getDescription(methodNode) + " is already defined in " + getDescription(node) + ". You cannot have both a static and an instance method with the same signature", errorNode); } } result.put(methodNode.getTypeDescriptor(), methodNode); } }
Example 19
Source File: StaticTypeCheckingSupport.java From groovy with Apache License 2.0 | 4 votes |
private static boolean areOverloadMethodsInSameClass(final MethodNode one, final MethodNode two) { return (one.getName().equals(two.getName()) && one.getDeclaringClass() == two.getDeclaringClass()); }
Example 20
Source File: StaticTypeCheckingSupport.java From groovy with Apache License 2.0 | 4 votes |
/** * Given a list of candidate methods, returns the one which best matches the argument types * * @param receiver * @param methods candidate methods * @param argumentTypes argument types * @return the list of methods which best matches the argument types. It is still possible that multiple * methods match the argument types. */ public static List<MethodNode> chooseBestMethod(final ClassNode receiver, final Collection<MethodNode> methods, final ClassNode... argumentTypes) { if (methods.isEmpty()) return Collections.emptyList(); if (isUsingUncheckedGenerics(receiver)) { ClassNode raw = makeRawType(receiver); return chooseBestMethod(raw, methods, argumentTypes); } List<MethodNode> bestChoices = new LinkedList<>(); int bestDist = Integer.MAX_VALUE; Collection<MethodNode> choicesLeft = removeCovariantsAndInterfaceEquivalents(methods); for (MethodNode candidateNode : choicesLeft) { ClassNode declaringClassForDistance = candidateNode.getDeclaringClass(); ClassNode actualReceiverForDistance = receiver != null ? receiver : candidateNode.getDeclaringClass(); MethodNode safeNode = candidateNode; ClassNode[] safeArgs = argumentTypes; boolean isExtensionMethodNode = candidateNode instanceof ExtensionMethodNode; if (isExtensionMethodNode) { safeArgs = new ClassNode[argumentTypes.length + 1]; System.arraycopy(argumentTypes, 0, safeArgs, 1, argumentTypes.length); safeArgs[0] = receiver; safeNode = ((ExtensionMethodNode) candidateNode).getExtensionMethodNode(); } // todo : corner case /* class B extends A {} Animal foo(A o) {...} Person foo(B i){...} B a = new B() Person p = foo(b) */ Map<GenericsType, GenericsType> declaringAndActualGenericsTypeMap = GenericsUtils.makeDeclaringAndActualGenericsTypeMap(declaringClassForDistance, actualReceiverForDistance); Parameter[] params = makeRawTypes(safeNode.getParameters(), declaringAndActualGenericsTypeMap); int dist = measureParametersAndArgumentsDistance(params, safeArgs); if (dist >= 0) { dist += getClassDistance(declaringClassForDistance, actualReceiverForDistance); dist += getExtensionDistance(isExtensionMethodNode); if (dist < bestDist) { bestChoices.clear(); bestChoices.add(candidateNode); bestDist = dist; } else if (dist == bestDist) { bestChoices.add(candidateNode); } } } if (bestChoices.size() > 1) { // GROOVY-6849: prefer extension methods in case of ambiguity List<MethodNode> onlyExtensionMethods = new LinkedList<>(); for (MethodNode choice : bestChoices) { if (choice instanceof ExtensionMethodNode) { onlyExtensionMethods.add(choice); } } if (onlyExtensionMethods.size() == 1) { return onlyExtensionMethods; } } return bestChoices; }