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);
}
}
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()));
}
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())));
}
}
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()));
}
}
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();
}
}
Aggregations