All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.bytebuddy.implementation.bytecode.assign.Assigner Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2014 - Present 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.implementation.bytecode.assign;

import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.implementation.bytecode.StackManipulation;
import net.bytebuddy.implementation.bytecode.assign.primitive.PrimitiveTypeAwareAssigner;
import net.bytebuddy.implementation.bytecode.assign.primitive.VoidAwareAssigner;
import net.bytebuddy.implementation.bytecode.assign.reference.GenericTypeAwareAssigner;
import net.bytebuddy.implementation.bytecode.assign.reference.ReferenceTypeAwareAssigner;

/**
 * An assigner is responsible for converting some type {@code A} to another type {@code B} if possible.
 * 

 

* An assigner is for example responsible for type casting, auto boxing or unboxing or for the widening of primitive * types. */ @SuppressFBWarnings(value = "IC_SUPERCLASS_USES_SUBCLASS_DURING_INITIALIZATION", justification = "Safe initialization is implied.") public interface Assigner { /** * A default assigner that can handle {@code void}, primitive types and reference types which considers generic types as raw types. */ Assigner DEFAULT = new VoidAwareAssigner(new PrimitiveTypeAwareAssigner(ReferenceTypeAwareAssigner.INSTANCE)); /** * A generics-aware assigner that can handle {@code void}, primitive types which reference types. */ Assigner GENERICS_AWARE = new VoidAwareAssigner(new PrimitiveTypeAwareAssigner(GenericTypeAwareAssigner.INSTANCE)); /** * @param source The original type that is to be transformed into the {@code targetType}. * @param target The target type into which the {@code sourceType} is to be converted. * @param typing A hint whether the assignment should consider the runtime type of the source type, * i.e. if type down or cross castings are allowed. If this hint is set, this is * also an indication that {@code void} to non-{@code void} assignments are permitted. * @return A stack manipulation that transforms the {@code sourceType} into the {@code targetType} if this * is possible. An illegal stack manipulation otherwise. */ StackManipulation assign(TypeDescription.Generic source, TypeDescription.Generic target, Typing typing); /** * Indicates for a type assignment, if a type casting should be applied in case that two types are not statically assignable. * Also, a dynamic typing indicates that void values are assignable to other types by assigning the target type's default value. */ enum Typing { /** * Requires static typing. */ STATIC(false), /** * Allows dynamic typing. */ DYNAMIC(true); /** * {@code true} if dynamic typing is a legitimate choice. */ private final boolean dynamic; /** * Creates a new typing hint. * * @param dynamic {@code true} if dynamic typing is a legitimate choice. */ Typing(boolean dynamic) { this.dynamic = dynamic; } /** * Resolves a typing constant for the presented boolean where {@code true} indicates that dynamic typing is a legitimate choice. * * @param dynamic An indicator for if dynamic typing is a legitimate choice. * @return A corresponding typing constant. */ public static Typing of(boolean dynamic) { return dynamic ? DYNAMIC : STATIC; } /** * Checks if this instance's typing behavior permits dynamic typing. * * @return {@code true} if dynamic typing is a legitimate choice. */ public boolean isDynamic() { return dynamic; } } /** * An assigner that only allows to assign types if they are equal to another. */ enum EqualTypesOnly implements Assigner { /** * An type assigner that only considers equal generic types to be assignable. */ GENERIC { /** {@inheritDoc} */ public StackManipulation assign(TypeDescription.Generic source, TypeDescription.Generic target, Typing typing) { return source.equals(target) ? StackManipulation.Trivial.INSTANCE : StackManipulation.Illegal.INSTANCE; } }, /** * A type assigner that considers two generic types to be equal if their erasure is equal. */ ERASURE { /** {@inheritDoc} */ public StackManipulation assign(TypeDescription.Generic source, TypeDescription.Generic target, Typing typing) { return source.asErasure().equals(target.asErasure()) ? StackManipulation.Trivial.INSTANCE : StackManipulation.Illegal.INSTANCE; } } } /** * An assigner that does not allow any assignments. */ enum Refusing implements Assigner { /** * The singleton instance. */ INSTANCE; /** * {@inheritDoc} */ public StackManipulation assign(TypeDescription.Generic source, TypeDescription.Generic target, Typing typing) { return StackManipulation.Illegal.INSTANCE; } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy