Class SpoonUtil
java.lang.Object
de.firemage.autograder.core.integrated.SpoonUtil
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordSpoonUtil.FilterAdapter<T extends spoon.reflect.declaration.CtElement,U extends spoon.reflect.declaration.CtElement> static class -
Method Summary
Modifier and TypeMethodDescriptionstatic booleanareLiteralsEqual(spoon.reflect.code.CtLiteral<?> left, spoon.reflect.code.CtLiteral<?> right) static <T> spoon.reflect.code.CtExpression<T>castExpression(Class<T> targetType, spoon.reflect.code.CtExpression<?> ctExpression) static <T,E extends spoon.reflect.code.CtExpression<T>>
EcastExpression(spoon.reflect.reference.CtTypeReference<T> type, spoon.reflect.code.CtExpression<?> ctExpression) static <T,R> spoon.reflect.code.CtLiteral<R> castLiteral(spoon.reflect.reference.CtTypeReference<R> type, spoon.reflect.code.CtLiteral<T> literal) static <T> spoon.reflect.code.CtBinaryOperator<T>createBinaryOperator(spoon.reflect.code.CtExpression<?> leftHandOperand, spoon.reflect.code.CtExpression<?> rightHandOperand, spoon.reflect.code.BinaryOperatorKind operatorKind) static <T> spoon.reflect.code.CtInvocation<T>createStaticInvocation(spoon.reflect.reference.CtTypeReference<?> targetType, String methodName, spoon.reflect.code.CtExpression<?>... parameters) Creates a static invocation of the given method on the given target type.static <T> spoon.reflect.code.CtUnaryOperator<T>createUnaryOperator(spoon.reflect.code.UnaryOperatorKind operatorKind, spoon.reflect.code.CtExpression<?> ctExpression) static spoon.reflect.declaration.CtElementfindCommonParent(spoon.reflect.declaration.CtElement firstElement, Iterable<? extends spoon.reflect.declaration.CtElement> others) Finds the closest common parent of the given elements.static spoon.reflect.cu.SourcePositionfindPosition(spoon.reflect.declaration.CtElement ctElement) static List<spoon.reflect.declaration.CtElement>findUses(spoon.reflect.declaration.CtElement ctElement) static List<spoon.reflect.declaration.CtElement>findUsesIn(spoon.reflect.declaration.CtElement ctElement, spoon.reflect.declaration.CtElement in) Finds all uses ofctElementinin.static <T> List<spoon.reflect.declaration.CtElement>findUsesOf(spoon.reflect.declaration.CtExecutable<T> ctExecutable) static List<spoon.reflect.declaration.CtElement>findUsesOf(spoon.reflect.declaration.CtTypeMember ctTypeMember) static <T> List<spoon.reflect.code.CtVariableAccess<T>>findUsesOf(spoon.reflect.declaration.CtVariable<T> ctVariable) static StringformatSourcePosition(spoon.reflect.cu.SourcePosition sourcePosition) Converts the provided source position into a human-readable string.getCasesEffects(Iterable<? extends spoon.reflect.code.CtCase<?>> ctCases) static <T> Optional<spoon.reflect.code.CtExpression<T>>getEffectivelyFinalExpression(spoon.reflect.declaration.CtVariable<T> ctVariable) static List<spoon.reflect.code.CtStatement>getEffectiveStatements(spoon.reflect.code.CtStatement ctStatement) static List<spoon.reflect.code.CtExpression<?>>getElementsOfExpression(spoon.reflect.code.CtExpression<?> ctExpression) static <T> spoon.reflect.reference.CtTypeReference<?>getExpressionType(spoon.reflect.code.CtExpression<T> ctExpression) static Optional<spoon.reflect.code.CtJavaDoc>getJavadoc(spoon.reflect.declaration.CtElement element) static spoon.reflect.cu.SourcePositiongetNamePosition(spoon.reflect.declaration.CtNamedElement ctNamedElement) static List<spoon.reflect.code.CtStatement>getNextStatements(spoon.reflect.code.CtStatement ctStatement) static Optional<spoon.reflect.code.CtStatement>getPreviousStatement(spoon.reflect.code.CtStatement ctStatement) Finds the statement that is before the given statement if possible.static spoon.reflect.declaration.CtElementgetReferenceDeclaration(spoon.reflect.reference.CtReference ctReference) getSingleEffect(Collection<? extends spoon.reflect.code.CtStatement> ctStatements) static booleanhasAnyUses(spoon.reflect.declaration.CtElement ctElement, Predicate<? super spoon.reflect.declaration.CtElement> predicate) static booleanhasAnyUsesIn(spoon.reflect.declaration.CtElement ctElement, spoon.reflect.declaration.CtElement toSearchIn, Predicate<? super spoon.reflect.declaration.CtElement> predicate) static booleanisBoolean(spoon.reflect.declaration.CtTypedElement<?> ctTypedElement) static booleanisEffectivelyFinal(spoon.reflect.declaration.CtVariable<?> ctVariable) static booleanisGetter(spoon.reflect.declaration.CtMethod<?> method) static <T> booleanisImmutable(spoon.reflect.reference.CtTypeReference<T> ctTypeReference) Checks if the given element is guaranteed to be immutable.static booleanstatic booleanisInMainMethod(spoon.reflect.declaration.CtElement ctElement) static booleanisInnerClass(spoon.reflect.declaration.CtTypeMember type) Checks if the given type is an inner class.static booleanisInOverriddenMethod(spoon.reflect.declaration.CtElement ctElement) static booleanisInSetter(spoon.reflect.declaration.CtElement ctElement) static booleanisIntegerLiteral(spoon.reflect.code.CtExpression<?> expression, int value) static booleanisInvocation(spoon.reflect.code.CtStatement statement) Checks if the given method is overriding another method.static booleanisMainMethod(spoon.reflect.declaration.CtMethod<?> method) static booleanisNullLiteral(spoon.reflect.code.CtExpression<?> expression) static booleanisOverriddenMethod(spoon.reflect.declaration.CtMethod<?> ctMethod) Checks if the given method is overriding another method.static booleanisPrimitiveNumeric(spoon.reflect.reference.CtTypeReference<?> type) static booleanisSetter(spoon.reflect.declaration.CtMethod<?> method) static booleanisSignatureEqualTo(spoon.reflect.reference.CtExecutableReference<?> ctExecutableReference, Class<?> returnType, String methodName, Class<?>... parameterTypes) static booleanisSignatureEqualTo(spoon.reflect.reference.CtExecutableReference<?> ctExecutableReference, spoon.reflect.reference.CtTypeReference<?> returnType, String methodName, spoon.reflect.reference.CtTypeReference<?>... parameterTypes) static booleanisStaticCallTo(spoon.reflect.code.CtInvocation<?> invocation, String typeName, String methodName) static booleanisString(spoon.reflect.reference.CtTypeReference<?> type) static booleanisStringLiteral(spoon.reflect.code.CtExpression<?> expression, String value) static booleanisSubtypeOf(spoon.reflect.reference.CtTypeReference<?> ctTypeReference, Class<?> expected) static Optional<spoon.reflect.reference.CtTypeReference<?>>isToStringCall(spoon.reflect.code.CtExpression<?> expression) static booleanisTypeEqualTo(spoon.reflect.reference.CtTypeReference<?> ctType, Class<?>... expected) Checks if the given type is equal to any of the expected types.static booleanisTypeEqualTo(spoon.reflect.reference.CtTypeReference<?> ctType, spoon.reflect.reference.CtTypeReference<?>... expected) Checks if the given type is equal to any of the expected types.static <T> spoon.reflect.code.CtLiteral<T>makeLiteral(spoon.reflect.reference.CtTypeReference<T> ctTypeReference, T value) Makes a new literal with the given value and type.static <T> spoon.reflect.code.CtLiteral<T>makeLiteralNumber(spoon.reflect.reference.CtTypeReference<T> ctTypeReference, Number number) static <T> spoon.reflect.code.CtLiteral<T>maximumValue(spoon.reflect.code.CtLiteral<T> ctLiteral) static <T> spoon.reflect.code.CtLiteral<T>minimumValue(spoon.reflect.code.CtLiteral<T> ctLiteral) static <T> spoon.reflect.code.CtExpression<T>negate(spoon.reflect.code.CtExpression<T> ctExpression) static <T> spoon.reflect.code.CtBinaryOperator<T>normalizeBy(BiPredicate<? super spoon.reflect.code.CtExpression<?>, ? super spoon.reflect.code.CtExpression<?>> shouldSwap, spoon.reflect.code.CtBinaryOperator<T> ctBinaryOperator) Converts a binary operator like < to <= or > to >= and adjusts the operands accordingly to make finding patterns on them easier by not having to special-case them.static <T> spoon.reflect.code.CtExpression<T>resolveConstant(spoon.reflect.code.CtExpression<T> ctExpression) ReplacesCtVariableReadin the provided expression if they are effectively final and their value is known.static <T> spoon.reflect.code.CtExpression<T>resolveCtExpression(spoon.reflect.code.CtExpression<T> ctExpression) static <T> spoon.reflect.code.CtBinaryOperator<T>swapCtBinaryOperator(spoon.reflect.code.CtBinaryOperator<T> ctBinaryOperator) Swaps the operands of a binary operator.tryGetBooleanLiteral(spoon.reflect.code.CtExpression<?> expression) tryGetStringLiteral(spoon.reflect.code.CtExpression<?> expression) tryMakeEffect(spoon.reflect.code.CtStatement ctStatement) static spoon.reflect.code.CtStatementunwrapStatement(spoon.reflect.code.CtStatement statement) Extracts a nested statement from a block if possible.static voidvisitCtCompilationUnit(spoon.reflect.CtModel ctModel, Consumer<? super spoon.reflect.declaration.CtCompilationUnit> lambda)
-
Method Details
-
isInJunitTest
public static boolean isInJunitTest() -
isString
public static boolean isString(spoon.reflect.reference.CtTypeReference<?> type) -
isToStringCall
public static Optional<spoon.reflect.reference.CtTypeReference<?>> isToStringCall(spoon.reflect.code.CtExpression<?> expression) -
isStringLiteral
-
isNullLiteral
public static boolean isNullLiteral(spoon.reflect.code.CtExpression<?> expression) -
isIntegerLiteral
public static boolean isIntegerLiteral(spoon.reflect.code.CtExpression<?> expression, int value) -
isBoolean
public static boolean isBoolean(spoon.reflect.declaration.CtTypedElement<?> ctTypedElement) -
tryGetBooleanLiteral
-
tryGetStringLiteral
-
areLiteralsEqual
public static boolean areLiteralsEqual(spoon.reflect.code.CtLiteral<?> left, spoon.reflect.code.CtLiteral<?> right) -
makeLiteralNumber
public static <T> spoon.reflect.code.CtLiteral<T> makeLiteralNumber(spoon.reflect.reference.CtTypeReference<T> ctTypeReference, Number number) -
makeLiteral
public static <T> spoon.reflect.code.CtLiteral<T> makeLiteral(spoon.reflect.reference.CtTypeReference<T> ctTypeReference, T value) Makes a new literal with the given value and type.- Type Parameters:
T- the type of the value- Parameters:
ctTypeReference- a reference to the type of the literalvalue- the value of the literal- Returns:
- a new literal with the given value, note that the base is not set
-
getElementsOfExpression
public static List<spoon.reflect.code.CtExpression<?>> getElementsOfExpression(spoon.reflect.code.CtExpression<?> ctExpression) -
minimumValue
public static <T> spoon.reflect.code.CtLiteral<T> minimumValue(spoon.reflect.code.CtLiteral<T> ctLiteral) -
maximumValue
public static <T> spoon.reflect.code.CtLiteral<T> maximumValue(spoon.reflect.code.CtLiteral<T> ctLiteral) -
createBinaryOperator
public static <T> spoon.reflect.code.CtBinaryOperator<T> createBinaryOperator(spoon.reflect.code.CtExpression<?> leftHandOperand, spoon.reflect.code.CtExpression<?> rightHandOperand, spoon.reflect.code.BinaryOperatorKind operatorKind) -
createUnaryOperator
public static <T> spoon.reflect.code.CtUnaryOperator<T> createUnaryOperator(spoon.reflect.code.UnaryOperatorKind operatorKind, spoon.reflect.code.CtExpression<?> ctExpression) -
swapCtBinaryOperator
public static <T> spoon.reflect.code.CtBinaryOperator<T> swapCtBinaryOperator(spoon.reflect.code.CtBinaryOperator<T> ctBinaryOperator) Swaps the operands of a binary operator.- Type Parameters:
T- the type the operator evaluates to- Parameters:
ctBinaryOperator- the operator to swap, can be of any kind- Returns:
- the cloned version with the operands swapped or the given operator if it is not supported
-
resolveConstant
public static <T> spoon.reflect.code.CtExpression<T> resolveConstant(spoon.reflect.code.CtExpression<T> ctExpression) ReplacesCtVariableReadin the provided expression if they are effectively final and their value is known.Additionally, it will fix broken operators that do not have a type.
- Type Parameters:
T- the type of the expression- Parameters:
ctExpression- the expression to resolve. If it isnull, thennullis returned- Returns:
- the resolved expression. It will be cloned and detached from the
CtModel
-
normalizeBy
public static <T> spoon.reflect.code.CtBinaryOperator<T> normalizeBy(BiPredicate<? super spoon.reflect.code.CtExpression<?>, ? super spoon.reflect.code.CtExpression<?>> shouldSwap, spoon.reflect.code.CtBinaryOperator<T> ctBinaryOperator) Converts a binary operator like < to <= or > to >= and adjusts the operands accordingly to make finding patterns on them easier by not having to special-case them. Additionally, one can specify a predicate to swap the operands if necessary. For example, to ensure that a literal is always on the right-hand side.- Type Parameters:
T- the type the operator evaluates to- Parameters:
shouldSwap- the left and right hands are passed to it, and it should return true if they should be swapped and false if nothing should be changedctBinaryOperator- the operator to normalize, can be of any kind- Returns:
- the normalized operator or the given operator if it is not supported
-
negate
public static <T> spoon.reflect.code.CtExpression<T> negate(spoon.reflect.code.CtExpression<T> ctExpression) -
getEffectiveStatements
public static List<spoon.reflect.code.CtStatement> getEffectiveStatements(spoon.reflect.code.CtStatement ctStatement) -
resolveCtExpression
public static <T> spoon.reflect.code.CtExpression<T> resolveCtExpression(spoon.reflect.code.CtExpression<T> ctExpression) -
unwrapStatement
public static spoon.reflect.code.CtStatement unwrapStatement(spoon.reflect.code.CtStatement statement) Extracts a nested statement from a block if possible.A statement might be in a block
{ statement }. This method will extract the statement from the block and return it.- Parameters:
statement- the statement to unwrap- Returns:
- the given statement or an unwrapped version if possible
-
isGetter
public static boolean isGetter(spoon.reflect.declaration.CtMethod<?> method) -
isSetter
public static boolean isSetter(spoon.reflect.declaration.CtMethod<?> method) -
isInSetter
public static boolean isInSetter(spoon.reflect.declaration.CtElement ctElement) -
isPrimitiveNumeric
public static boolean isPrimitiveNumeric(spoon.reflect.reference.CtTypeReference<?> type) -
isSignatureEqualTo
-
isSignatureEqualTo
public static boolean isSignatureEqualTo(spoon.reflect.reference.CtExecutableReference<?> ctExecutableReference, spoon.reflect.reference.CtTypeReference<?> returnType, String methodName, spoon.reflect.reference.CtTypeReference<?>... parameterTypes) -
createStaticInvocation
public static <T> spoon.reflect.code.CtInvocation<T> createStaticInvocation(spoon.reflect.reference.CtTypeReference<?> targetType, String methodName, spoon.reflect.code.CtExpression<?>... parameters) Creates a static invocation of the given method on the given target type.- Type Parameters:
T- the result type of the invocation- Parameters:
targetType- the type on which the method is definedmethodName- the name of the methodparameters- the parameters to pass to the method- Returns:
- the invocation
-
castExpression
public static <T> spoon.reflect.code.CtExpression<T> castExpression(Class<T> targetType, spoon.reflect.code.CtExpression<?> ctExpression) -
castLiteral
public static <T,R> spoon.reflect.code.CtLiteral<R> castLiteral(spoon.reflect.reference.CtTypeReference<R> type, spoon.reflect.code.CtLiteral<T> literal) -
getExpressionType
public static <T> spoon.reflect.reference.CtTypeReference<?> getExpressionType(spoon.reflect.code.CtExpression<T> ctExpression) -
castExpression
public static <T,E extends spoon.reflect.code.CtExpression<T>> E castExpression(spoon.reflect.reference.CtTypeReference<T> type, spoon.reflect.code.CtExpression<?> ctExpression) -
getJavadoc
public static Optional<spoon.reflect.code.CtJavaDoc> getJavadoc(spoon.reflect.declaration.CtElement element) -
isStaticCallTo
-
isEffectivelyFinal
public static boolean isEffectivelyFinal(spoon.reflect.declaration.CtVariable<?> ctVariable) -
getEffectivelyFinalExpression
public static <T> Optional<spoon.reflect.code.CtExpression<T>> getEffectivelyFinalExpression(spoon.reflect.declaration.CtVariable<T> ctVariable) -
isImmutable
public static <T> boolean isImmutable(spoon.reflect.reference.CtTypeReference<T> ctTypeReference) Checks if the given element is guaranteed to be immutable.Note that when this method returns
false, the type might still be immutable.- Type Parameters:
T- the type of the element- Parameters:
ctTypeReference- the type to check- Returns:
- true if the given element is guaranteed to be immutable, false otherwise
-
isTypeEqualTo
public static boolean isTypeEqualTo(spoon.reflect.reference.CtTypeReference<?> ctType, Class<?>... expected) Checks if the given type is equal to any of the expected types.- Parameters:
ctType- the type to checkexpected- all allowed types- Returns:
- true if the given type is equal to any of the expected types, false otherwise
-
isTypeEqualTo
public static boolean isTypeEqualTo(spoon.reflect.reference.CtTypeReference<?> ctType, spoon.reflect.reference.CtTypeReference<?>... expected) Checks if the given type is equal to any of the expected types.- Parameters:
ctType- the type to checkexpected- all allowed types- Returns:
- true if the given type is equal to any of the expected types, false otherwise
-
isSubtypeOf
public static boolean isSubtypeOf(spoon.reflect.reference.CtTypeReference<?> ctTypeReference, Class<?> expected) -
isMainMethod
public static boolean isMainMethod(spoon.reflect.declaration.CtMethod<?> method) -
visitCtCompilationUnit
public static void visitCtCompilationUnit(spoon.reflect.CtModel ctModel, Consumer<? super spoon.reflect.declaration.CtCompilationUnit> lambda) -
findCommonParent
public static spoon.reflect.declaration.CtElement findCommonParent(spoon.reflect.declaration.CtElement firstElement, Iterable<? extends spoon.reflect.declaration.CtElement> others) Finds the closest common parent of the given elements.- Parameters:
firstElement- the first element to find the common parent ofothers- any amount of other elements to find the common parent of- Returns:
- the closest common parent of the given elements or the firstElement itself if others is empty
-
isInnerClass
public static boolean isInnerClass(spoon.reflect.declaration.CtTypeMember type) Checks if the given type is an inner class.- Parameters:
type- the type to check, not null- Returns:
- true if the given type is an inner class, false otherwise
-
isOverriddenMethod
public static boolean isOverriddenMethod(spoon.reflect.declaration.CtMethod<?> ctMethod) Checks if the given method is overriding another method.This implies that there is another method in a super class or interface that has the same signature.
- Parameters:
ctMethod- the method to check, must not be null- Returns:
- true if the given method is overriding another method, false otherwise
-
isInOverriddenMethod
public static boolean isInOverriddenMethod(spoon.reflect.declaration.CtElement ctElement) -
isInvocation
public static boolean isInvocation(spoon.reflect.code.CtStatement statement) Checks if the given method is overriding another method.- Parameters:
statement- which is checked- Returns:
- true if the statement is an invocation (instance of CtInvocation, CtConstructorCall or CtLambda), false otherwise
-
isInMainMethod
public static boolean isInMainMethod(spoon.reflect.declaration.CtElement ctElement) -
findUsesIn
public static List<spoon.reflect.declaration.CtElement> findUsesIn(spoon.reflect.declaration.CtElement ctElement, spoon.reflect.declaration.CtElement in) Finds all uses ofctElementinin.- Parameters:
ctElement- the element to search forin- the element to search in- Returns:
- all uses of
ctElementinin
-
getReferenceDeclaration
public static spoon.reflect.declaration.CtElement getReferenceDeclaration(spoon.reflect.reference.CtReference ctReference) -
findUsesOf
public static <T> List<spoon.reflect.code.CtVariableAccess<T>> findUsesOf(spoon.reflect.declaration.CtVariable<T> ctVariable) -
findUsesOf
public static List<spoon.reflect.declaration.CtElement> findUsesOf(spoon.reflect.declaration.CtTypeMember ctTypeMember) -
findUsesOf
public static <T> List<spoon.reflect.declaration.CtElement> findUsesOf(spoon.reflect.declaration.CtExecutable<T> ctExecutable) -
hasAnyUses
public static boolean hasAnyUses(spoon.reflect.declaration.CtElement ctElement, Predicate<? super spoon.reflect.declaration.CtElement> predicate) -
hasAnyUsesIn
public static boolean hasAnyUsesIn(spoon.reflect.declaration.CtElement ctElement, spoon.reflect.declaration.CtElement toSearchIn, Predicate<? super spoon.reflect.declaration.CtElement> predicate) -
findUses
public static List<spoon.reflect.declaration.CtElement> findUses(spoon.reflect.declaration.CtElement ctElement) -
getPreviousStatement
public static Optional<spoon.reflect.code.CtStatement> getPreviousStatement(spoon.reflect.code.CtStatement ctStatement) Finds the statement that is before the given statement if possible.- Parameters:
ctStatement- the statement to find the previous statement of, must not be null- Returns:
- the previous statement or an empty optional if there is no previous statement
-
getNextStatements
public static List<spoon.reflect.code.CtStatement> getNextStatements(spoon.reflect.code.CtStatement ctStatement) -
tryMakeEffect
-
getSingleEffect
public static Optional<Effect> getSingleEffect(Collection<? extends spoon.reflect.code.CtStatement> ctStatements) -
getCasesEffects
-
findPosition
public static spoon.reflect.cu.SourcePosition findPosition(spoon.reflect.declaration.CtElement ctElement) -
formatSourcePosition
Converts the provided source position into a human-readable string.- Parameters:
sourcePosition- the source position as given by spoon- Returns:
- a human-readable string representation of the source position
-
getNamePosition
public static spoon.reflect.cu.SourcePosition getNamePosition(spoon.reflect.declaration.CtNamedElement ctNamedElement)
-