Search in sources :

Example 1 with RecordComponentNode

use of org.codehaus.groovy.ast.RecordComponentNode in project groovy by apache.

the class ExtendedVerifier method visitRecordComponents.

private void visitRecordComponents(ClassNode node) {
    for (RecordComponentNode recordComponentNode : node.getRecordComponents()) {
        visitAnnotations(recordComponentNode, RECORD_COMPONENT_TARGET);
        visitTypeAnnotations(recordComponentNode.getType());
        extractTypeUseAnnotations(recordComponentNode.getAnnotations(), recordComponentNode.getType(), RECORD_COMPONENT_TARGET);
    }
}
Also used : RecordComponentNode(org.codehaus.groovy.ast.RecordComponentNode)

Example 2 with RecordComponentNode

use of org.codehaus.groovy.ast.RecordComponentNode in project groovy by apache.

the class Java16 method makeRecordComponents.

@Override
protected void makeRecordComponents(final CompileUnit cu, final ClassNode classNode, final Class<?> clazz) {
    if (!clazz.isRecord())
        return;
    classNode.setRecordComponents(Arrays.stream(clazz.getRecordComponents()).map(rc -> {
        ClassNode type = makeClassNode(cu, rc.getGenericType(), rc.getType());
        type.addTypeAnnotations(Arrays.stream(rc.getAnnotatedType().getAnnotations()).map(annotation -> {
            AnnotationNode node = new AnnotationNode(ClassHelper.make(annotation.annotationType()));
            configureAnnotation(node, annotation);
            return node;
        }).collect(Collectors.toList()));
        return new RecordComponentNode(classNode, rc.getName(), type, Arrays.stream(rc.getAnnotations()).map(annotation -> {
            AnnotationNode node = new AnnotationNode(ClassHelper.make(annotation.annotationType()));
            configureAnnotation(node, annotation);
            return node;
        }).collect(Collectors.toList()));
    }).collect(Collectors.toList()));
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) RecordComponentNode(org.codehaus.groovy.ast.RecordComponentNode) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode)

Example 3 with RecordComponentNode

use of org.codehaus.groovy.ast.RecordComponentNode in project groovy by apache.

the class RecordTypeASTTransformation method doProcessRecordType.

private void doProcessRecordType(ClassNode cNode, PropertyHandler handler) {
    List<AnnotationNode> annotations = cNode.getAnnotations(RECORD_OPTIONS_TYPE);
    AnnotationNode options = annotations.isEmpty() ? null : annotations.get(0);
    RecordTypeMode mode = getMode(options, "mode");
    boolean isPostJDK16 = false;
    String message = "Expecting JDK16+ but unable to determine target bytecode";
    if (sourceUnit != null) {
        CompilerConfiguration config = sourceUnit.getConfiguration();
        String targetBytecode = config.getTargetBytecode();
        isPostJDK16 = CompilerConfiguration.isPostJDK16(targetBytecode);
        message = "Expecting JDK16+ but found " + targetBytecode;
    }
    boolean isNative = isPostJDK16 && mode != RecordTypeMode.EMULATE;
    if (isNative) {
        String sName = cNode.getUnresolvedSuperClass().getName();
        // level when using the record keyword so do a few more sanity checks here
        if (!sName.equals("java.lang.Object") && !sName.equals(RECORD_CLASS_NAME)) {
            addError("Invalid superclass for native record found: " + sName, cNode);
        }
        cNode.setSuperClass(ClassHelper.makeWithoutCaching(RECORD_CLASS_NAME));
        cNode.setModifiers(cNode.getModifiers() | Opcodes.ACC_RECORD);
        final List<PropertyNode> pList = getInstanceProperties(cNode);
        if (!pList.isEmpty()) {
            cNode.setRecordComponents(new ArrayList<>());
        }
        for (PropertyNode pNode : pList) {
            cNode.getRecordComponents().add(new RecordComponentNode(cNode, pNode.getName(), pNode.getOriginType(), pNode.getAnnotations()));
        }
    } else if (mode == RecordTypeMode.NATIVE) {
        addError(message + " when attempting to create a native record", cNode);
    }
    String cName = cNode.getName();
    if (!checkNotInterface(cNode, MY_TYPE_NAME))
        return;
    makeClassFinal(this, cNode);
    makeInnerRecordStatic(cNode);
    final List<PropertyNode> pList = getInstanceProperties(cNode);
    for (PropertyNode pNode : pList) {
        adjustPropertyForShallowImmutability(cNode, pNode, handler);
        pNode.setModifiers(pNode.getModifiers() | ACC_FINAL);
    }
    final List<FieldNode> fList = cNode.getFields();
    for (FieldNode fNode : fList) {
        ensureNotPublic(this, cName, fNode);
    }
    // 0L serialVersionUID by default
    if (cNode.getDeclaredField("serialVersionUID") == null) {
        cNode.addField("serialVersionUID", ACC_PRIVATE | ACC_STATIC | ACC_FINAL, ClassHelper.long_TYPE, constX(0L));
    }
    if (!hasAnnotation(cNode, ToStringASTTransformation.MY_TYPE)) {
        if (isNative) {
            createRecordToString(cNode);
        } else {
            ToStringASTTransformation.createToString(cNode, false, false, null, null, true, false, false, true, false, false, false, false, false, new String[] { "[", "]", "=", ", " });
        }
    }
    if (!hasAnnotation(cNode, EqualsAndHashCodeASTTransformation.MY_TYPE)) {
        if (isNative) {
            createRecordEquals(cNode);
            createRecordHashCode(cNode);
        } else {
            EqualsAndHashCodeASTTransformation.createEquals(cNode, false, false, false, null, null);
            EqualsAndHashCodeASTTransformation.createHashCode(cNode, false, false, false, null, null);
        }
    }
    if (hasAnnotation(cNode, TupleConstructorASTTransformation.MY_TYPE)) {
        AnnotationNode tupleCons = cNode.getAnnotations(TupleConstructorASTTransformation.MY_TYPE).get(0);
        if (unsupportedTupleAttribute(tupleCons, "excludes"))
            return;
        if (unsupportedTupleAttribute(tupleCons, "includes"))
            return;
        if (unsupportedTupleAttribute(tupleCons, "includeProperties"))
            return;
        if (unsupportedTupleAttribute(tupleCons, "includeSuperFields"))
            return;
    }
    if (options != null && memberHasValue(options, COPY_WITH, Boolean.TRUE) && !hasDeclaredMethod(cNode, COPY_WITH, 1)) {
        createCopyWith(cNode, pList);
    }
    if ((options == null || !memberHasValue(options, GET_AT, Boolean.FALSE)) && !hasDeclaredMethod(cNode, GET_AT, 1)) {
        createGetAt(cNode, pList);
    }
    if ((options == null || !memberHasValue(options, TO_LIST, Boolean.FALSE)) && !hasDeclaredMethod(cNode, TO_LIST, 0)) {
        createToList(cNode, pList);
    }
    if ((options == null || !memberHasValue(options, TO_MAP, Boolean.FALSE)) && !hasDeclaredMethod(cNode, TO_MAP, 0)) {
        createToMap(cNode, pList);
    }
    if (options != null && memberHasValue(options, COMPONENTS, Boolean.TRUE) && !hasDeclaredMethod(cNode, COMPONENTS, 0)) {
        createComponents(cNode, pList);
    }
    if ((options == null || !memberHasValue(options, SIZE, Boolean.FALSE)) && !hasDeclaredMethod(cNode, SIZE, 0)) {
        addGeneratedMethod(cNode, SIZE, PUBLIC_FINAL, int_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, returnS(constX(pList.size())));
    }
}
Also used : RecordTypeMode(groovy.transform.RecordTypeMode) RecordComponentNode(org.codehaus.groovy.ast.RecordComponentNode) FieldNode(org.codehaus.groovy.ast.FieldNode) AnnotationNode(org.codehaus.groovy.ast.AnnotationNode) PropertyNode(org.codehaus.groovy.ast.PropertyNode) CompilerConfiguration(org.codehaus.groovy.control.CompilerConfiguration)

Example 4 with RecordComponentNode

use of org.codehaus.groovy.ast.RecordComponentNode in project groovy by apache.

the class ClassSignatureParser method configureClass.

static void configureClass(ClassNode classNode, ClassStub stub, AsmReferenceResolver resolver) {
    if (stub.signature != null) {
        parseClassSignature(classNode, stub.signature, resolver);
        return;
    }
    if (stub.superName != null) {
        classNode.setSuperClass(resolver.resolveClass(AsmDecompiler.fromInternalName(stub.superName)));
    }
    ClassNode[] interfaces = new ClassNode[stub.interfaceNames.length];
    for (int i = 0; i < stub.interfaceNames.length; i++) {
        interfaces[i] = resolver.resolveClass(AsmDecompiler.fromInternalName(stub.interfaceNames[i]));
    }
    classNode.setInterfaces(interfaces);
    if (!stub.permittedSubclasses.isEmpty()) {
        List<ClassNode> permittedSubclasses = classNode.getPermittedSubclasses();
        for (String name : stub.permittedSubclasses) {
            permittedSubclasses.add(resolver.resolveClass(AsmDecompiler.fromInternalName(name)));
        }
    }
    if (!stub.recordComponents.isEmpty()) {
        classNode.setRecordComponents(stub.recordComponents.stream().map(r -> {
            ClassNode type = resolver.resolveType(Type.getType(r.descriptor));
            ObjectHolder<ClassNode> typeHolder = new ObjectHolder<>(type);
            if (null != r.signature) {
                new SignatureReader(r.signature).accept(new TypeSignatureParser(resolver) {

                    @Override
                    void finished(final ClassNode result) {
                        typeHolder.setObject(applyErasure(result, typeHolder.getObject()));
                    }
                });
            }
            ClassNode cn = typeHolder.getObject();
            Annotations.addTypeAnnotations(r, cn, resolver);
            RecordComponentNode recordComponentNode = new RecordComponentNode(classNode, r.name, cn);
            Annotations.addAnnotations(r, recordComponentNode, resolver);
            return recordComponentNode;
        }).collect(Collectors.toList()));
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) ObjectHolder(org.apache.groovy.util.ObjectHolder) RecordComponentNode(org.codehaus.groovy.ast.RecordComponentNode) SignatureReader(org.objectweb.asm.signature.SignatureReader)

Example 5 with RecordComponentNode

use of org.codehaus.groovy.ast.RecordComponentNode in project groovy by apache.

the class AsmClassGenerator method visitRecordComponents.

private void visitRecordComponents(final ClassNode classNode) {
    List<RecordComponentNode> recordComponentNodeList = classNode.getRecordComponents();
    if (null == recordComponentNodeList)
        return;
    for (RecordComponentNode recordComponentNode : recordComponentNodeList) {
        final ClassNode type = recordComponentNode.getType();
        RecordComponentVisitor rcv = classVisitor.visitRecordComponent(recordComponentNode.getName(), BytecodeHelper.getTypeDescription(type), BytecodeHelper.getTypeGenericsSignature(type));
        visitAnnotations(recordComponentNode, rcv);
        // the int encoded value of the type reference is ALWAYS `318767104`
        // TODO Get the magic number `318767104` via `TypeReference.newXXX()`
        TypeReference typeRef = new TypeReference(318767104);
        visitTypeAnnotations(recordComponentNode.getType(), rcv, typeRef, "", true);
        rcv.visitEnd();
    }
}
Also used : InterfaceHelperClassNode(org.codehaus.groovy.ast.InterfaceHelperClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) RecordComponentNode(org.codehaus.groovy.ast.RecordComponentNode) RecordComponentVisitor(org.objectweb.asm.RecordComponentVisitor) TypeReference.newTypeReference(org.objectweb.asm.TypeReference.newTypeReference) TypeReference(org.objectweb.asm.TypeReference) TypeReference.newSuperTypeReference(org.objectweb.asm.TypeReference.newSuperTypeReference)

Aggregations

RecordComponentNode (org.codehaus.groovy.ast.RecordComponentNode)5 ClassNode (org.codehaus.groovy.ast.ClassNode)3 AnnotationNode (org.codehaus.groovy.ast.AnnotationNode)2 RecordTypeMode (groovy.transform.RecordTypeMode)1 ObjectHolder (org.apache.groovy.util.ObjectHolder)1 FieldNode (org.codehaus.groovy.ast.FieldNode)1 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)1 InterfaceHelperClassNode (org.codehaus.groovy.ast.InterfaceHelperClassNode)1 PropertyNode (org.codehaus.groovy.ast.PropertyNode)1 CompilerConfiguration (org.codehaus.groovy.control.CompilerConfiguration)1 RecordComponentVisitor (org.objectweb.asm.RecordComponentVisitor)1 TypeReference (org.objectweb.asm.TypeReference)1 TypeReference.newSuperTypeReference (org.objectweb.asm.TypeReference.newSuperTypeReference)1 TypeReference.newTypeReference (org.objectweb.asm.TypeReference.newTypeReference)1 SignatureReader (org.objectweb.asm.signature.SignatureReader)1