pascal.taie.analysis.pta.plugin.reflection.MetaObjHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tai-e Show documentation
Show all versions of tai-e Show documentation
An easy-to-learn/use static analysis framework for Java
The newest version!
/*
* Tai-e: A Static Analysis Framework for Java
*
* Copyright (C) 2022 Tian Tan
* Copyright (C) 2022 Yue Li
*
* This file is part of Tai-e.
*
* Tai-e is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* Tai-e is distributed in the hope that it will be useful,but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
* Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with Tai-e. If not, see .
*/
package pascal.taie.analysis.pta.plugin.reflection;
import pascal.taie.analysis.pta.core.cs.element.CSObj;
import pascal.taie.analysis.pta.core.heap.Descriptor;
import pascal.taie.analysis.pta.core.heap.HeapModel;
import pascal.taie.analysis.pta.core.heap.Obj;
import pascal.taie.analysis.pta.core.solver.Solver;
import pascal.taie.analysis.pta.plugin.util.CSObjs;
import pascal.taie.ir.exp.ClassLiteral;
import pascal.taie.ir.stmt.Invoke;
import pascal.taie.language.annotation.Annotation;
import pascal.taie.language.classes.ClassMember;
import pascal.taie.language.classes.ClassNames;
import pascal.taie.language.classes.JClass;
import pascal.taie.language.classes.JField;
import pascal.taie.language.classes.JMethod;
import pascal.taie.language.type.ClassType;
import pascal.taie.language.type.Type;
import pascal.taie.language.type.TypeSystem;
import javax.annotation.Nullable;
import java.util.Objects;
import java.util.Set;
/**
* Helps manage reflection and annotation objects.
*/
class MetaObjHelper {
/**
* Descriptor for the meta objects generated by reflection inference.
*/
private static final Descriptor REFLECTION_DESC = () -> "ReflectionMetaObj";
/**
* Descriptor for the meta objects generated by reflection log.
*/
private static final Descriptor REFLECTION_LOG_DESC = () -> "ReflectionLogMetaObj";
/**
* Descriptor for the array objects generated by
* Class.get[Declared][Constructor|Method|Field]s().
*/
private static final Descriptor REFLECTION_ARRAY_DESC = () -> "ReflectionMetaObjArray";
/**
* Descriptor for unknown meta objects.
*/
private static final Descriptor UNKNOWN_REFLECTION_DESC = () -> "UnknownReflectionMetaObj";
/**
* Descriptor for annotation objects.
*/
private static final Descriptor ANNOTATION_DESC = () -> "AnnotationObj";
private final TypeSystem typeSystem;
private final HeapModel heapModel;
final ClassType clazz;
final ClassType constructor;
final ClassType method;
final ClassType field;
MetaObjHelper(Solver solver) {
typeSystem = solver.getTypeSystem();
heapModel = solver.getHeapModel();
clazz = typeSystem.getClassType(ClassNames.CLASS);
constructor = typeSystem.getClassType(ClassNames.CONSTRUCTOR);
method = typeSystem.getClassType(ClassNames.METHOD);
field = typeSystem.getClassType(ClassNames.FIELD);
}
/**
* Given a JClass, Type, or ClassMember, return the corresponding meta object.
* @throws IllegalArgumentException if type of {@code classOrTypeOrMember}
* is neither {@link JClass}, {@link Type}, nor {@link ClassMember}.
*/
Obj getMetaObj(Object classOrTypeOrMember) {
return getMetaObj(classOrTypeOrMember, REFLECTION_DESC);
}
Obj getLogMetaObj(Object classOrTypeOrMember) {
return getMetaObj(classOrTypeOrMember, REFLECTION_LOG_DESC);
}
boolean isLogMetaObj(CSObj obj) {
return CSObjs.hasDescriptor(obj, REFLECTION_LOG_DESC);
}
private Obj getMetaObj(Object classOrTypeOrMember, Descriptor desc) {
if (classOrTypeOrMember instanceof JClass jclass) {
ClassLiteral classLiteral = ClassLiteral.get(jclass.getType());
return desc.equals(REFLECTION_LOG_DESC)
? heapModel.getMockObj(desc, classLiteral, clazz)
: heapModel.getConstantObj(classLiteral);
} else if (classOrTypeOrMember instanceof Type type) {
ClassLiteral classLiteral = ClassLiteral.get(type);
return desc.equals(REFLECTION_LOG_DESC)
? heapModel.getMockObj(desc, classLiteral, clazz)
: heapModel.getConstantObj(classLiteral);
} else if (classOrTypeOrMember instanceof JMethod m) {
if (m.isConstructor()) {
return heapModel.getMockObj(desc, classOrTypeOrMember, constructor);
} else {
return heapModel.getMockObj(desc, classOrTypeOrMember, method);
}
} else if (classOrTypeOrMember instanceof JField) {
return heapModel.getMockObj(desc, classOrTypeOrMember, field);
} else {
throw new IllegalArgumentException(
"Expected JClass or ClassMember," + " given " + classOrTypeOrMember);
}
}
Obj getMetaObjArray(Invoke invoke) {
assert Set.of("getConstructors", "getDeclaredConstructors",
"getMethods", "getDeclaredMethods",
"getFields", "getDeclaredFields").contains(invoke.getMethodRef().getName());
return heapModel.getMockObj(REFLECTION_ARRAY_DESC, invoke,
invoke.getMethodRef().getReturnType(), invoke.getContainer());
}
/**
* @return an unknown class generated at {@code invoke}.
*/
Obj getUnknownClass(Invoke invoke) {
return heapModel.getMockObj(UNKNOWN_REFLECTION_DESC, invoke, clazz, false);
}
Obj getUnknownMethod(Invoke invoke, @Nullable JClass clazz, @Nullable String name) {
MethodInfo methodInfo = new MethodInfo(invoke, clazz, name);
return heapModel.getMockObj(UNKNOWN_REFLECTION_DESC, methodInfo, method,
invoke.getContainer(), false);
}
MethodInfo getMethodInfo(CSObj csObj) {
return (MethodInfo) csObj.getObject().getAllocation();
}
boolean isUnknownMetaObj(CSObj csObj) {
return CSObjs.hasDescriptor(csObj, UNKNOWN_REFLECTION_DESC);
}
Obj getAnnotationObj(Annotation annotation) {
ClassType type = typeSystem.getClassType(annotation.getType());
Objects.requireNonNull(type,
"Annotation type" + annotation.getType() + " is not found");
return heapModel.getMockObj(ANNOTATION_DESC, annotation, type);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy