Top Description Inners Fields Constructors Methods
org.codehaus.groovy.ast.tools

public Class WideningCategories

extends Object
Class Inheritance
Imports
org.codehaus.groovy.ast.ClassNode, .GenericsType, java.util.ArrayList, .Arrays, .Collection, .Collections, .Comparator, .HashSet, .LinkedList, .List, .Map, .Set, .StringJoiner

This class provides helper methods to determine the type from a widening operation for example for a plus operation.

To determine the resulting type of for example a=exp1+exp2 we look at the conditions isIntCategory(ClassNode), isLongCategory(ClassNode), isBigIntCategory(ClassNode), isDoubleCategory(ClassNode) and isBigDecCategory(ClassNode) in that order. The first case applying to exp1 and exp2 is defining the result type of the expression.

If for example you look at x = 1 + 2l we have the first category applying to the number 1 being int, since the 1 is an int. The 2l is a long, therefore the int category will not apply and the result type can't be int. The next category in the list is long, and since both apply to long, the result type is a long.

Nested and Inner Type Summary

Modifier and TypeClass and Description
public static class
WideningCategories.LowestUpperBoundClassNode

This ClassNode specialization is used when the lowest upper bound of two types cannot be represented by an existing type.

Field Summary

Modifier and TypeField and Description
private static final Comparator<ClassNode>
INTERFACE_CLASSNODE_COMPARATOR

A comparator which is used in case we generate a virtual lower upper bound class node.

private static final Map<ClassNode, Integer>

Constructor Summary

AccessConstructor and Description
public

Method Summary

Modifier and TypeMethod and Description
private static void
addMostSpecificInterface(final ClassNode interfaceNode, final List<ClassNode> nodes)

private static boolean

Returns:

true if the class nodes are equal, false otherwise
areEqualWithGenerics
(final ClassNode a, final ClassNode b)

Compares two class nodes, but including their generics types.

private static ClassNode

Returns:

the class node representing the lowest upper bound
buildTypeWithInterfaces
(final ClassNode baseType1, final ClassNode baseType2, final Collection<ClassNode>
interfaces both class nodes share, which their lowest common super class do not implement.
interfaces
)

Given two class nodes supposedly at the upper common level, returns a class node which is able to represent their lowest upper bound.

private static void
private static ClassNode
public static boolean
implementsInterfaceOrSubclassOf(final ClassNode source, final ClassNode target)

Determines if the source class implements an interface or subclasses the target type.

public static boolean
isBigDecCategory(final ClassNode type)

Checks if type is a BigDecimal, BigInteger, long, int, byte, char or short.

public static boolean
isBigIntCategory(final ClassNode type)

Checks if type is a BigInteger, long, int, byte, char or short.

public static boolean
isDouble(final ClassNode type)

Checks if type is a double.

public static boolean
isDoubleCategory(final ClassNode type)

Checks if type is a float, double or BigDecimal (category).

public static boolean
isFloat(final ClassNode type)

Checks if type is a float.

public static boolean
isFloatingCategory(final ClassNode type)

Checks if type is a float or double.

public static boolean
isInt(final ClassNode type)

Checks if type is an int.

public static boolean
isIntCategory(final ClassNode type)

Checks if type is an int, byte, char or short.

public static boolean
isLongCategory(final ClassNode type)

Checks if type is a long, int, byte, char or short.

public static boolean
isNumberCategory(final ClassNode type)

Checks if type is a BigDecimal (category) or Number.

private static List<ClassNode>
keepLowestCommonInterfaces(final Set<ClassNode> fromA, final Set<ClassNode> fromB)

Given the interfaces implemented by two types, returns a list of the most specific common implemented interfaces.

public static ClassNode
lowestUpperBound(final List<ClassNode> nodes)

Given a list of types, returns the first common supertype.

public static ClassNode
lowestUpperBound(final ClassNode a, final ClassNode b)

Given two types, returns the first common supertype, or the class itself if there are equal.

private static ClassNode
lowestUpperBound(final ClassNode a, final ClassNode b, Set<ClassNode> interfacesImplementedByA, Set<ClassNode> interfacesImplementedByB)

private static ClassNode

Returns:

the class node representing the parameterized lowest upper bound
parameterizeLowestUpperBound
(final ClassNode
the type to be parameterized
lub
,
final ClassNode
parameterized type a
a
,
final ClassNode
parameterized type b
b
,
final ClassNode
if we detect a recursive call, use this LUB as the parameterized type instead of computing a value
fallback
)

Given a lowest upper bound computed without generic type information but which requires to be parameterized and the two implementing classnodes which are parameterized with potentially two different types, returns a parameterized lowest upper bound.

private static ClassNode
Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

INTERFACE_CLASSNODE_COMPARATORback to summary
private static final Comparator<ClassNode> INTERFACE_CLASSNODE_COMPARATOR

A comparator which is used in case we generate a virtual lower upper bound class node. In that case, since a concrete implementation should be used at compile time, we must ensure that interfaces are always sorted. It is not important what sort is used, as long as the result is constant.

NUMBER_TYPES_PRECEDENCEback to summary
private static final Map<ClassNode, Integer> NUMBER_TYPES_PRECEDENCE

Constructor Detail

WideningCategoriesback to summary
public WideningCategories()

Method Detail

addMostSpecificInterfaceback to summary
private static void addMostSpecificInterface(final ClassNode interfaceNode, final List<ClassNode> nodes)
areEqualWithGenericsback to summary
private static boolean areEqualWithGenerics(final ClassNode a, final ClassNode b)

Compares two class nodes, but including their generics types.

Returns:boolean

true if the class nodes are equal, false otherwise

buildTypeWithInterfacesback to summary
private static ClassNode buildTypeWithInterfaces(final ClassNode baseType1, final ClassNode baseType2, final Collection<ClassNode> interfaces)

Given two class nodes supposedly at the upper common level, returns a class node which is able to represent their lowest upper bound.

Parameters
interfaces:Collection<ClassNode>

interfaces both class nodes share, which their lowest common super class do not implement.

Returns:ClassNode

the class node representing the lowest upper bound

extractMostSpecificImplementedInterfacesback to summary
private static void extractMostSpecificImplementedInterfaces(final ClassNode type, final ClassNode inode, final List<ClassNode> result)
findGenericsTypeHolderForClassback to summary
private static ClassNode findGenericsTypeHolderForClass(ClassNode source, final ClassNode target)
implementsInterfaceOrSubclassOfback to summary
public static boolean implementsInterfaceOrSubclassOf(final ClassNode source, final ClassNode target)

Determines if the source class implements an interface or subclasses the target type. This method takes the lowest upper bound class node type into account, allowing removal of unnecessary casts.

Since
2.3.0
isBigDecCategoryback to summary
public static boolean isBigDecCategory(final ClassNode type)

Checks if type is a BigDecimal, BigInteger, long, int, byte, char or short.

Since
2.0.0
isBigIntCategoryback to summary
public static boolean isBigIntCategory(final ClassNode type)

Checks if type is a BigInteger, long, int, byte, char or short.

Since
2.0.0
isDoubleback to summary
public static boolean isDouble(final ClassNode type)

Checks if type is a double.

Since
2.0.0
isDoubleCategoryback to summary
public static boolean isDoubleCategory(final ClassNode type)

Checks if type is a float, double or BigDecimal (category).

Since
2.0.0
isFloatback to summary
public static boolean isFloat(final ClassNode type)

Checks if type is a float.

Since
2.0.0
isFloatingCategoryback to summary
public static boolean isFloatingCategory(final ClassNode type)

Checks if type is a float or double.

Since
2.0.0
isIntback to summary
public static boolean isInt(final ClassNode type)

Checks if type is an int.

Since
2.0.0
isIntCategoryback to summary
public static boolean isIntCategory(final ClassNode type)

Checks if type is an int, byte, char or short.

Since
2.0.0
isLongCategoryback to summary
public static boolean isLongCategory(final ClassNode type)

Checks if type is a long, int, byte, char or short.

Since
2.0.0
isNumberCategoryback to summary
public static boolean isNumberCategory(final ClassNode type)

Checks if type is a BigDecimal (category) or Number.

Since
2.0.0
keepLowestCommonInterfacesback to summary
private static List<ClassNode> keepLowestCommonInterfaces(final Set<ClassNode> fromA, final Set<ClassNode> fromB)

Given the interfaces implemented by two types, returns a list of the most specific common implemented interfaces.

lowestUpperBoundback to summary
public static ClassNode lowestUpperBound(final List<ClassNode> nodes)

Given a list of types, returns the first common supertype. For example, Double and Float would return Number, while Set and String would return Object.

Since
2.0.0
lowestUpperBoundback to summary
public static ClassNode lowestUpperBound(final ClassNode a, final ClassNode b)

Given two types, returns the first common supertype, or the class itself if there are equal. For example, Double and Float would return Number, while Set and String would return Object.

This method is not guaranteed to return a class node which corresponds to a real type. For example, if two types have more than one interface in common and are not in the same hierarchy branch, then the returned type will be a virtual type implementing all those interfaces.

Calls to this method are supposed to be made with resolved generics. This means that you can have wildcards, but no placeholder.

Since
2.0.0
lowestUpperBoundback to summary
private static ClassNode lowestUpperBound(final ClassNode a, final ClassNode b, Set<ClassNode> interfacesImplementedByA, Set<ClassNode> interfacesImplementedByB)
parameterizeLowestUpperBoundback to summary
private static ClassNode parameterizeLowestUpperBound(final ClassNode lub, final ClassNode a, final ClassNode b, final ClassNode fallback)

Given a lowest upper bound computed without generic type information but which requires to be parameterized and the two implementing classnodes which are parameterized with potentially two different types, returns a parameterized lowest upper bound. For example, if LUB is Set<T> and a is Set<String> and b is Set<StringBuffer>, this will return a LUB which parameterized type matches Set<? extends CharSequence>

Parameters
lub:ClassNode

the type to be parameterized

a:ClassNode

parameterized type a

b:ClassNode

parameterized type b

fallback:ClassNode

if we detect a recursive call, use this LUB as the parameterized type instead of computing a value

Returns:ClassNode

the class node representing the parameterized lowest upper bound

upperBoundback to summary
private static ClassNode upperBound(final GenericsType gt)
org.codehaus.groovy.ast.tools back to summary

public Class WideningCategories.LowestUpperBoundClassNode

extends ClassNode
Class Inheritance

This ClassNode specialization is used when the lowest upper bound of two types cannot be represented by an existing type. For example, if B extends A, C extends A and both C and B implement a common interface not implemented by A, then we use this class to represent the bound. At compile time, some classes like org.codehaus.groovy.classgen.AsmClassGenerator need to know about a real class node, so we compute a "compile time" node which will be used to return a name and a type class.

Field Summary

Modifier and TypeField and Description
private final ClassNode
private final ClassNode[]
private final String
private final String
private final ClassNode
Inherited from org.codehaus.groovy.ast.ClassNode:
clazzEMPTY_ARRAYinnerClassesisPrimaryNodelazyInitLockSUPERTHIS

Constructor Summary

AccessConstructor and Description
public
LowestUpperBoundClassNode(final String name, final ClassNode upper, final ClassNode... interfaces)

Method Summary

Modifier and TypeMethod and Description
public GenericsType
public String
public String
public ClassNode
public String
public Class<T>
getTypeClass()

Overrides org.codehaus.groovy.ast.ClassNode.getTypeClass.

Returns the concrete class this classnode relates to.
public int
hashCode()

Overrides org.codehaus.groovy.ast.ClassNode.hashCode.

Returns a hash code value for the object.
Inherited from org.codehaus.groovy.ast.ClassNode:
addConstructoraddConstructoraddFieldaddFieldaddFieldFirstaddFieldFirstaddInterfaceaddMethodaddMethodaddMixinaddObjectInitializerStatementsaddPropertyaddPropertyaddStaticInitializerStatementsaddSyntheticMethodaddTransformdeclaresAnyInterfacesdeclaresInterfaceequalsgetAbstractMethodsgetAllDeclaredMethodsgetAllInterfacesgetAnnotationsgetAnnotationsgetCompileUnitgetComponentTypegetDeclaredConstructorgetDeclaredConstructorsgetDeclaredFieldgetDeclaredMethodgetDeclaredMethodsgetDeclaredMethodsMapgetEnclosingMethodgetFieldgetFieldIndexgetFieldsgetGenericsTypesgetGetterMethodgetGetterMethodgetInnerClassesgetInterfacesgetMethodgetMethodsgetMethodsgetMixinsgetModifiersgetModulegetNameWithoutPackagegetObjectInitializerStatementsgetOuterClassgetOuterClassesgetOuterFieldgetPackagegetPackageNamegetPropertiesgetPropertygetSetterMethodgetSetterMethodgetSuperClassgetTransformsgetUnresolvedInterfacesgetUnresolvedInterfacesgetUnresolvedNamegetUnresolvedSuperClassgetUnresolvedSuperClasshasDeclaredMethodhasMethodhasPackageNamehasPossibleMethodhasPossibleStaticMethodhasPropertyimplementsAnyInterfacesimplementsInterfaceisAbstractisAnnotatedisAnnotationDefinitionisArrayisDerivedFromisDerivedFromGroovyObjectisEnumisGenericsPlaceHolderisInterfaceisPrimaryClassNodeisRedirectNodeisResolvedisScriptisScriptBodyisStaticClassisSyntheticPublicisUsingGenericsmakeArrayparametersEqualpositionStmtsAfterEnumInitStmtsredirectremoveConstructorremoveFieldremoveMethodrenameFieldsetAnnotatedsetCompileUnitsetEnclosingMethodsetGenericsPlaceHoldersetGenericsTypessetInterfacessetMixinssetModifierssetModulesetNamesetRedirectsetScriptsetScriptBodysetStaticClasssetSuperClasssetSyntheticPublicsetUnresolvedSuperClasssetUsingGenericstoStringtoStringtryFindPossibleMethodvisitContents

Field Detail

compileTimeClassNodeback to summary
private final ClassNode compileTimeClassNode
interfacesback to summary
private final ClassNode[] interfaces

Hides org.codehaus.groovy.ast.ClassNode.interfaces.

nameback to summary
private final String name

Hides org.codehaus.groovy.ast.ClassNode.name.

textback to summary
private final String text
upperback to summary
private final ClassNode upper

Constructor Detail

LowestUpperBoundClassNodeback to summary
public LowestUpperBoundClassNode(final String name, final ClassNode upper, final ClassNode... interfaces)

Method Detail

asGenericsTypeback to summary
public GenericsType asGenericsType()

Overrides org.codehaus.groovy.ast.ClassNode.asGenericsType.

Annotations
@Override
getLubNameback to summary
public String getLubName()
getNameback to summary
public String getName()

Overrides org.codehaus.groovy.ast.ClassNode.getName.

Annotations
@Override
getPlainNodeReferenceback to summary
public ClassNode getPlainNodeReference()

Overrides org.codehaus.groovy.ast.ClassNode.getPlainNodeReference.

Annotations
@Override
getTextback to summary
public String getText()

Overrides org.codehaus.groovy.ast.ClassNode.getText.

Annotations
@Override
getTypeClassback to summary
public Class<T> getTypeClass()

Overrides org.codehaus.groovy.ast.ClassNode.getTypeClass.

Doc from org.codehaus.groovy.ast.ClassNode.getTypeClass.

Returns the concrete class this classnode relates to. However, this method is inherently unsafe as it may return null depending on the compile phase you are using. AST transformations should never use this method directly, but rather obtain a new class node using getPlainNodeReference().

Returns:Class<T>

the class this classnode relates to. May return null.

Annotations
@Override
hashCodeback to summary
public int hashCode()

Overrides org.codehaus.groovy.ast.ClassNode.hashCode.

Doc from java.lang.Object.hashCode.

Returns a hash code value for the object. This method is supported for the benefit of hash tables such as those provided by java.util.HashMap.

The general contract of hashCode is:

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals method, then calling the hashCode method on each of the two objects must produce the same integer result.
  • It is not required that if two objects are unequal according to the equals method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.
Returns:int

a hash code value for this object.

Annotations
@Override