use of org.codehaus.groovy.GroovyBugError in project groovy-core by groovy.
the class StaticTypeCheckingSupport method evaluateExpression.
/**
* A helper method that can be used to evaluate expressions as found in annotation
* parameters. For example, it will evaluate a constant, be it referenced directly as
* an integer or as a reference to a field.
*
* If this method throws an exception, then the expression cannot be evaluated on its own.
*
* @param expr the expression to be evaluated
* @param config the compiler configuration
* @return the result of the expression
*/
public static Object evaluateExpression(Expression expr, CompilerConfiguration config) {
String className = "Expression$" + UUID.randomUUID().toString().replace('-', '$');
ClassNode node = new ClassNode(className, Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE);
ReturnStatement code = new ReturnStatement(expr);
node.addMethod(new MethodNode("eval", Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, code));
CompilerConfiguration copyConf = new CompilerConfiguration(config);
CompilationUnit cu = new CompilationUnit(copyConf);
cu.addClassNode(node);
cu.compile(Phases.CLASS_GENERATION);
@SuppressWarnings("unchecked") List<GroovyClass> classes = (List<GroovyClass>) cu.getClasses();
Class aClass = cu.getClassLoader().defineClass(className, classes.get(0).getBytes());
try {
return aClass.getMethod("eval").invoke(null);
} catch (IllegalAccessException e) {
throw new GroovyBugError(e);
} catch (InvocationTargetException e) {
throw new GroovyBugError(e);
} catch (NoSuchMethodException e) {
throw new GroovyBugError(e);
}
}
use of org.codehaus.groovy.GroovyBugError in project groovy-core by groovy.
the class StaticTypeCheckingVisitor method extractPlaceHolders.
private static Map<String, GenericsType> extractPlaceHolders(MethodNode method, ClassNode receiver, ClassNode declaringClass) {
if (declaringClass.equals(OBJECT_TYPE)) {
Map<String, GenericsType> resolvedPlaceholders = new HashMap<String, GenericsType>();
if (method != null)
addMethodLevelDeclaredGenerics(method, resolvedPlaceholders);
return resolvedPlaceholders;
}
Map<String, GenericsType> resolvedPlaceholders = null;
if (isPrimitiveType(receiver) && !isPrimitiveType(declaringClass)) {
receiver = getWrapper(receiver);
}
final List<ClassNode> queue;
if (receiver instanceof UnionTypeClassNode) {
queue = Arrays.asList(((UnionTypeClassNode) receiver).getDelegates());
} else {
queue = Collections.singletonList(receiver);
}
for (ClassNode item : queue) {
ClassNode current = item;
while (current != null) {
boolean continueLoop = true;
//extract the place holders
Map<String, GenericsType> currentPlaceHolders = new HashMap<String, GenericsType>();
if (isGenericsPlaceHolderOrArrayOf(declaringClass) || declaringClass.equals(current)) {
extractGenericsConnections(currentPlaceHolders, current, declaringClass);
if (method != null)
addMethodLevelDeclaredGenerics(method, currentPlaceHolders);
continueLoop = false;
} else {
GenericsUtils.extractPlaceholders(current, currentPlaceHolders);
}
if (resolvedPlaceholders != null) {
// merge maps
Set<Map.Entry<String, GenericsType>> entries = currentPlaceHolders.entrySet();
for (Map.Entry<String, GenericsType> entry : entries) {
GenericsType gt = entry.getValue();
if (!gt.isPlaceholder())
continue;
GenericsType referenced = resolvedPlaceholders.get(gt.getName());
if (referenced == null)
continue;
entry.setValue(referenced);
}
}
resolvedPlaceholders = currentPlaceHolders;
// we are done if we are now in the declaring class
if (!continueLoop)
break;
current = getNextSuperClass(current, declaringClass);
if (current == null && CLASS_Type.equals(declaringClass)) {
// this can happen if the receiver is Class<Foo>, then
// the actual receiver is Foo and declaringClass is Class
current = declaringClass;
}
}
}
if (resolvedPlaceholders == null) {
String descriptor = "<>";
if (method != null)
descriptor = method.getTypeDescriptor();
throw new GroovyBugError("Declaring class for method call to '" + descriptor + "' declared in " + declaringClass.getName() + " was not matched with found receiver " + receiver.getName() + "." + " This should not have happened!");
}
return resolvedPlaceholders;
}
use of org.codehaus.groovy.GroovyBugError in project groovy-core by groovy.
the class GeneratorContext method encodeAsValidClassName.
public static String encodeAsValidClassName(String name) {
final int l = name.length();
StringBuilder b = null;
int lastEscape = -1;
for (int i = 0; i < l; ++i) {
final int encodeIndex = name.charAt(i) - MIN_ENCODING;
if (encodeIndex >= 0 && encodeIndex < CHARACTERS_TO_ENCODE.length) {
if (CHARACTERS_TO_ENCODE[encodeIndex]) {
if (b == null) {
b = new StringBuilder(name.length() + 3);
b.append(name, 0, i);
} else {
b.append(name, lastEscape + 1, i);
}
b.append('_');
lastEscape = i;
}
}
}
if (b == null)
return name.toString();
if (lastEscape == -1)
throw new GroovyBugError("unexpected escape char control flow in " + name);
b.append(name, lastEscape + 1, l);
return b.toString();
}
use of org.codehaus.groovy.GroovyBugError in project groovy-core by groovy.
the class AsmClassGenerator method visitAnnotationDefaultExpression.
void visitAnnotationDefaultExpression(AnnotationVisitor av, ClassNode type, Expression exp) {
if (exp instanceof ClosureExpression) {
ClassNode closureClass = controller.getClosureWriter().getOrAddClosureClass((ClosureExpression) exp, ACC_PUBLIC);
Type t = Type.getType(BytecodeHelper.getTypeDescription(closureClass));
av.visit(null, t);
} else if (type.isArray()) {
ListExpression list = (ListExpression) exp;
AnnotationVisitor avl = av.visitArray(null);
ClassNode componentType = type.getComponentType();
for (Expression lExp : list.getExpressions()) {
visitAnnotationDefaultExpression(avl, componentType, lExp);
}
} else if (ClassHelper.isPrimitiveType(type) || type.equals(ClassHelper.STRING_TYPE)) {
ConstantExpression constExp = (ConstantExpression) exp;
av.visit(null, constExp.getValue());
} else if (ClassHelper.CLASS_Type.equals(type)) {
ClassNode clazz = exp.getType();
Type t = Type.getType(BytecodeHelper.getTypeDescription(clazz));
av.visit(null, t);
} else if (type.isDerivedFrom(ClassHelper.Enum_Type)) {
PropertyExpression pExp = (PropertyExpression) exp;
ClassExpression cExp = (ClassExpression) pExp.getObjectExpression();
String desc = BytecodeHelper.getTypeDescription(cExp.getType());
String name = pExp.getPropertyAsString();
av.visitEnum(null, desc, name);
} else if (type.implementsInterface(ClassHelper.Annotation_TYPE)) {
AnnotationConstantExpression avExp = (AnnotationConstantExpression) exp;
AnnotationNode value = (AnnotationNode) avExp.getValue();
AnnotationVisitor avc = av.visitAnnotation(null, BytecodeHelper.getTypeDescription(avExp.getType()));
visitAnnotationAttributes(value, avc);
} else {
throw new GroovyBugError("unexpected annotation type " + type.getName());
}
av.visitEnd();
}
use of org.codehaus.groovy.GroovyBugError in project groovy-core by groovy.
the class Expression method transformExpressions.
/**
* Transforms the list of expressions, and checks that all transformed expressions have the given type.
*
* @return a new list of transformed expressions
*/
protected <T extends Expression> List<T> transformExpressions(List<? extends Expression> expressions, ExpressionTransformer transformer, Class<T> transformedType) {
List<T> list = new ArrayList<T>(expressions.size());
for (Expression expr : expressions) {
Expression transformed = transformer.transform(expr);
if (!transformedType.isInstance(transformed))
throw new GroovyBugError(String.format("Transformed expression should have type %s but has type %s", transformedType, transformed.getClass()));
list.add(transformedType.cast(transformed));
}
return list;
}
Aggregations