/*
* Copyright 2014 - 2020 Rafael Winterhalter
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.bytebuddy.dynamic.scaffold;
import net.bytebuddy.build.HashCodeAndEqualsPlugin;
import net.bytebuddy.description.method.MethodDescription;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.implementation.Implementation;
import net.bytebuddy.implementation.attribute.AnnotationValueFilter;
import net.bytebuddy.implementation.bytecode.ByteCodeAppender;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
A type initializer is responsible for defining a type's static initialization block.
/**
* A type initializer is responsible for defining a type's static initialization block.
*/
public interface TypeInitializer extends ByteCodeAppender {
Indicates if this type initializer is defined.
Returns: true
if this type initializer is defined.
/**
* Indicates if this type initializer is defined.
*
* @return {@code true} if this type initializer is defined.
*/
boolean isDefined();
Expands this type initializer with another byte code appender. For this to be possible, this type initializer must
be defined.
Params: - byteCodeAppender – The byte code appender to apply as the type initializer.
Returns: A defined type initializer.
/**
* Expands this type initializer with another byte code appender. For this to be possible, this type initializer must
* be defined.
*
* @param byteCodeAppender The byte code appender to apply as the type initializer.
* @return A defined type initializer.
*/
TypeInitializer expandWith(ByteCodeAppender byteCodeAppender);
Creates a method pool record that applies this type initializer while preserving the record that was supplied.
Params: - record – The record to wrap.
Returns: A new record that represents the supplied record while also executing this type initializer.
/**
* Creates a method pool record that applies this type initializer while preserving the record that was supplied.
*
* @param record The record to wrap.
* @return A new record that represents the supplied record while also executing this type initializer.
*/
TypeWriter.MethodPool.Record wrap(TypeWriter.MethodPool.Record record);
A drain for writing a type initializer.
/**
* A drain for writing a type initializer.
*/
interface Drain {
Applies the drain.
Params: - classVisitor – The class visitor to apply the initializer to.
- typeInitializer – The type initializer to write.
- implementationContext – The corresponding implementation context.
/**
* Applies the drain.
*
* @param classVisitor The class visitor to apply the initializer to.
* @param typeInitializer The type initializer to write.
* @param implementationContext The corresponding implementation context.
*/
void apply(ClassVisitor classVisitor, TypeInitializer typeInitializer, Implementation.Context implementationContext);
A default implementation of a type initializer drain that creates a initializer method.
/**
* A default implementation of a type initializer drain that creates a initializer method.
*/
@HashCodeAndEqualsPlugin.Enhance
class Default implements Drain {
The instrumented type.
/**
* The instrumented type.
*/
protected final TypeDescription instrumentedType;
The method pool to use.
/**
* The method pool to use.
*/
protected final TypeWriter.MethodPool methodPool;
The annotation value filter factory to use.
/**
* The annotation value filter factory to use.
*/
protected final AnnotationValueFilter.Factory annotationValueFilterFactory;
Creates a new default type initializer drain.
Params: - instrumentedType – The instrumented type.
- methodPool – The method pool to use.
- annotationValueFilterFactory – The annotation value filter factory to use.
/**
* Creates a new default type initializer drain.
*
* @param instrumentedType The instrumented type.
* @param methodPool The method pool to use.
* @param annotationValueFilterFactory The annotation value filter factory to use.
*/
public Default(TypeDescription instrumentedType,
TypeWriter.MethodPool methodPool,
AnnotationValueFilter.Factory annotationValueFilterFactory) {
this.instrumentedType = instrumentedType;
this.methodPool = methodPool;
this.annotationValueFilterFactory = annotationValueFilterFactory;
}
{@inheritDoc}
/**
* {@inheritDoc}
*/
public void apply(ClassVisitor classVisitor, TypeInitializer typeInitializer, Implementation.Context implementationContext) {
typeInitializer.wrap(methodPool.target(new MethodDescription.Latent.TypeInitializer(instrumentedType))).apply(classVisitor,
implementationContext,
annotationValueFilterFactory);
}
}
}
Canonical implementation of a non-defined type initializer.
/**
* Canonical implementation of a non-defined type initializer.
*/
enum None implements TypeInitializer {
The singleton instance.
/**
* The singleton instance.
*/
INSTANCE;
{@inheritDoc}
/**
* {@inheritDoc}
*/
public boolean isDefined() {
return false;
}
{@inheritDoc}
/**
* {@inheritDoc}
*/
public TypeInitializer expandWith(ByteCodeAppender byteCodeAppenderFactory) {
return new TypeInitializer.Simple(byteCodeAppenderFactory);
}
{@inheritDoc}
/**
* {@inheritDoc}
*/
public TypeWriter.MethodPool.Record wrap(TypeWriter.MethodPool.Record record) {
return record;
}
{@inheritDoc}
/**
* {@inheritDoc}
*/
public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext, MethodDescription instrumentedMethod) {
return new Size(0, 0);
}
}
A simple, defined type initializer that executes a given ByteCodeAppender
. /**
* A simple, defined type initializer that executes a given {@link ByteCodeAppender}.
*/
@HashCodeAndEqualsPlugin.Enhance
class Simple implements TypeInitializer {
The byte code appender to apply as the type initializer.
/**
* The byte code appender to apply as the type initializer.
*/
private final ByteCodeAppender byteCodeAppender;
Creates a new simple type initializer.
Params: - byteCodeAppender – The byte code appender to apply as the type initializer.
/**
* Creates a new simple type initializer.
*
* @param byteCodeAppender The byte code appender to apply as the type initializer.
*/
public Simple(ByteCodeAppender byteCodeAppender) {
this.byteCodeAppender = byteCodeAppender;
}
{@inheritDoc}
/**
* {@inheritDoc}
*/
public boolean isDefined() {
return true;
}
{@inheritDoc}
/**
* {@inheritDoc}
*/
public TypeInitializer expandWith(ByteCodeAppender byteCodeAppender) {
return new TypeInitializer.Simple(new Compound(this.byteCodeAppender, byteCodeAppender));
}
{@inheritDoc}
/**
* {@inheritDoc}
*/
public TypeWriter.MethodPool.Record wrap(TypeWriter.MethodPool.Record record) {
return record.prepend(byteCodeAppender);
}
{@inheritDoc}
/**
* {@inheritDoc}
*/
public Size apply(MethodVisitor methodVisitor, Implementation.Context implementationContext, MethodDescription instrumentedMethod) {
return byteCodeAppender.apply(methodVisitor, implementationContext, instrumentedMethod);
}
}
}