Skip to content

Commit

Permalink
Add a common abstract class for type definitions (classes, records, i…
Browse files Browse the repository at this point in the history
…nterfaces, enums) (#162)

* Use a common abstract class for types (objects, records, interfaces, records) to reuse behavior

* Add a method for getting this instance during building

* Update graalvm

* Remove getThis method and remove unneeded builder properties
  • Loading branch information
andriy-dmytruk authored Oct 28, 2024
1 parent 69e692b commit f9c5304
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 117 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
* @since 1.0
*/
@Experimental
abstract sealed class AbstractElement permits ClassDef, EnumDef, FieldDef, InterfaceDef, MethodDef, ParameterDef, PropertyDef, RecordDef {
abstract sealed class AbstractElement permits ObjectDef, FieldDef, MethodDef, ParameterDef, PropertyDef {

protected final String name;
protected final Set<Modifier> modifiers;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@
* @since 1.0
*/
@Experimental
public sealed class AbstractElementBuilder<ThisType> permits ClassDef.ClassDefBuilder, EnumDef.EnumDefBuilder, FieldDef.FieldDefBuilder, InterfaceDef.InterfaceDefBuilder, MethodDef.MethodDefBuilder, ParameterDef.ParameterDefBuilder, PropertyDef.PropertyDefBuilder, RecordDef.RecordDefBuilder {
public sealed class AbstractElementBuilder<ThisType> permits ObjectDefBuilder, FieldDef.FieldDefBuilder, MethodDef.MethodDefBuilder, ParameterDef.ParameterDefBuilder, PropertyDef.PropertyDefBuilder {

protected final String name;
protected EnumSet<Modifier> modifiers = EnumSet.noneOf(Modifier.class);
protected List<AnnotationDef> annotations = new ArrayList<>();
protected List<String> javadoc = new ArrayList<>();
private final ThisType thisInstance;
protected final ThisType thisInstance;

protected AbstractElementBuilder(String name) {
this.name = name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,11 @@
* @since 1.0
*/
@Experimental
public final class ClassDef extends AbstractElement implements ObjectDef {
public final class ClassDef extends ObjectDef {

private final List<FieldDef> fields;
private final List<MethodDef> methods;
private final List<PropertyDef> properties;
private final List<TypeDef.TypeVariable> typeVariables;
private final List<TypeDef> superinterfaces;
private final ClassTypeDef superclass;

private ClassDef(String name,
Expand All @@ -52,12 +50,10 @@ private ClassDef(String name,
List<TypeDef.TypeVariable> typeVariables,
List<TypeDef> superinterfaces,
ClassTypeDef superclass) {
super(name, modifiers, annotations, javadoc);
super(name, modifiers, annotations, javadoc, methods, superinterfaces);
this.fields = fields;
this.methods = methods;
this.properties = properties;
this.typeVariables = typeVariables;
this.superinterfaces = superinterfaces;
this.superclass = superclass;
}

Expand All @@ -69,10 +65,6 @@ public List<FieldDef> getFields() {
return fields;
}

public List<MethodDef> getMethods() {
return methods;
}

public List<PropertyDef> getProperties() {
return properties;
}
Expand All @@ -81,10 +73,6 @@ public List<TypeDef.TypeVariable> getTypeVariables() {
return typeVariables;
}

public List<TypeDef> getSuperinterfaces() {
return superinterfaces;
}

@Nullable
public ClassTypeDef getSuperclass() {
return superclass;
Expand Down Expand Up @@ -152,13 +140,11 @@ public String toString() {
* @since 1.0
*/
@Experimental
public static final class ClassDefBuilder extends AbstractElementBuilder<ClassDefBuilder> {
public static final class ClassDefBuilder extends ObjectDefBuilder<ClassDefBuilder> {

private final List<FieldDef> fields = new ArrayList<>();
private final List<MethodDef> methods = new ArrayList<>();
private final List<PropertyDef> properties = new ArrayList<>();
private final List<TypeDef.TypeVariable> typeVariables = new ArrayList<>();
private final List<TypeDef> superinterfaces = new ArrayList<>();
private ClassTypeDef superclass;

private ClassDefBuilder(String name) {
Expand All @@ -175,11 +161,6 @@ public ClassDefBuilder addField(FieldDef field) {
return this;
}

public ClassDefBuilder addMethod(MethodDef method) {
methods.add(method);
return this;
}

public ClassDefBuilder addProperty(PropertyDef property) {
properties.add(property);
return this;
Expand All @@ -190,11 +171,6 @@ public ClassDefBuilder addTypeVariable(TypeDef.TypeVariable typeVariable) {
return this;
}

public ClassDefBuilder addSuperinterface(TypeDef superinterface) {
superinterfaces.add(superinterface);
return this;
}

public ClassDef build() {
return new ClassDef(name, modifiers, fields, methods, properties, annotations, javadoc, typeVariables, superinterfaces, superclass);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,9 @@
* @since 1.0
*/
@Experimental
public final class EnumDef extends AbstractElement implements ObjectDef {
public final class EnumDef extends ObjectDef {

private final List<String> enumConstants;
private final List<MethodDef> methods;
private final List<TypeDef> superinterfaces;

private EnumDef(String name,
EnumSet<Modifier> modifiers,
Expand All @@ -42,60 +40,38 @@ private EnumDef(String name,
List<String> javadoc,
List<String> enumConstants,
List<TypeDef> superinterfaces) {
super(name, modifiers, annotations, javadoc);
this.methods = methods;
super(name, modifiers, annotations, javadoc, methods, superinterfaces);
this.enumConstants = enumConstants;
this.superinterfaces = superinterfaces;
}

public static EnumDefBuilder builder(String name) {
return new EnumDefBuilder(name);
}

public List<MethodDef> getMethods() {
return methods;
}

public List<String> getEnumConstants() {
return enumConstants;
}

public List<TypeDef> getSuperinterfaces() {
return superinterfaces;
}

/**
* The enum definition builder.
*
* @author Denis Stepanov
* @since 1.0
*/
@Experimental
public static final class EnumDefBuilder extends AbstractElementBuilder<EnumDefBuilder> {
public static final class EnumDefBuilder extends ObjectDefBuilder<EnumDefBuilder> {

private final List<String> enumConstants = new ArrayList<>();
private final List<MethodDef> methods = new ArrayList<>();
private final List<TypeDef> superinterfaces = new ArrayList<>();

private EnumDefBuilder(String name) {
super(name);
}

public EnumDefBuilder addMethod(MethodDef method) {
methods.add(method);
return this;
}

public EnumDefBuilder addEnumConstant(String name) {
enumConstants.add(name);
return this;
}

public EnumDefBuilder addSuperinterface(TypeDef superinterface) {
superinterfaces.add(superinterface);
return this;
}

public EnumDef build() {
return new EnumDef(name, modifiers, methods, annotations, javadoc, enumConstants, superinterfaces);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,10 @@
* @since 1.0
*/
@Experimental
public final class InterfaceDef extends AbstractElement implements ObjectDef {
public final class InterfaceDef extends ObjectDef {

private final List<MethodDef> methods;
private final List<PropertyDef> properties;
private final List<TypeDef.TypeVariable> typeVariables;
private final List<TypeDef> superinterfaces;

private InterfaceDef(String name,
EnumSet<Modifier> modifiers,
Expand All @@ -44,21 +42,15 @@ private InterfaceDef(String name,
List<String> javadoc,
List<TypeDef.TypeVariable> typeVariables,
List<TypeDef> superinterfaces) {
super(name, modifiers, annotations, javadoc);
this.methods = methods;
super(name, modifiers, annotations, javadoc, methods, superinterfaces);
this.properties = properties;
this.typeVariables = typeVariables;
this.superinterfaces = superinterfaces;
}

public static InterfaceDefBuilder builder(String name) {
return new InterfaceDefBuilder(name);
}

public List<MethodDef> getMethods() {
return methods;
}

public List<PropertyDef> getProperties() {
return properties;
}
Expand All @@ -67,33 +59,22 @@ public List<TypeDef.TypeVariable> getTypeVariables() {
return typeVariables;
}

public List<TypeDef> getSuperinterfaces() {
return superinterfaces;
}

/**
* The interface definition builder.
*
* @author Denis Stepanov
* @since 1.0
*/
@Experimental
public static final class InterfaceDefBuilder extends AbstractElementBuilder<InterfaceDefBuilder> {
public static final class InterfaceDefBuilder extends ObjectDefBuilder<InterfaceDefBuilder> {

private final List<MethodDef> methods = new ArrayList<>();
private final List<PropertyDef> properties = new ArrayList<>();
private final List<TypeDef.TypeVariable> typeVariables = new ArrayList<>();
private final List<TypeDef> superinterfaces = new ArrayList<>();

private InterfaceDefBuilder(String name) {
super(name);
}

public InterfaceDefBuilder addMethod(MethodDef method) {
methods.add(method);
return this;
}

public InterfaceDefBuilder addProperty(PropertyDef property) {
properties.add(property);
return this;
Expand All @@ -104,11 +85,6 @@ public InterfaceDefBuilder addTypeVariable(TypeDef.TypeVariable typeVariable) {
return this;
}

public InterfaceDefBuilder addSuperinterface(TypeDef superinterface) {
superinterfaces.add(superinterface);
return this;
}

public InterfaceDef build() {
return new InterfaceDef(name, modifiers, methods, properties, annotations, javadoc, typeVariables, superinterfaces);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,56 @@
*/
package io.micronaut.sourcegen.model;

import io.micronaut.core.annotation.Experimental;
import io.micronaut.core.naming.NameUtils;

import javax.lang.model.element.Modifier;
import java.util.List;
import java.util.Set;

/**
* The interface defining the object type.
* The abstract class representing a type: class, enum, interface or record.
*
* @author Denis Stepanov
* @since 1.0
*/
public interface ObjectDef {
@Experimental
public abstract sealed class ObjectDef extends AbstractElement permits ClassDef, EnumDef, InterfaceDef, RecordDef {

private final List<MethodDef> methods;
private final List<TypeDef> superinterfaces;

ObjectDef(
String name, Set<Modifier> modifiers, List<AnnotationDef> annotations,
List<String> javadoc, List<MethodDef> methods, List<TypeDef> superinterfaces
) {
super(name, modifiers, annotations, javadoc);
this.methods = methods;
this.superinterfaces = superinterfaces;
}

String getName();
public final List<MethodDef> getMethods() {
return methods;
}

public final List<TypeDef> getSuperinterfaces() {
return superinterfaces;
}

default String getPackageName() {
public final String getPackageName() {
return NameUtils.getPackageName(getName());
}

default String getSimpleName() {
public final String getSimpleName() {
return NameUtils.getSimpleName(getName());
}

default ClassTypeDef asTypeDef() {
/**
* Get the type definition for this type.
*
* @return The type definition
*/
public ClassTypeDef asTypeDef() {
return ClassTypeDef.of(getName());
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright 2017-2023 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micronaut.sourcegen.model;

import io.micronaut.core.annotation.Experimental;

import java.util.ArrayList;
import java.util.List;

/**
* The abstract builder that is used for specific types: interfaces, classes, records or enums.
*
* @param <ThisType> The type of this builder
* @author Andriy Dmytruk
* @since 1.3
*/
@Experimental
public sealed class ObjectDefBuilder<ThisType>
extends AbstractElementBuilder<ThisType>
permits ClassDef.ClassDefBuilder, InterfaceDef.InterfaceDefBuilder,
RecordDef.RecordDefBuilder, EnumDef.EnumDefBuilder {

protected final List<MethodDef> methods = new ArrayList<>();
protected final List<TypeDef> superinterfaces = new ArrayList<>();

protected ObjectDefBuilder(String name) {
super(name);
}

public final ThisType addMethod(MethodDef method) {
methods.add(method);
return thisInstance;
}

public final ThisType addSuperinterface(TypeDef superinterface) {
superinterfaces.add(superinterface);
return thisInstance;
}

}
Loading

0 comments on commit f9c5304

Please sign in to comment.