Java Code Examples for org.codehaus.groovy.ast.ClassNode#isStaticClass()

The following examples show how to use org.codehaus.groovy.ast.ClassNode#isStaticClass() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: StaticTypesBinaryExpressionMultiTypeDispatcher.java    From groovy with Apache License 2.0 5 votes vote down vote up
private boolean makeSetPrivateFieldWithBridgeMethod(final Expression receiver, final ClassNode receiverType, final String fieldName, final Expression arguments, final boolean safe, final boolean spreadSafe, final boolean implicitThis) {
    FieldNode field = receiverType.getField(fieldName);
    ClassNode outerClass = receiverType.getOuterClass();
    if (field == null && implicitThis && outerClass != null && !receiverType.isStaticClass()) {
        Expression pexp;
        if (controller.isInGeneratedFunction()) {
            MethodCallExpression mce = callThisX("getThisObject");
            mce.setImplicitThis(true);
            mce.setMethodTarget(CLOSURE_GETTHISOBJECT_METHOD);
            mce.putNodeMetaData(INFERRED_TYPE, controller.getOutermostClass());
            pexp = castX(controller.getOutermostClass(), mce);
        } else {
            pexp = propX(classX(outerClass), "this");
            ((PropertyExpression) pexp).setImplicitThis(true);
        }
        pexp.putNodeMetaData(INFERRED_TYPE, outerClass);
        pexp.setSourcePosition(receiver);
        return makeSetPrivateFieldWithBridgeMethod(pexp, outerClass, fieldName, arguments, safe, spreadSafe, true);
    }
    ClassNode classNode = controller.getClassNode();
    if (field != null && field.isPrivate() && !receiverType.equals(classNode)
            && (StaticInvocationWriter.isPrivateBridgeMethodsCallAllowed(receiverType, classNode)
                || StaticInvocationWriter.isPrivateBridgeMethodsCallAllowed(classNode,receiverType))) {
        Map<String, MethodNode> mutators = receiverType.redirect().getNodeMetaData(StaticCompilationMetadataKeys.PRIVATE_FIELDS_MUTATORS);
        if (mutators != null) {
            MethodNode methodNode = mutators.get(fieldName);
            if (methodNode != null) {
                MethodCallExpression call = callX(receiver, methodNode.getName(), args(field.isStatic() ? nullX() : receiver, arguments));
                call.setImplicitThis(implicitThis);
                call.setMethodTarget(methodNode);
                call.setSafe(safe);
                call.setSpreadSafe(spreadSafe);
                call.visit(controller.getAcg());
                return true;
            }
        }
    }
    return false;
}
 
Example 2
Source File: StaticTypesLambdaWriter.java    From groovy with Apache License 2.0 5 votes vote down vote up
protected ClassNode createLambdaClass(final LambdaExpression expression, final int modifiers, final MethodNode abstractMethod) {
    ClassNode enclosingClass = controller.getClassNode();
    ClassNode outermostClass = controller.getOutermostClass();
    boolean staticMethodOrInStaticClass = (controller.isStaticMethod() || enclosingClass.isStaticClass());

    InnerClassNode lambdaClass = new InnerClassNode(enclosingClass, nextLambdaClassName(), modifiers, CLOSURE_TYPE.getPlainNodeReference());
  //lambdaClass.setUsingGenerics(outermostClass.isUsingGenerics());
    lambdaClass.setEnclosingMethod(controller.getMethodNode());
    lambdaClass.setSourcePosition(expression);
    lambdaClass.setSynthetic(true);

    if (controller.isInScriptBody()) {
        lambdaClass.setScriptBody(true);
    }
    if (staticMethodOrInStaticClass) {
        lambdaClass.setStaticClass(true);
    }
    if (expression.isSerializable()) {
        addSerialVersionUIDField(lambdaClass);
    }

    MethodNode syntheticLambdaMethodNode = addSyntheticLambdaMethodNode(expression, lambdaClass, abstractMethod);
    Parameter[] localVariableParameters = expression.getNodeMetaData(LAMBDA_SHARED_VARIABLES);

    addFieldsAndGettersForLocalVariables(lambdaClass, localVariableParameters);
    ConstructorNode constructorNode = addConstructor(expression, localVariableParameters, lambdaClass, createBlockStatementForConstructor(expression, outermostClass, enclosingClass));
    constructorNode.putNodeMetaData(IS_GENERATED_CONSTRUCTOR, Boolean.TRUE);

    syntheticLambdaMethodNode.getCode().visit(new CorrectAccessedVariableVisitor(lambdaClass));

    return lambdaClass;
}
 
Example 3
Source File: AsmClassGenerator.java    From groovy with Apache License 2.0 4 votes vote down vote up
private void visitAttributeOrProperty(final PropertyExpression pexp, final MethodCallerMultiAdapter adapter) {
    ClassNode classNode = controller.getClassNode();
    String propertyName = pexp.getPropertyAsString();
    Expression objectExpression = pexp.getObjectExpression();

    if (objectExpression instanceof ClassExpression && "this".equals(propertyName)) {
        // 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();
        if (controller.getCompileStack().isInSpecialConstructorCall() && type.equals(classNode.getOuterClass())) {
            // Outer.this in a special constructor call
            ConstructorNode ctor = controller.getConstructorNode();
            Expression receiver = !classNode.isStaticClass() ? new VariableExpression(ctor.getParameters()[0]) : new ClassExpression(type);
            receiver.setSourcePosition(pexp);
            receiver.visit(this);
            return;
        }

        MethodVisitor mv = controller.getMethodVisitor();
        mv.visitVarInsn(ALOAD, 0);
        ClassNode iterType = classNode;
        while (!iterType.equals(type)) {
            String ownerName = BytecodeHelper.getClassInternalName(iterType);
            if (iterType.getOuterClass() == null) break;
            FieldNode thisField = iterType.getField("this$0");
            iterType = iterType.getOuterClass();
            if (thisField == null) {
                // closure within inner class
                while (ClassHelper.isGeneratedFunction(iterType)) {
                    // GROOVY-8881: cater for closures within closures - getThisObject is already outer class of all closures
                    iterType = iterType.getOuterClass();
                }
                mv.visitMethodInsn(INVOKEVIRTUAL, BytecodeHelper.getClassInternalName(ClassHelper.CLOSURE_TYPE), "getThisObject", "()Ljava/lang/Object;", false);
                mv.visitTypeInsn(CHECKCAST, BytecodeHelper.getClassInternalName(iterType));
            } else {
                ClassNode thisFieldType = thisField.getType();
                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 (propertyName != null) {
        // TODO: spread safe should be handled inside
        if (adapter == getProperty && !pexp.isSpreadSafe()) {
            controller.getCallSiteWriter().makeGetPropertySite(objectExpression, propertyName, pexp.isSafe(), pexp.isImplicitThis());
        } else if (adapter == getGroovyObjectProperty && !pexp.isSpreadSafe()) {
            controller.getCallSiteWriter().makeGroovyObjectGetPropertySite(objectExpression, propertyName, pexp.isSafe(), pexp.isImplicitThis());
        } else {
            controller.getCallSiteWriter().fallbackAttributeOrPropertySite(pexp, objectExpression, propertyName, adapter);
        }
    } else {
        controller.getCallSiteWriter().fallbackAttributeOrPropertySite(pexp, objectExpression, null, adapter);
    }
}
 
Example 4
Source File: InnerClassVisitor.java    From groovy with Apache License 2.0 4 votes vote down vote up
@Override
public void visitConstructorCallExpression(ConstructorCallExpression call) {
    super.visitConstructorCallExpression(call);
    if (!call.isUsingAnonymousInnerClass()) {
        passThisReference(call);
        return;
    }

    InnerClassNode innerClass = (InnerClassNode) call.getType();
    ClassNode outerClass = innerClass.getOuterClass();
    ClassNode superClass = innerClass.getSuperClass();
    if (!superClass.isInterface() && superClass.getOuterClass() != null
            && !(superClass.isStaticClass() || (superClass.getModifiers() & ACC_STATIC) != 0)) {
        insertThis0ToSuperCall(call, innerClass);
    }
    if (!innerClass.getDeclaredConstructors().isEmpty()) return;
    if ((innerClass.getModifiers() & ACC_STATIC) != 0) return;

    VariableScope scope = innerClass.getVariableScope();
    if (scope == null) return;
    boolean isStatic = !inClosure && isStatic(innerClass, scope, call);

    // expressions = constructor call arguments
    List<Expression> expressions = ((TupleExpression) call.getArguments()).getExpressions();
    // block = init code for the constructor we produce
    BlockStatement block = new BlockStatement();
    // parameters = parameters of the constructor
    int additionalParamCount = (isStatic ? 0 : 1) + scope.getReferencedLocalVariablesCount();
    List<Parameter> parameters = new ArrayList<>(expressions.size() + additionalParamCount);
    // superCallArguments = arguments for the super call == the constructor call arguments
    List<Expression> superCallArguments = new ArrayList<>(expressions.size());

    // first we add a super() call for all expressions given in the constructor call expression
    for (int i = 0, n = expressions.size(); i < n; i += 1) {
        // add one parameter for each expression in the constructor call
        Parameter param = new Parameter(ClassHelper.OBJECT_TYPE, "p" + additionalParamCount + i);
        parameters.add(param);
        // add the corresponding argument to the super constructor call
        superCallArguments.add(new VariableExpression(param));
    }

    // add the super call
    ConstructorCallExpression cce = new ConstructorCallExpression(
            ClassNode.SUPER,
            new TupleExpression(superCallArguments)
    );

    block.addStatement(new ExpressionStatement(cce));

    int pCount = 0;
    if (!isStatic) {
        // need to pass "this" to access unknown methods/properties
        expressions.add(pCount, VariableExpression.THIS_EXPRESSION);

        ClassNode enclosingType = (inClosure ? ClassHelper.CLOSURE_TYPE : outerClass).getPlainNodeReference();
        Parameter thisParameter = new Parameter(enclosingType, "p" + pCount);
        parameters.add(pCount++, thisParameter);

        // "this" reference is saved in a field named "this$0"
        FieldNode thisField = innerClass.addField("this$0", ACC_FINAL | ACC_SYNTHETIC, enclosingType, null);
        addFieldInit(thisParameter, thisField, block);
    }

    // for each shared variable, add a Reference field
    for (Iterator<Variable> it = scope.getReferencedLocalVariablesIterator(); it.hasNext();) {
        Variable var = it.next();

        VariableExpression ve = new VariableExpression(var);
        ve.setClosureSharedVariable(true);
        ve.setUseReferenceDirectly(true);
        expressions.add(pCount, ve);

        ClassNode referenceType = ClassHelper.REFERENCE_TYPE.getPlainNodeReference();
        Parameter p = new Parameter(referenceType, "p" + pCount);
        p.setOriginType(var.getOriginType());
        parameters.add(pCount++, p);

        VariableExpression initial = new VariableExpression(p);
        initial.setSynthetic(true);
        initial.setUseReferenceDirectly(true);
        FieldNode pField = innerClass.addFieldFirst(ve.getName(), ACC_PUBLIC | ACC_SYNTHETIC, referenceType, initial);
        pField.setHolder(true);
        pField.setOriginType(ClassHelper.getWrapper(var.getOriginType()));
    }

    innerClass.addConstructor(ACC_SYNTHETIC, parameters.toArray(Parameter.EMPTY_ARRAY), ClassNode.EMPTY_ARRAY, block);
}
 
Example 5
Source File: ClosureWriter.java    From groovy with Apache License 2.0 4 votes vote down vote up
protected ClassNode createClosureClass(final ClosureExpression expression, final int modifiers) {
    ClassNode classNode = controller.getClassNode();
    ClassNode outerClass = controller.getOutermostClass();
    String name = genClosureClassName();
    boolean staticMethodOrInStaticClass = controller.isStaticMethod() || classNode.isStaticClass();

    Parameter[] parameters = expression.getParameters();
    if (parameters == null) {
        parameters = Parameter.EMPTY_ARRAY;
    } else if (parameters.length == 0) {
        // let's create a default 'it' parameter
        Parameter it = new Parameter(ClassHelper.OBJECT_TYPE, "it", ConstantExpression.NULL);
        parameters = new Parameter[]{it};
        Variable ref = expression.getVariableScope().getDeclaredVariable("it");
        if (ref!=null) it.setClosureSharedVariable(ref.isClosureSharedVariable());
    }

    Parameter[] localVariableParams = getClosureSharedVariables(expression);
    removeInitialValues(localVariableParams);

    InnerClassNode answer = new InnerClassNode(classNode, name, modifiers, ClassHelper.CLOSURE_TYPE.getPlainNodeReference());
    answer.setEnclosingMethod(controller.getMethodNode());
    answer.setSynthetic(true);
    answer.setUsingGenerics(outerClass.isUsingGenerics());
    answer.setSourcePosition(expression);

    if (staticMethodOrInStaticClass) {
        answer.setStaticClass(true);
    }
    if (controller.isInScriptBody()) {
        answer.setScriptBody(true);
    }
    MethodNode method =
            answer.addMethod("doCall", ACC_PUBLIC, ClassHelper.OBJECT_TYPE, parameters, ClassNode.EMPTY_ARRAY, expression.getCode());
    method.setSourcePosition(expression);

    VariableScope varScope = expression.getVariableScope();
    if (varScope == null) {
        throw new RuntimeException(
                "Must have a VariableScope by now! for expression: " + expression + " class: " + name);
    } else {
        method.setVariableScope(varScope.copy());
    }
    if (parameters.length > 1
            || (parameters.length == 1
            && parameters[0].getType() != null
            && parameters[0].getType() != ClassHelper.OBJECT_TYPE
            && !ClassHelper.OBJECT_TYPE.equals(parameters[0].getType().getComponentType())))
    {

        // let's add a typesafe call method
        MethodNode call = answer.addMethod(
                "call",
                ACC_PUBLIC,
                ClassHelper.OBJECT_TYPE,
                parameters,
                ClassNode.EMPTY_ARRAY,
                new ReturnStatement(
                        new MethodCallExpression(
                                VariableExpression.THIS_EXPRESSION,
                                "doCall",
                                new ArgumentListExpression(parameters))));
        call.setSourcePosition(expression);
    }

    // let's make the constructor
    BlockStatement block = createBlockStatementForConstructor(expression, outerClass, classNode);

    // let's assign all the parameter fields from the outer context
    addFieldsAndGettersForLocalVariables(answer, localVariableParams);

    addConstructor(expression, localVariableParams, answer, block);

    correctAccessedVariable(answer,expression);

    return answer;
}