/** * Matches a default constructor, i.e. a constructor without arguments. * * @param <T> The type of the matched object. * @return A matcher that matches a default constructor. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> isDefaultConstructor() { return isConstructor().and(takesArguments(0)); }
/** * Only matches the {@link Object#clone()} method, also if it was overridden. * * @param <T> The type of the matched object. * @return A matcher that only matches the {@link Object#clone()} method. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> isClone() { return named("clone").and(takesArguments(0)); }
@Override protected ElementMatcher.Junction<MethodDescription> getExtraMethodElementMatcher() { return named("_eval").and(takesArguments(Environment.class)); }
/** * Only matches the {@link Object#toString()} method, also if it was overridden. * * @param <T> The type of the matched object. * @return A matcher that only matches the {@link Object#toString()} method. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> isHashCode() { return named("hashCode").and(takesArguments(0)).and(returns(int.class)); }
/** * Only matches the {@link Object#equals(Object)} method, also if it was overridden. * * @param <T> The type of the matched object. * @return A matcher that only matches the {@link Object#equals(Object)} method. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> isEquals() { return named("equals").and(takesArguments(TypeDescription.OBJECT)).and(returns(boolean.class)); }
/** * Only matches the {@link Object#toString()} method, also if it was overridden. * * @param <T> The type of the matched object. * @return A matcher that only matches the {@link Object#toString()} method. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> isToString() { return named("toString").and(takesArguments(0)).and(returns(TypeDescription.STRING)); }
/** * Matches any Java bean setter method. * * @param <T> The type of the matched object. * @return A matcher that matches any setter method. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> isSetter() { return nameStartsWith("set").and(takesArguments(1)).and(returns(TypeDescription.VOID)); }
/** * Only matches the {@link Object#finalize()} method, even if it was overridden. * * @param <T> The type of the matched object. * @return A matcher that only matches the {@link Object#finalize()} method. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> isFinalizer() { return named("finalize").and(takesArguments(0)).and(returns(TypeDescription.VOID)); }
/** * Creates a new construction delegate that calls a default constructor. * * @param throwableType The type of the {@link Throwable}. */ public ForDefaultConstructor(TypeDescription throwableType) { this.throwableType = throwableType; this.targetConstructor = throwableType.getDeclaredMethods() .filter(isConstructor().and(takesArguments(0))).getOnly(); }
/** * Creates a new construction delegate that calls a constructor by handing it the given string. * * @param throwableType The type of the {@link Throwable}. * @param message The string that is handed to the constructor. */ public ForStringConstructor(TypeDescription throwableType, String message) { this.throwableType = throwableType; this.targetConstructor = throwableType.getDeclaredMethods() .filter(isConstructor().and(takesArguments(String.class))).getOnly(); this.message = message; }
@Override protected ElementMatcher.Junction<MethodDescription> getExtraMethodElementMatcher() { return named("getConnection") .and(returns(Connection.class)) .and(isPublic()) .and(takesArguments(String.class, String.class).or(takesArguments(0))); }
@Override protected ElementMatcher.Junction<MethodDescription> getMethodElementMatcher() { return named("postProcessBeforeInitialization") .and(returns(Object.class)) .and(takesArguments(Object.class, String.class)); }
@Override protected List<MethodDescription.Token> doExtractConstructors(TypeDescription instrumentedType) { TypeDescription.Generic superClass = instrumentedType.getSuperClass(); MethodList<?> defaultConstructors = superClass == null ? new MethodList.Empty<MethodDescription.InGenericShape>() : superClass.getDeclaredMethods().filter(isConstructor().and(takesArguments(0)).<MethodDescription>and(isVisibleTo(instrumentedType))); if (defaultConstructors.size() == 1) { return Collections.singletonList(new MethodDescription.Token(Opcodes.ACC_PUBLIC)); } else { throw new IllegalArgumentException(instrumentedType.getSuperClass() + " declares no constructor that is visible to " + instrumentedType); } }
/** * Creates the singleton instance. */ @SuppressFBWarnings(value = "SE_BAD_FIELD_STORE", justification = "Fields of enumerations are never serialized") AbstractMethodErrorThrow() { TypeDescription abstractMethodError = TypeDescription.ForLoadedType.of(AbstractMethodError.class); MethodDescription constructor = abstractMethodError.getDeclaredMethods() .filter(isConstructor().and(takesArguments(0))).getOnly(); implementation = new Compound(TypeCreation.of(abstractMethodError), Duplication.SINGLE, MethodInvocation.invoke(constructor), Throw.INSTANCE); }
/** * {@inheritDoc} */ public MethodRegistry inject(TypeDescription instrumentedType, MethodRegistry methodRegistry) { MethodList<?> candidates = instrumentedType.getSuperClass().getDeclaredMethods().filter(isConstructor().and(elementMatcher)); if (candidates.isEmpty()) { throw new IllegalStateException("No possible candidate for super constructor invocation in " + instrumentedType.getSuperClass()); } else if (!candidates.filter(takesArguments(0)).isEmpty()) { candidates = candidates.filter(takesArguments(0)); } else if (candidates.size() > 1) { throw new IllegalStateException("More than one possible super constructor for constructor delegation: " + candidates); } MethodCall methodCall = MethodCall.invoke(candidates.getOnly()); for (TypeDescription typeDescription : candidates.getOnly().getParameters().asTypeList().asErasures()) { methodCall = methodCall.with(typeDescription.getDefaultValue()); } return methodRegistry.append(new LatentMatcher.Resolved<MethodDescription>(isConstructor().and(takesArguments(0))), new MethodRegistry.Handler.ForImplementation(methodCall), methodAttributeAppenderFactory, Transformer.NoOp.<MethodDescription>make()); } }
/** * Matches any Java bean getter method. * * @param <T> The type of the matched object. * @return A matcher that matches any getter method. */ public static <T extends MethodDescription> ElementMatcher.Junction<T> isGetter() { return takesArguments(0).and(not(returns(TypeDescription.VOID))).and(nameStartsWith("get").or(nameStartsWith("is").and(returnsGeneric(anyOf(boolean.class, Boolean.class))))); }
/** * {@inheritDoc} */ public ByteCodeAppender appender(Target implementationTarget) { return new Appender(targetMethod.getOwnerType() .getDeclaredMethods() .filter(hasMethodName(targetMethod.getName()) .and(returns(targetMethod.getReturnType())) .and(takesArguments(targetMethod.getParameterTypes()))) .getOnly(), specializedLambdaMethod, implementationTarget.getInstrumentedType().getDeclaredFields()); }
/** * {@inheritDoc} */ public Compiled compile(TypeDescription instrumentedType) { MethodList<?> targets = new MethodList.Explicit<MethodDescription>(CompoundList.<MethodDescription>of( instrumentedType.getDeclaredMethods().filter(isStatic().or(isPrivate())), methodGraphCompiler.compile(instrumentedType).listNodes().asMethodList()) ).filter(named(name).and(takesArguments(0)).and(not(returns(isPrimitive().or(isArray()))))); if (targets.size() != 1) { throw new IllegalStateException(instrumentedType + " does not define method without arguments with name " + name + ": " + targets); } else if (!targets.getOnly().getReturnType().asErasure().isVisibleTo(instrumentedType)) { throw new IllegalStateException(targets.getOnly() + " is not visible to " + instrumentedType); } else { MethodList<?> candidates = methodGraphCompiler.compile(targets.getOnly().getReturnType(), instrumentedType) .listNodes() .asMethodList() .filter(matcher); List<MethodDelegationBinder.Record> records = new ArrayList<MethodDelegationBinder.Record>(candidates.size()); MethodDelegationBinder methodDelegationBinder = TargetMethodAnnotationDrivenBinder.of(parameterBinders); for (MethodDescription candidate : candidates) { records.add(methodDelegationBinder.compile(candidate)); } return new Compiled.ForMethodReturn(targets.get(0), records); } }
/** * {@inheritDoc} */ public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext) { TypeDescription proxyType = implementationContext.register(new TypeProxy(proxiedType, implementationTarget, InvocationFactory.Default.SUPER_METHOD, ignoreFinalizer, serializableProxy)); return new Compound( MethodInvocation.invoke(proxyType.getDeclaredMethods().filter(named(REFLECTION_METHOD).and(takesArguments(0))).getOnly()), Duplication.SINGLE, MethodVariableAccess.loadThis(), FieldAccess.forField(proxyType.getDeclaredFields().filter((named(INSTANCE_FIELD))).getOnly()).write() ).apply(methodVisitor, implementationContext); } }
/** * Creates a matcher where only overridable or declared methods are matched unless those are ignored. Methods that * are declared by the target type are only matched if they are not ignored. Declared methods that are not found on the * target type are always matched. * * @param ignoredMethods A method matcher that matches any ignored method. * @param originalType The original type of the instrumentation before adding any user methods. * @return A latent method matcher that identifies any method to instrument for a rebasement or redefinition. */ protected static LatentMatcher<MethodDescription> of(LatentMatcher<? super MethodDescription> ignoredMethods, TypeDescription originalType) { ElementMatcher.Junction<MethodDescription> predefinedMethodSignatures = none(); for (MethodDescription methodDescription : originalType.getDeclaredMethods()) { ElementMatcher.Junction<MethodDescription> signature = methodDescription.isConstructor() ? isConstructor() : ElementMatchers.<MethodDescription>named(methodDescription.getName()); signature = signature.and(returns(methodDescription.getReturnType().asErasure())); signature = signature.and(takesArguments(methodDescription.getParameters().asTypeList().asErasures())); predefinedMethodSignatures = predefinedMethodSignatures.or(signature); } return new InliningImplementationMatcher(ignoredMethods, predefinedMethodSignatures); }