use of org.codehaus.groovy.ast.expr.ClassExpression in project groovy by apache.
the class StaticImportVisitor method transformMethodCallExpression.
protected Expression transformMethodCallExpression(MethodCallExpression mce) {
Expression args = transform(mce.getArguments());
Expression method = transform(mce.getMethod());
Expression object = transform(mce.getObjectExpression());
boolean isExplicitThisOrSuper = false;
boolean isExplicitSuper = false;
if (object instanceof VariableExpression) {
VariableExpression ve = (VariableExpression) object;
isExplicitThisOrSuper = !mce.isImplicitThis() && (ve.isThisExpression() || ve.isSuperExpression());
isExplicitSuper = ve.isSuperExpression();
}
if (mce.isImplicitThis() || isExplicitThisOrSuper) {
if (mce.isImplicitThis()) {
Expression ret = findStaticMethodImportFromModule(method, args);
if (ret != null) {
setSourcePosition(ret, mce);
return ret;
}
if (method instanceof ConstantExpression && !inLeftExpression) {
// could be a closure field
String methodName = (String) ((ConstantExpression) method).getValue();
ret = findStaticFieldOrPropAccessorImportFromModule(methodName);
if (ret != null) {
ret = new MethodCallExpression(ret, "call", args);
setSourcePosition(ret, mce);
return ret;
}
}
} else if (currentMethod != null && currentMethod.isStatic() && isExplicitSuper) {
MethodCallExpression ret = new MethodCallExpression(new ClassExpression(currentClass.getSuperClass()), method, args);
setSourcePosition(ret, mce);
return ret;
}
if (method instanceof ConstantExpression) {
ConstantExpression ce = (ConstantExpression) method;
Object value = ce.getValue();
if (value instanceof String) {
boolean foundInstanceMethod = false;
String methodName = (String) value;
boolean inInnerClass = isInnerClass(currentClass);
if (currentMethod != null && !currentMethod.isStatic()) {
if (currentClass.hasPossibleMethod(methodName, args)) {
foundInstanceMethod = true;
}
}
boolean lookForPossibleStaticMethod = !methodName.equals("call");
lookForPossibleStaticMethod &= !foundInstanceMethod;
lookForPossibleStaticMethod |= inSpecialConstructorCall;
lookForPossibleStaticMethod &= !inInnerClass;
if (!inClosure && lookForPossibleStaticMethod && (hasPossibleStaticMethod(currentClass, methodName, args, true)) || hasPossibleStaticProperty(currentClass, methodName)) {
StaticMethodCallExpression smce = new StaticMethodCallExpression(currentClass, methodName, args);
setSourcePosition(smce, mce);
return smce;
}
if (!inClosure && inInnerClass && inSpecialConstructorCall && mce.isImplicitThis() && !foundInstanceMethod) {
if (currentClass.getOuterClass().hasPossibleMethod(methodName, args)) {
object = new PropertyExpression(new ClassExpression(currentClass.getOuterClass()), new ConstantExpression("this"));
} else if (hasPossibleStaticMethod(currentClass.getOuterClass(), methodName, args, true) || hasPossibleStaticProperty(currentClass.getOuterClass(), methodName)) {
StaticMethodCallExpression smce = new StaticMethodCallExpression(currentClass.getOuterClass(), methodName, args);
setSourcePosition(smce, mce);
return smce;
}
}
}
}
}
MethodCallExpression result = new MethodCallExpression(object, method, args);
result.setSafe(mce.isSafe());
result.setImplicitThis(mce.isImplicitThis());
result.setSpreadSafe(mce.isSpreadSafe());
result.setMethodTarget(mce.getMethodTarget());
// GROOVY-6757
result.setGenericsTypes(mce.getGenericsTypes());
setSourcePosition(result, mce);
return result;
}
use of org.codehaus.groovy.ast.expr.ClassExpression in project groovy by apache.
the class InnerClassCompletionVisitor method addDefaultMethods.
private void addDefaultMethods(InnerClassNode node) {
final boolean isStatic = isStatic(node);
ClassNode outerClass = node.getOuterClass();
final String classInternalName = org.codehaus.groovy.classgen.asm.BytecodeHelper.getClassInternalName(node);
final String outerClassInternalName = getInternalName(outerClass, isStatic);
final String outerClassDescriptor = getTypeDescriptor(outerClass, isStatic);
final int objectDistance = getObjectDistance(outerClass);
// add missing method dispatcher
Parameter[] parameters = new Parameter[] { new Parameter(ClassHelper.STRING_TYPE, "name"), new Parameter(ClassHelper.OBJECT_TYPE, "args") };
String methodName = "methodMissing";
if (isStatic)
addCompilationErrorOnCustomMethodNode(node, methodName, parameters);
MethodNode method = node.addSyntheticMethod(methodName, Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE, parameters, ClassNode.EMPTY_ARRAY, null);
BlockStatement block = new BlockStatement();
if (isStatic) {
setMethodDispatcherCode(block, new ClassExpression(outerClass), parameters);
} else {
block.addStatement(new BytecodeSequence(new BytecodeInstruction() {
public void visit(MethodVisitor mv) {
getThis(mv, classInternalName, outerClassDescriptor, outerClassInternalName);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKEVIRTUAL, outerClassInternalName, "this$dist$invoke$" + objectDistance, "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;", false);
mv.visitInsn(ARETURN);
}
}));
}
method.setCode(block);
// add static missing method dispatcher
methodName = "$static_methodMissing";
if (isStatic)
addCompilationErrorOnCustomMethodNode(node, methodName, parameters);
method = node.addSyntheticMethod(methodName, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, ClassHelper.OBJECT_TYPE, parameters, ClassNode.EMPTY_ARRAY, null);
block = new BlockStatement();
setMethodDispatcherCode(block, new ClassExpression(outerClass), parameters);
method.setCode(block);
// add property setter dispatcher
parameters = new Parameter[] { new Parameter(ClassHelper.STRING_TYPE, "name"), new Parameter(ClassHelper.OBJECT_TYPE, "val") };
methodName = "propertyMissing";
if (isStatic)
addCompilationErrorOnCustomMethodNode(node, methodName, parameters);
method = node.addSyntheticMethod(methodName, Opcodes.ACC_PUBLIC, ClassHelper.VOID_TYPE, parameters, ClassNode.EMPTY_ARRAY, null);
block = new BlockStatement();
if (isStatic) {
setPropertySetterDispatcher(block, new ClassExpression(outerClass), parameters);
} else {
block.addStatement(new BytecodeSequence(new BytecodeInstruction() {
public void visit(MethodVisitor mv) {
getThis(mv, classInternalName, outerClassDescriptor, outerClassInternalName);
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKEVIRTUAL, outerClassInternalName, "this$dist$set$" + objectDistance, "(Ljava/lang/String;Ljava/lang/Object;)V", false);
mv.visitInsn(RETURN);
}
}));
}
method.setCode(block);
// add static property missing setter dispatcher
methodName = "$static_propertyMissing";
if (isStatic)
addCompilationErrorOnCustomMethodNode(node, methodName, parameters);
method = node.addSyntheticMethod(methodName, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, ClassHelper.VOID_TYPE, parameters, ClassNode.EMPTY_ARRAY, null);
block = new BlockStatement();
setPropertySetterDispatcher(block, new ClassExpression(outerClass), parameters);
method.setCode(block);
// add property getter dispatcher
parameters = new Parameter[] { new Parameter(ClassHelper.STRING_TYPE, "name") };
methodName = "propertyMissing";
if (isStatic)
addCompilationErrorOnCustomMethodNode(node, methodName, parameters);
method = node.addSyntheticMethod(methodName, Opcodes.ACC_PUBLIC, ClassHelper.OBJECT_TYPE, parameters, ClassNode.EMPTY_ARRAY, null);
block = new BlockStatement();
if (isStatic) {
setPropertyGetterDispatcher(block, new ClassExpression(outerClass), parameters);
} else {
block.addStatement(new BytecodeSequence(new BytecodeInstruction() {
public void visit(MethodVisitor mv) {
getThis(mv, classInternalName, outerClassDescriptor, outerClassInternalName);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, outerClassInternalName, "this$dist$get$" + objectDistance, "(Ljava/lang/String;)Ljava/lang/Object;", false);
mv.visitInsn(ARETURN);
}
}));
}
method.setCode(block);
// add static property missing getter dispatcher
methodName = "$static_propertyMissing";
if (isStatic)
addCompilationErrorOnCustomMethodNode(node, methodName, parameters);
method = node.addSyntheticMethod(methodName, Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, ClassHelper.OBJECT_TYPE, parameters, ClassNode.EMPTY_ARRAY, null);
block = new BlockStatement();
setPropertyGetterDispatcher(block, new ClassExpression(outerClass), parameters);
method.setCode(block);
}
use of org.codehaus.groovy.ast.expr.ClassExpression in project groovy by apache.
the class ClosureWriter method writeClosure.
public void writeClosure(ClosureExpression expression) {
CompileStack compileStack = controller.getCompileStack();
MethodVisitor mv = controller.getMethodVisitor();
ClassNode classNode = controller.getClassNode();
AsmClassGenerator acg = controller.getAcg();
// generate closure as public class to make sure it can be properly invoked by classes of the
// Groovy runtime without circumventing JVM access checks (see CachedMethod for example).
int mods = ACC_PUBLIC;
if (classNode.isInterface()) {
mods |= ACC_STATIC;
}
ClassNode closureClass = getOrAddClosureClass(expression, mods);
String closureClassinternalName = BytecodeHelper.getClassInternalName(closureClass);
List constructors = closureClass.getDeclaredConstructors();
ConstructorNode node = (ConstructorNode) constructors.get(0);
Parameter[] localVariableParams = node.getParameters();
mv.visitTypeInsn(NEW, closureClassinternalName);
mv.visitInsn(DUP);
if (controller.isStaticMethod() || compileStack.isInSpecialConstructorCall()) {
(new ClassExpression(classNode)).visit(acg);
(new ClassExpression(controller.getOutermostClass())).visit(acg);
} else {
mv.visitVarInsn(ALOAD, 0);
controller.getOperandStack().push(ClassHelper.OBJECT_TYPE);
loadThis();
}
// on the stack
for (int i = 2; i < localVariableParams.length; i++) {
Parameter param = localVariableParams[i];
String name = param.getName();
loadReference(name, controller);
if (param.getNodeMetaData(ClosureWriter.UseExistingReference.class) == null) {
param.setNodeMetaData(ClosureWriter.UseExistingReference.class, Boolean.TRUE);
}
}
// we may need to pass in some other constructors
//cv.visitMethodInsn(INVOKESPECIAL, innerClassinternalName, "<init>", prototype + ")V");
mv.visitMethodInsn(INVOKESPECIAL, closureClassinternalName, "<init>", BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, localVariableParams), false);
controller.getOperandStack().replace(ClassHelper.CLOSURE_TYPE, localVariableParams.length);
}
use of org.codehaus.groovy.ast.expr.ClassExpression in project groovy by apache.
the class StaticImportVisitor method findStaticPropertyAccessor.
private Expression findStaticPropertyAccessor(ClassNode staticImportType, String propName) {
String accessorName = getAccessorName(propName);
Expression accessor = findStaticPropertyAccessorByFullName(staticImportType, accessorName);
if (accessor == null && accessorName.startsWith("get")) {
accessor = findStaticPropertyAccessorByFullName(staticImportType, "is" + accessorName.substring(3));
}
if (accessor == null && hasStaticProperty(staticImportType, propName)) {
// args will be replaced
if (inLeftExpression)
accessor = new StaticMethodCallExpression(staticImportType, accessorName, ArgumentListExpression.EMPTY_ARGUMENTS);
else
accessor = new PropertyExpression(new ClassExpression(staticImportType), propName);
}
return accessor;
}
use of org.codehaus.groovy.ast.expr.ClassExpression in project groovy by apache.
the class StaticImportVisitor method transformPropertyExpression.
protected Expression transformPropertyExpression(PropertyExpression pe) {
if (currentMethod != null && currentMethod.isStatic() && pe.getObjectExpression() instanceof VariableExpression && ((VariableExpression) pe.getObjectExpression()).isSuperExpression()) {
PropertyExpression pexp = new PropertyExpression(new ClassExpression(currentClass.getSuperClass()), transform(pe.getProperty()));
pexp.setSourcePosition(pe);
return pexp;
}
boolean oldInPropertyExpression = inPropertyExpression;
Expression oldFoundArgs = foundArgs;
Expression oldFoundConstant = foundConstant;
inPropertyExpression = true;
foundArgs = null;
foundConstant = null;
Expression objectExpression = transform(pe.getObjectExpression());
boolean candidate = false;
if (objectExpression instanceof MethodCallExpression) {
candidate = ((MethodCallExpression) objectExpression).isImplicitThis();
}
if (foundArgs != null && foundConstant != null && candidate) {
Expression result = findStaticMethodImportFromModule(foundConstant, foundArgs);
if (result != null) {
objectExpression = result;
objectExpression.setSourcePosition(pe);
}
}
inPropertyExpression = oldInPropertyExpression;
foundArgs = oldFoundArgs;
foundConstant = oldFoundConstant;
pe.setObjectExpression(objectExpression);
return pe;
}
Aggregations