use of org.codehaus.groovy.ast.InnerClassNode in project groovy by apache.
the class MacroInvocationTrap method visitConstructorCallExpression.
@Override
public void visitConstructorCallExpression(final ConstructorCallExpression call) {
ClassNode type = call.getType();
if (type instanceof InnerClassNode) {
if (((InnerClassNode) type).isAnonymous() && MACROCLASS_TYPE.getNameWithoutPackage().equals(type.getSuperClass().getNameWithoutPackage())) {
//System.out.println("call = " + call.getText());
try {
String source = convertInnerClassToSource(type);
List<Expression> macroArgumentsExpressions = new LinkedList<Expression>();
macroArgumentsExpressions.add(new ConstantExpression(source));
macroArgumentsExpressions.add(buildSubstitutionMap(type));
macroArgumentsExpressions.add(new ClassExpression(ClassHelper.make(ClassNode.class)));
MethodCallExpression macroCall = new MethodCallExpression(new PropertyExpression(new ClassExpression(ClassHelper.makeWithoutCaching(MacroBuilder.class, false)), "INSTANCE"), MacroTransformation.MACRO_METHOD, new ArgumentListExpression(macroArgumentsExpressions));
macroCall.setSpreadSafe(false);
macroCall.setSafe(false);
macroCall.setImplicitThis(false);
call.putNodeMetaData(MacroTransformation.class, macroCall);
List<ClassNode> classes = sourceUnit.getAST().getClasses();
for (Iterator<ClassNode> iterator = classes.iterator(); iterator.hasNext(); ) {
final ClassNode aClass = iterator.next();
if (aClass == type || type == aClass.getOuterClass()) {
iterator.remove();
}
}
} catch (Exception e) {
e.printStackTrace();
}
return;
}
}
super.visitConstructorCallExpression(call);
}
use of org.codehaus.groovy.ast.InnerClassNode in project groovy by apache.
the class AntlrParserPlugin method innerInterfaceDef.
protected void innerInterfaceDef(AST classDef) {
List<AnnotationNode> annotations = new ArrayList<AnnotationNode>();
AST node = classDef.getFirstChild();
int modifiers = Opcodes.ACC_PUBLIC;
if (isType(MODIFIERS, node)) {
modifiers = modifiers(node, annotations, modifiers);
checkNoInvalidModifier(classDef, "Interface", modifiers, Opcodes.ACC_SYNCHRONIZED, "synchronized");
node = node.getNextSibling();
}
modifiers |= Opcodes.ACC_ABSTRACT | Opcodes.ACC_INTERFACE;
String name = identifier(node);
node = node.getNextSibling();
ClassNode superClass = ClassHelper.OBJECT_TYPE;
GenericsType[] genericsType = null;
if (isType(TYPE_PARAMETERS, node)) {
genericsType = makeGenericsType(node);
node = node.getNextSibling();
}
ClassNode[] interfaces = ClassNode.EMPTY_ARRAY;
if (isType(EXTENDS_CLAUSE, node)) {
interfaces = interfaces(node);
node = node.getNextSibling();
}
ClassNode outerClass = classNode;
boolean syntheticPublic = ((modifiers & Opcodes.ACC_SYNTHETIC) != 0);
modifiers &= ~Opcodes.ACC_SYNTHETIC;
if (classNode != null) {
name = classNode.getNameWithoutPackage() + "$" + name;
String fullName = dot(classNode.getPackageName(), name);
classNode = new InnerClassNode(classNode, fullName, modifiers, superClass, interfaces, null);
} else {
classNode = new ClassNode(dot(getPackageName(), name), modifiers, superClass, interfaces, null);
}
classNode.setSyntheticPublic(syntheticPublic);
classNode.addAnnotations(annotations);
classNode.setGenericsTypes(genericsType);
configureAST(classNode, classDef);
int oldClassCount = innerClassCounter;
assertNodeType(OBJBLOCK, node);
objectBlock(node);
output.addClass(classNode);
classNode = outerClass;
innerClassCounter = oldClassCount;
}
use of org.codehaus.groovy.ast.InnerClassNode in project groovy by apache.
the class StaticTypeCheckingVisitor method visitClass.
@Override
public void visitClass(final ClassNode node) {
if (shouldSkipClassNode(node))
return;
if (extension.beforeVisitClass(node)) {
extension.afterVisitClass(node);
return;
}
Object type = node.getNodeMetaData(StaticTypesMarker.INFERRED_TYPE);
if (type != null) {
// transformation has already been run on this class node
// so we'll use a silent collector in order not to duplicate errors
typeCheckingContext.pushErrorCollector();
}
typeCheckingContext.pushEnclosingClassNode(node);
Set<MethodNode> oldVisitedMethod = typeCheckingContext.alreadyVisitedMethods;
typeCheckingContext.alreadyVisitedMethods = new LinkedHashSet<MethodNode>();
super.visitClass(node);
Iterator<InnerClassNode> innerClasses = node.getInnerClasses();
while (innerClasses.hasNext()) {
InnerClassNode innerClassNode = innerClasses.next();
visitClass(innerClassNode);
}
typeCheckingContext.alreadyVisitedMethods = oldVisitedMethod;
node.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, node);
// works in a two pass sequence and we don't want to skip the second pass
for (MethodNode methodNode : node.getMethods()) {
methodNode.putNodeMetaData(StaticTypeCheckingVisitor.class, Boolean.TRUE);
}
for (ConstructorNode constructorNode : node.getDeclaredConstructors()) {
constructorNode.putNodeMetaData(StaticTypeCheckingVisitor.class, Boolean.TRUE);
}
extension.afterVisitClass(node);
}
use of org.codehaus.groovy.ast.InnerClassNode 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.InnerClassNode in project groovy-core by groovy.
the class AsmClassGenerator method visitAttributeOrProperty.
private void visitAttributeOrProperty(PropertyExpression expression, MethodCallerMultiAdapter adapter) {
MethodVisitor mv = controller.getMethodVisitor();
Expression objectExpression = expression.getObjectExpression();
ClassNode classNode = controller.getClassNode();
if (isThisOrSuper(objectExpression)) {
// let's use the field expression if it's available
String name = expression.getPropertyAsString();
if (name != null) {
FieldNode field = null;
boolean privateSuperField = false;
if (isSuperExpression(objectExpression)) {
field = classNode.getSuperClass().getDeclaredField(name);
if (field != null && ((field.getModifiers() & ACC_PRIVATE) != 0)) {
privateSuperField = true;
}
} else {
if (controller.isNotExplicitThisInClosure(expression.isImplicitThis())) {
field = classNode.getDeclaredField(name);
if (field == null && classNode instanceof InnerClassNode) {
ClassNode outer = classNode.getOuterClass();
FieldNode outerClassField;
while (outer != null) {
outerClassField = outer.getDeclaredField(name);
if (outerClassField != null && outerClassField.isStatic() && outerClassField.isFinal()) {
if (outer != classNode.getOuterClass() && Modifier.isPrivate(outerClassField.getModifiers())) {
throw new GroovyBugError("Trying to access private constant field [" + outerClassField.getDeclaringClass() + "#" + outerClassField.getName() + "] from inner class");
}
PropertyExpression pexp = new PropertyExpression(new ClassExpression(outer), expression.getProperty());
pexp.visit(controller.getAcg());
return;
}
outer = outer.getSuperClass();
}
}
if (field == null && expression instanceof AttributeExpression && isThisExpression(objectExpression) && controller.isStaticContext()) {
// GROOVY-6183
ClassNode current = classNode.getSuperClass();
while (field == null && current != null) {
field = current.getDeclaredField(name);
current = current.getSuperClass();
}
if (field != null && (field.isProtected() || field.isPublic())) {
visitFieldExpression(new FieldExpression(field));
return;
}
}
}
}
if (field != null && !privateSuperField) {
// GROOVY-4497: don't visit super field if it is private
visitFieldExpression(new FieldExpression(field));
return;
}
}
if (isSuperExpression(objectExpression)) {
String prefix;
if (controller.getCompileStack().isLHS()) {
throw new GroovyBugError("Unexpected super property set for:" + expression.getText());
} else {
prefix = "get";
}
String propName = prefix + MetaClassHelper.capitalize(name);
visitMethodCallExpression(new MethodCallExpression(objectExpression, propName, MethodCallExpression.NO_ARGUMENTS));
return;
}
}
final String propName = expression.getPropertyAsString();
// TODO: add support for super here too
if (expression.getObjectExpression() instanceof ClassExpression && propName != null && propName.equals("this")) {
// we have something like A.B.this, and need to make it
// into this.this$0.this$0, where this.this$0 returns
// A.B and this.this$0.this$0 return A.
ClassNode type = objectExpression.getType();
ClassNode iterType = classNode;
if (controller.getCompileStack().isInSpecialConstructorCall() && classNode instanceof InnerClassNode) {
boolean staticInnerClass = classNode.isStaticClass();
// Outer.this in a special constructor call
if (classNode.getOuterClass().equals(type)) {
ConstructorNode ctor = controller.getConstructorNode();
Expression receiver = !staticInnerClass ? new VariableExpression(ctor.getParameters()[0]) : new ClassExpression(type);
receiver.setSourcePosition(expression);
receiver.visit(this);
return;
}
}
mv.visitVarInsn(ALOAD, 0);
while (!iterType.equals(type)) {
String ownerName = BytecodeHelper.getClassInternalName(iterType);
if (iterType.getOuterClass() == null)
break;
FieldNode thisField = iterType.getField("this$0");
if (thisField == null)
break;
ClassNode thisFieldType = thisField.getType();
iterType = iterType.getOuterClass();
if (ClassHelper.CLOSURE_TYPE.equals(thisFieldType)) {
mv.visitFieldInsn(GETFIELD, ownerName, "this$0", BytecodeHelper.getTypeDescription(ClassHelper.CLOSURE_TYPE));
mv.visitMethodInsn(INVOKEVIRTUAL, BytecodeHelper.getClassInternalName(ClassHelper.CLOSURE_TYPE), "getThisObject", "()Ljava/lang/Object;", false);
mv.visitTypeInsn(CHECKCAST, BytecodeHelper.getClassInternalName(iterType));
} else {
String typeName = BytecodeHelper.getTypeDescription(iterType);
mv.visitFieldInsn(GETFIELD, ownerName, "this$0", typeName);
}
}
controller.getOperandStack().push(type);
return;
}
if (adapter == getProperty && !expression.isSpreadSafe() && propName != null) {
controller.getCallSiteWriter().makeGetPropertySite(objectExpression, propName, expression.isSafe(), expression.isImplicitThis());
} else if (adapter == getGroovyObjectProperty && !expression.isSpreadSafe() && propName != null) {
controller.getCallSiteWriter().makeGroovyObjectGetPropertySite(objectExpression, propName, expression.isSafe(), expression.isImplicitThis());
} else {
// todo: for improved modularity and extensibility, this should be moved into a writer
if (controller.getCompileStack().isLHS())
controller.getOperandStack().box();
controller.getInvocationWriter().makeCall(expression, // receiver
objectExpression, // messageName
new CastExpression(ClassHelper.STRING_TYPE, expression.getProperty()), MethodCallExpression.NO_ARGUMENTS, adapter, expression.isSafe(), expression.isSpreadSafe(), expression.isImplicitThis());
}
}
Aggregations