Search in sources :

Example 16 with GroovyBugError

use of org.codehaus.groovy.GroovyBugError 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());
    }
}
Also used : InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) InterfaceHelperClassNode(org.codehaus.groovy.ast.InterfaceHelperClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) FieldNode(org.codehaus.groovy.ast.FieldNode) GroovyBugError(org.codehaus.groovy.GroovyBugError) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) MethodVisitor(org.objectweb.asm.MethodVisitor) ConstructorNode(org.codehaus.groovy.ast.ConstructorNode)

Example 17 with GroovyBugError

use of org.codehaus.groovy.GroovyBugError in project groovy-core by groovy.

the class CompileStack method init.

/**
     * initializes this class for a MethodNode. This method will
     * automatically define variables for the method parameters
     * and will create references if needed.  The created variables
     * can be accessed by calling getVariable().
     *
     */
public void init(VariableScope el, Parameter[] parameters) {
    if (!clear)
        throw new GroovyBugError("CompileStack#init called without calling clear before");
    clear = false;
    pushVariableScope(el);
    defineMethodVariables(parameters, el.isInStaticContext());
    this.className = BytecodeHelper.getTypeDescription(controller.getClassNode());
}
Also used : GroovyBugError(org.codehaus.groovy.GroovyBugError)

Example 18 with GroovyBugError

use of org.codehaus.groovy.GroovyBugError in project groovy-core by groovy.

the class OperandStack method castToBool.

/**
     * ensure last marked parameter on the stack is a primitive boolean
     * if mark==stack size, we assume an empty expression or statement.
     * was used and we will use the value given in emptyDefault as boolean 
     * if mark==stack.size()-1 the top element will be cast to boolean using
     * Groovy truth.
     * In other cases we throw a GroovyBugError
     */
public void castToBool(int mark, boolean emptyDefault) {
    int size = stack.size();
    MethodVisitor mv = controller.getMethodVisitor();
    if (mark == size) {
        // no element, so use emptyDefault
        if (emptyDefault) {
            mv.visitIntInsn(BIPUSH, 1);
        } else {
            mv.visitIntInsn(BIPUSH, 0);
        }
        stack.add(null);
    } else if (mark == stack.size() - 1) {
        ClassNode last = stack.get(size - 1);
        // nothing to do in that case
        if (last == ClassHelper.boolean_TYPE)
            return;
        // not a primitive type, so call booleanUnbox
        if (!ClassHelper.isPrimitiveType(last)) {
            controller.getInvocationWriter().castNonPrimitiveToBool(last);
        } else {
            primitive2b(mv, last);
        }
    } else {
        throw new GroovyBugError("operand stack contains " + stack.size() + " elements, but we expected only " + mark);
    }
    stack.set(mark, ClassHelper.boolean_TYPE);
}
Also used : GroovyBugError(org.codehaus.groovy.GroovyBugError) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 19 with GroovyBugError

use of org.codehaus.groovy.GroovyBugError in project groovy-core by groovy.

the class SourceUnit method parse.

//---------------------------------------------------------------------------
// PROCESSING
/**
     * Parses the source to a CST.  You can retrieve it with getCST().
     */
public void parse() throws CompilationFailedException {
    if (this.phase > Phases.PARSING) {
        throw new GroovyBugError("parsing is already complete");
    }
    if (this.phase == Phases.INITIALIZATION) {
        nextPhase();
    }
    //
    // Create a reader on the source and run the parser.
    Reader reader = null;
    try {
        reader = source.getReader();
        // let's recreate the parser each time as it tends to keep around state
        parserPlugin = getConfiguration().getPluginFactory().createParserPlugin();
        cst = parserPlugin.parseCST(this, reader);
        reader.close();
    } catch (IOException e) {
        getErrorCollector().addFatalError(new SimpleMessage(e.getMessage(), this));
    } finally {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
            // Ignore
            }
        }
    }
}
Also used : SimpleMessage(org.codehaus.groovy.control.messages.SimpleMessage) GroovyBugError(org.codehaus.groovy.GroovyBugError) Reader(java.io.Reader) IOException(java.io.IOException)

Example 20 with GroovyBugError

use of org.codehaus.groovy.GroovyBugError in project groovy-core by groovy.

the class Traits method findHelpers.

static TraitHelpersTuple findHelpers(final ClassNode trait) {
    ClassNode helperClassNode = null;
    ClassNode fieldHelperClassNode = null;
    Iterator<InnerClassNode> innerClasses = trait.redirect().getInnerClasses();
    if (innerClasses != null && innerClasses.hasNext()) {
        // trait defined in same source unit
        while (innerClasses.hasNext()) {
            ClassNode icn = innerClasses.next();
            if (icn.getName().endsWith(Traits.FIELD_HELPER)) {
                fieldHelperClassNode = icn;
            } else if (icn.getName().endsWith(Traits.TRAIT_HELPER)) {
                helperClassNode = icn;
            }
        }
    } else {
        // precompiled trait
        try {
            final ClassLoader classLoader = trait.getTypeClass().getClassLoader();
            String helperClassName = Traits.helperClassName(trait);
            helperClassNode = ClassHelper.make(classLoader.loadClass(helperClassName));
            try {
                fieldHelperClassNode = ClassHelper.make(classLoader.loadClass(Traits.fieldHelperClassName(trait)));
            } catch (ClassNotFoundException e) {
            // not a problem, the field helper may be absent
            }
        } catch (ClassNotFoundException e) {
            throw new GroovyBugError("Couldn't find trait helper classes on compile classpath!", e);
        }
    }
    return new TraitHelpersTuple(helperClassNode, fieldHelperClassNode);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) GroovyBugError(org.codehaus.groovy.GroovyBugError) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode)

Aggregations

GroovyBugError (org.codehaus.groovy.GroovyBugError)71 ClassNode (org.codehaus.groovy.ast.ClassNode)31 AnnotationNode (org.codehaus.groovy.ast.AnnotationNode)11 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)11 MethodNode (org.codehaus.groovy.ast.MethodNode)11 GenericsType (org.codehaus.groovy.ast.GenericsType)9 AnnotatedNode (org.codehaus.groovy.ast.AnnotatedNode)8 FieldNode (org.codehaus.groovy.ast.FieldNode)8 SyntaxException (org.codehaus.groovy.syntax.SyntaxException)8 MethodVisitor (org.objectweb.asm.MethodVisitor)8 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)7 Closure (groovy.lang.Closure)6 GroovyRuntimeException (groovy.lang.GroovyRuntimeException)6 IOException (java.io.IOException)6 ArrayList (java.util.ArrayList)6 LinkedList (java.util.LinkedList)5 Expression (org.codehaus.groovy.ast.expr.Expression)5 GroovyClassLoader (groovy.lang.GroovyClassLoader)4 InvocationTargetException (java.lang.reflect.InvocationTargetException)4 Collection (java.util.Collection)4