mirror of
https://gitee.com/dcren/initializr.git
synced 2026-02-25 21:22:58 +08:00
Polish "Adding field declaration for code generation"
See gh-881
This commit is contained in:
@@ -20,8 +20,7 @@ package io.spring.initializr.generator.language.groovy;
|
||||
* A Groovy expression.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public interface GroovyExpression {
|
||||
public class GroovyExpression {
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ package io.spring.initializr.generator.language.groovy;
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class GroovyExpressionStatement implements GroovyStatement {
|
||||
public class GroovyExpressionStatement extends GroovyStatement {
|
||||
|
||||
private final GroovyExpression expression;
|
||||
|
||||
|
||||
@@ -24,13 +24,13 @@ import io.spring.initializr.generator.language.Annotatable;
|
||||
import io.spring.initializr.generator.language.Annotation;
|
||||
|
||||
/**
|
||||
* Declaration, and potential initialization, of a field in Groovy.
|
||||
* Declaration of a field written in Groovy.
|
||||
*
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public final class GroovyFieldDeclaration implements Annotatable {
|
||||
|
||||
private final List<Annotation> annotations;
|
||||
private final List<Annotation> annotations = new ArrayList<>();
|
||||
|
||||
private final int modifiers;
|
||||
|
||||
@@ -40,12 +40,14 @@ public final class GroovyFieldDeclaration implements Annotatable {
|
||||
|
||||
private final Object value;
|
||||
|
||||
private final boolean initialized;
|
||||
|
||||
private GroovyFieldDeclaration(Builder builder) {
|
||||
this.modifiers = builder.modifiers;
|
||||
this.name = builder.name;
|
||||
this.returnType = builder.returnType;
|
||||
this.value = builder.value;
|
||||
this.annotations = builder.annotations;
|
||||
this.initialized = builder.initialized;
|
||||
}
|
||||
|
||||
public static Builder field(String name) {
|
||||
@@ -78,9 +80,11 @@ public final class GroovyFieldDeclaration implements Annotatable {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
public boolean isInitialized() {
|
||||
return this.initialized;
|
||||
}
|
||||
|
||||
private final List<Annotation> annotations = new ArrayList<>();
|
||||
public static final class Builder {
|
||||
|
||||
private final String name;
|
||||
|
||||
@@ -88,7 +92,9 @@ public final class GroovyFieldDeclaration implements Annotatable {
|
||||
|
||||
private int modifiers;
|
||||
|
||||
private Object value = InitializedStatus.NOT_INITIALIZED;
|
||||
private Object value;
|
||||
|
||||
private boolean initialized;
|
||||
|
||||
private Builder(String name) {
|
||||
this.name = name;
|
||||
@@ -99,13 +105,9 @@ public final class GroovyFieldDeclaration implements Annotatable {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder value(GroovyExpression value) {
|
||||
public Builder value(Object value) {
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder withAnnotation(Annotation annotation) {
|
||||
this.annotations.add(annotation);
|
||||
this.initialized = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -116,14 +118,4 @@ public final class GroovyFieldDeclaration implements Annotatable {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Track if the value has been set or not. Using this because initializing a field to
|
||||
* null should be possible.
|
||||
*/
|
||||
enum InitializedStatus {
|
||||
|
||||
NOT_INITIALIZED;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,9 +23,8 @@ import java.util.List;
|
||||
* An invocation of a method.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public class GroovyMethodInvocation implements GroovyExpression, GroovyStatement {
|
||||
public class GroovyMethodInvocation extends GroovyExpression {
|
||||
|
||||
private final String target;
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or 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.spring.initializr.generator.language.groovy;
|
||||
|
||||
/**
|
||||
* A primitive in the Groovy language.
|
||||
*
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public interface GroovyPrimitive extends GroovyExpression {
|
||||
|
||||
}
|
||||
@@ -1,270 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or 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.spring.initializr.generator.language.groovy;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import io.spring.initializr.generator.language.java.JavaPrimitives;
|
||||
|
||||
/**
|
||||
* Primitives for the Groovy language. Are just wrappers around the
|
||||
* {@link JavaPrimitives}.
|
||||
*
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public final class GroovyPrimitives {
|
||||
|
||||
private GroovyPrimitives() {
|
||||
// hide public constructor
|
||||
}
|
||||
|
||||
public static GroovyPrimitive byteValue(Byte value) {
|
||||
return new GroovyByte(value);
|
||||
}
|
||||
|
||||
public static GroovyPrimitive shortValue(Short value) {
|
||||
return new GroovyShort(value);
|
||||
}
|
||||
|
||||
public static GroovyPrimitive integerValue(Integer value) {
|
||||
return new GroovyInteger(value);
|
||||
}
|
||||
|
||||
public static GroovyPrimitive doubleValue(Double value) {
|
||||
return new GroovyDouble(value);
|
||||
}
|
||||
|
||||
public static GroovyPrimitive longValue(Long value) {
|
||||
return new GroovyLong(value);
|
||||
}
|
||||
|
||||
public static GroovyPrimitive charValue(String charString) {
|
||||
return new GroovyChar(charString);
|
||||
}
|
||||
|
||||
public static GroovyPrimitive booleanValue(Boolean value) {
|
||||
return new GroovyBoolean(value);
|
||||
}
|
||||
|
||||
private static String valueOrNull(Object value, Supplier<String> nonNullSupplier) {
|
||||
if (value == null) {
|
||||
return "null";
|
||||
}
|
||||
return nonNullSupplier.get();
|
||||
}
|
||||
|
||||
public static final class GroovyByte implements GroovyPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "java.lang.Byte";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "byte";
|
||||
|
||||
protected final Byte value;
|
||||
|
||||
public GroovyByte(Byte value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> Byte.toString(this.value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class GroovyShort implements GroovyPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "java.lang.Short";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "short";
|
||||
|
||||
protected final Short value;
|
||||
|
||||
private GroovyShort(Short value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> Short.toString(this.value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class GroovyInteger implements GroovyPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "java.lang.Integer";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "int";
|
||||
|
||||
protected final Integer value;
|
||||
|
||||
private GroovyInteger(Integer value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> Integer.toString(this.value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class GroovyDouble implements GroovyPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "java.lang.Double";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "double";
|
||||
|
||||
protected final Double value;
|
||||
|
||||
private GroovyDouble(Double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> Double.toString(this.value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class GroovyFloat implements GroovyPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "java.lang.Float";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "float";
|
||||
|
||||
protected final Float value;
|
||||
|
||||
private GroovyFloat(Float value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> this.value + "f");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class GroovyLong implements GroovyPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "java.lang.Long";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "long";
|
||||
|
||||
protected final Long value;
|
||||
|
||||
private GroovyLong(Long value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> this.value + "L");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class GroovyChar implements GroovyPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "java.lang.Character";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "char";
|
||||
|
||||
protected final String value;
|
||||
|
||||
private GroovyChar(String charString) {
|
||||
this.value = charString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> this.value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class GroovyBoolean implements GroovyPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "java.lang.Boolean";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "boolean";
|
||||
|
||||
protected final Boolean value;
|
||||
|
||||
private GroovyBoolean(Boolean value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> Boolean.toString(this.value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,12 +20,17 @@ package io.spring.initializr.generator.language.groovy;
|
||||
* A return statement.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public class GroovyReturnStatement extends GroovyExpressionStatement {
|
||||
public class GroovyReturnStatement extends GroovyStatement {
|
||||
|
||||
private final GroovyExpression expression;
|
||||
|
||||
public GroovyReturnStatement(GroovyExpression expression) {
|
||||
super(expression);
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public GroovyExpression getExpression() {
|
||||
return this.expression;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
@@ -53,10 +52,10 @@ public class GroovySourceCodeWriter implements SourceCodeWriter<GroovySourceCode
|
||||
|
||||
private static final Map<Predicate<Integer>, String> TYPE_MODIFIERS;
|
||||
|
||||
private static final Map<Predicate<Integer>, String> METHOD_MODIFIERS;
|
||||
|
||||
private static final Map<Predicate<Integer>, String> FIELD_MODIFIERS;
|
||||
|
||||
private static final Map<Predicate<Integer>, String> METHOD_MODIFIERS;
|
||||
|
||||
static {
|
||||
Map<Predicate<Integer>, String> typeModifiers = new LinkedHashMap<>();
|
||||
typeModifiers.put(Modifier::isProtected, "protected");
|
||||
@@ -66,11 +65,6 @@ public class GroovySourceCodeWriter implements SourceCodeWriter<GroovySourceCode
|
||||
typeModifiers.put(Modifier::isFinal, "final");
|
||||
typeModifiers.put(Modifier::isStrict, "strictfp");
|
||||
TYPE_MODIFIERS = typeModifiers;
|
||||
Map<Predicate<Integer>, String> methodModifiers = new LinkedHashMap<>(typeModifiers);
|
||||
methodModifiers.put(Modifier::isSynchronized, "synchronized");
|
||||
methodModifiers.put(Modifier::isNative, "native");
|
||||
METHOD_MODIFIERS = methodModifiers;
|
||||
|
||||
Map<Predicate<Integer>, String> fieldModifiers = new LinkedHashMap<>();
|
||||
fieldModifiers.put(Modifier::isPublic, "public");
|
||||
fieldModifiers.put(Modifier::isProtected, "protected");
|
||||
@@ -80,6 +74,10 @@ public class GroovySourceCodeWriter implements SourceCodeWriter<GroovySourceCode
|
||||
fieldModifiers.put(Modifier::isTransient, "transient");
|
||||
fieldModifiers.put(Modifier::isVolatile, "volatile");
|
||||
FIELD_MODIFIERS = fieldModifiers;
|
||||
Map<Predicate<Integer>, String> methodModifiers = new LinkedHashMap<>(typeModifiers);
|
||||
methodModifiers.put(Modifier::isSynchronized, "synchronized");
|
||||
methodModifiers.put(Modifier::isNative, "native");
|
||||
METHOD_MODIFIERS = methodModifiers;
|
||||
}
|
||||
|
||||
private final IndentingWriterFactory indentingWriterFactory;
|
||||
@@ -90,7 +88,7 @@ public class GroovySourceCodeWriter implements SourceCodeWriter<GroovySourceCode
|
||||
|
||||
@Override
|
||||
public void writeTo(Path directory, GroovySourceCode sourceCode) throws IOException {
|
||||
if (!directory.toFile().exists()) {
|
||||
if (!Files.exists(directory)) {
|
||||
Files.createDirectories(directory);
|
||||
}
|
||||
for (GroovyCompilationUnit compilationUnit : sourceCode.getCompilationUnits()) {
|
||||
@@ -142,37 +140,65 @@ public class GroovySourceCodeWriter implements SourceCodeWriter<GroovySourceCode
|
||||
}
|
||||
}
|
||||
|
||||
private void writeFieldDeclaration(IndentingWriter writer, GroovyFieldDeclaration fieldDeclaration) {
|
||||
if (!fieldDeclaration.getAnnotations().isEmpty()) {
|
||||
writeAnnotations(writer, fieldDeclaration);
|
||||
private void writeAnnotations(IndentingWriter writer, Annotatable annotatable) {
|
||||
annotatable.getAnnotations().forEach((annotation) -> writeAnnotation(writer, annotation));
|
||||
}
|
||||
|
||||
private void writeAnnotation(IndentingWriter writer, Annotation annotation) {
|
||||
writer.print("@" + getUnqualifiedName(annotation.getName()));
|
||||
List<Annotation.Attribute> attributes = annotation.getAttributes();
|
||||
if (!attributes.isEmpty()) {
|
||||
writer.print("(");
|
||||
if (attributes.size() == 1 && attributes.get(0).getName().equals("value")) {
|
||||
writer.print(formatAnnotationAttribute(attributes.get(0)));
|
||||
}
|
||||
else {
|
||||
writer.print(attributes.stream()
|
||||
.map((attribute) -> attribute.getName() + " = " + formatAnnotationAttribute(attribute))
|
||||
.collect(Collectors.joining(", ")));
|
||||
}
|
||||
writer.print(")");
|
||||
}
|
||||
writeFieldModifiers(writer, fieldDeclaration);
|
||||
writer.println();
|
||||
}
|
||||
|
||||
private String formatAnnotationAttribute(Annotation.Attribute attribute) {
|
||||
List<String> values = attribute.getValues();
|
||||
if (attribute.getType().equals(Class.class)) {
|
||||
return formatValues(values, this::getUnqualifiedName);
|
||||
}
|
||||
if (Enum.class.isAssignableFrom(attribute.getType())) {
|
||||
return formatValues(values, (value) -> {
|
||||
String enumValue = value.substring(value.lastIndexOf(".") + 1);
|
||||
String enumClass = value.substring(0, value.lastIndexOf("."));
|
||||
return String.format("%s.%s", getUnqualifiedName(enumClass), enumValue);
|
||||
});
|
||||
}
|
||||
if (attribute.getType().equals(String.class)) {
|
||||
return formatValues(values, (value) -> String.format("\"%s\"", value));
|
||||
}
|
||||
return formatValues(values, (value) -> String.format("%s", value));
|
||||
}
|
||||
|
||||
private String formatValues(List<String> values, Function<String, String> formatter) {
|
||||
String result = values.stream().map(formatter).collect(Collectors.joining(", "));
|
||||
return (values.size() > 1) ? "{ " + result + " }" : result;
|
||||
}
|
||||
|
||||
private void writeFieldDeclaration(IndentingWriter writer, GroovyFieldDeclaration fieldDeclaration) {
|
||||
writeAnnotations(writer, fieldDeclaration);
|
||||
writeModifiers(writer, FIELD_MODIFIERS, fieldDeclaration.getModifiers());
|
||||
writer.print(getUnqualifiedName(fieldDeclaration.getReturnType()));
|
||||
writer.print(" ");
|
||||
writer.print(fieldDeclaration.getName());
|
||||
if (!Objects.equals(GroovyFieldDeclaration.InitializedStatus.NOT_INITIALIZED, fieldDeclaration.getValue())) {
|
||||
if (fieldDeclaration.isInitialized()) {
|
||||
writer.print(" = ");
|
||||
writeFieldValue(writer, fieldDeclaration.getValue(), fieldDeclaration.getReturnType());
|
||||
writer.print(String.valueOf(fieldDeclaration.getValue()));
|
||||
}
|
||||
writer.println();
|
||||
writer.println();
|
||||
}
|
||||
|
||||
private void writeFieldValue(IndentingWriter writer, Object value, String returnType) {
|
||||
quote(writer, value, returnType);
|
||||
writer.print(String.valueOf(value));
|
||||
quote(writer, value, returnType);
|
||||
}
|
||||
|
||||
private void quote(IndentingWriter writer, Object value, String returnType) {
|
||||
if (value instanceof Character || "char".equals(returnType) || "java.lang.Character".equals(returnType)) {
|
||||
writer.print("\'");
|
||||
}
|
||||
else if (value instanceof CharSequence) {
|
||||
writer.print("\"");
|
||||
}
|
||||
}
|
||||
|
||||
private void writeMethodDeclaration(IndentingWriter writer, GroovyMethodDeclaration methodDeclaration) {
|
||||
writeAnnotations(writer, methodDeclaration);
|
||||
writeModifiers(writer, METHOD_MODIFIERS, methodDeclaration.getModifiers());
|
||||
@@ -200,10 +226,6 @@ public class GroovySourceCodeWriter implements SourceCodeWriter<GroovySourceCode
|
||||
writer.println();
|
||||
}
|
||||
|
||||
private void writeFieldModifiers(IndentingWriter writer, GroovyFieldDeclaration fieldDeclaration) {
|
||||
writeModifiers(writer, FIELD_MODIFIERS, fieldDeclaration.getModifiers());
|
||||
}
|
||||
|
||||
private void writeModifiers(IndentingWriter writer, Map<Predicate<Integer>, String> availableModifiers,
|
||||
int declaredModifiers) {
|
||||
String modifiers = availableModifiers.entrySet().stream()
|
||||
@@ -215,10 +237,6 @@ public class GroovySourceCodeWriter implements SourceCodeWriter<GroovySourceCode
|
||||
}
|
||||
}
|
||||
|
||||
private void writeMethodModifiers(IndentingWriter writer, GroovyMethodDeclaration methodDeclaration) {
|
||||
writeModifiers(writer, METHOD_MODIFIERS, methodDeclaration.getModifiers());
|
||||
}
|
||||
|
||||
private void writeExpression(IndentingWriter writer, GroovyExpression expression) {
|
||||
if (expression instanceof GroovyMethodInvocation) {
|
||||
writeMethodInvocation(writer, (GroovyMethodInvocation) expression);
|
||||
@@ -246,6 +264,12 @@ public class GroovySourceCodeWriter implements SourceCodeWriter<GroovySourceCode
|
||||
imports.add(typeDeclaration.getExtends());
|
||||
}
|
||||
imports.addAll(getRequiredImports(typeDeclaration.getAnnotations(), this::determineImports));
|
||||
for (GroovyFieldDeclaration fieldDeclaration : typeDeclaration.getFieldDeclarations()) {
|
||||
if (requiresImport(fieldDeclaration.getReturnType())) {
|
||||
imports.add(fieldDeclaration.getReturnType());
|
||||
}
|
||||
imports.addAll(getRequiredImports(fieldDeclaration.getAnnotations(), this::determineImports));
|
||||
}
|
||||
for (GroovyMethodDeclaration methodDeclaration : typeDeclaration.getMethodDeclarations()) {
|
||||
if (requiresImport(methodDeclaration.getReturnType())) {
|
||||
imports.add(methodDeclaration.getReturnType());
|
||||
@@ -264,85 +288,6 @@ public class GroovySourceCodeWriter implements SourceCodeWriter<GroovySourceCode
|
||||
return new LinkedHashSet<>(imports);
|
||||
}
|
||||
|
||||
private void writeAnnotations(IndentingWriter writer, Annotatable annotatable) {
|
||||
writeAnnotations(writer, annotatable, true);
|
||||
}
|
||||
|
||||
private void writeAnnotations(IndentingWriter writer, Annotatable annotatable, boolean newLine) {
|
||||
for (Annotation annotation : annotatable.getAnnotations()) {
|
||||
writeAnnotation(writer, annotation, newLine);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeAnnotation(IndentingWriter writer, Annotation annotation, boolean newLine) {
|
||||
writer.print("@" + getUnqualifiedName(annotation.getName()));
|
||||
List<Annotation.Attribute> attributes = annotation.getAttributes();
|
||||
if (!attributes.isEmpty()) {
|
||||
writer.print("(");
|
||||
if (attributes.size() == 1 && attributes.get(0).getName().equals("value")) {
|
||||
writer.print(formatAnnotationAttribute(attributes.get(0)));
|
||||
}
|
||||
else {
|
||||
writer.print(attributes.stream()
|
||||
.map((attribute) -> attribute.getName() + " = " + formatAnnotationAttribute(attribute))
|
||||
.collect(Collectors.joining(", ")));
|
||||
}
|
||||
writer.print(")");
|
||||
}
|
||||
if (newLine) {
|
||||
writer.println();
|
||||
}
|
||||
else {
|
||||
writer.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
private void writeAnnotation(IndentingWriter writer, Annotation annotation) {
|
||||
writeAnnotation(writer, annotation, true);
|
||||
}
|
||||
|
||||
protected String formatAnnotationAttribute(Annotation.Attribute attribute) {
|
||||
List<String> values = attribute.getValues();
|
||||
if (attribute.getType().equals(Class.class)) {
|
||||
return formatValues(values, (value) -> String.format(annotationFormatString(), getUnqualifiedName(value)));
|
||||
}
|
||||
if (Enum.class.isAssignableFrom(attribute.getType())) {
|
||||
return formatValues(values, (value) -> {
|
||||
String enumValue = value.substring(value.lastIndexOf(".") + 1);
|
||||
String enumClass = value.substring(0, value.lastIndexOf("."));
|
||||
return String.format("%s.%s", getUnqualifiedName(enumClass), enumValue);
|
||||
});
|
||||
}
|
||||
if (attribute.getType().equals(String.class)) {
|
||||
return formatValues(values, (value) -> String.format("\"%s\"", value));
|
||||
}
|
||||
return formatValues(values, (value) -> String.format("%s", value));
|
||||
}
|
||||
|
||||
private String formatValues(List<String> values, Function<String, String> formatter) {
|
||||
String result = values.stream().map(formatter).collect(Collectors.joining(", "));
|
||||
return (values.size() > 1) ? formatAnnotationArray(result) : result;
|
||||
}
|
||||
|
||||
private String formatAnnotationArray(String values) {
|
||||
return "{ " + values + " }";
|
||||
}
|
||||
|
||||
private String getUnqualifiedName(String name) {
|
||||
if (!name.contains(".")) {
|
||||
return name;
|
||||
}
|
||||
return name.substring(name.lastIndexOf(".") + 1);
|
||||
}
|
||||
|
||||
private boolean requiresImport(String name) {
|
||||
if (name == null || !name.contains(".")) {
|
||||
return false;
|
||||
}
|
||||
String packageName = name.substring(0, name.lastIndexOf('.'));
|
||||
return !"java.lang".equals(packageName);
|
||||
}
|
||||
|
||||
private Collection<String> determineImports(Annotation annotation) {
|
||||
List<String> imports = new ArrayList<>();
|
||||
imports.add(annotation.getName());
|
||||
@@ -367,8 +312,19 @@ public class GroovySourceCodeWriter implements SourceCodeWriter<GroovySourceCode
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private String annotationFormatString() {
|
||||
return "%s";
|
||||
private String getUnqualifiedName(String name) {
|
||||
if (!name.contains(".")) {
|
||||
return name;
|
||||
}
|
||||
return name.substring(name.lastIndexOf(".") + 1);
|
||||
}
|
||||
|
||||
private boolean requiresImport(String name) {
|
||||
if (name == null || !name.contains(".")) {
|
||||
return false;
|
||||
}
|
||||
String packageName = name.substring(0, name.lastIndexOf('.'));
|
||||
return !"java.lang".equals(packageName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,8 +20,7 @@ package io.spring.initializr.generator.language.groovy;
|
||||
* A statement in Groovy.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public interface GroovyStatement {
|
||||
public class GroovyStatement {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or 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.spring.initializr.generator.language.groovy;
|
||||
|
||||
/**
|
||||
* A String type in the Groovy language.
|
||||
*
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public final class GroovyString implements GroovyExpression {
|
||||
|
||||
/**
|
||||
* The class name of this type.
|
||||
*/
|
||||
public static final String CLASS_NAME = "java.lang.String";
|
||||
|
||||
private final String value;
|
||||
|
||||
private GroovyString(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "\"" + value + "\"";
|
||||
}
|
||||
|
||||
public static GroovyString stringValue(String value) {
|
||||
return new GroovyString(value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,10 +30,10 @@ public class GroovyTypeDeclaration extends TypeDeclaration {
|
||||
|
||||
private int modifiers;
|
||||
|
||||
private final List<GroovyMethodDeclaration> methodDeclarations = new ArrayList<>();
|
||||
|
||||
private final List<GroovyFieldDeclaration> fieldDeclarations = new ArrayList<>();
|
||||
|
||||
private final List<GroovyMethodDeclaration> methodDeclarations = new ArrayList<>();
|
||||
|
||||
GroovyTypeDeclaration(String name) {
|
||||
super(name);
|
||||
}
|
||||
@@ -46,14 +46,6 @@ public class GroovyTypeDeclaration extends TypeDeclaration {
|
||||
return this.modifiers;
|
||||
}
|
||||
|
||||
public void addMethodDeclaration(GroovyMethodDeclaration methodDeclaration) {
|
||||
this.methodDeclarations.add(methodDeclaration);
|
||||
}
|
||||
|
||||
public List<GroovyMethodDeclaration> getMethodDeclarations() {
|
||||
return this.methodDeclarations;
|
||||
}
|
||||
|
||||
public void addFieldDeclaration(GroovyFieldDeclaration fieldDeclaration) {
|
||||
this.fieldDeclarations.add(fieldDeclaration);
|
||||
}
|
||||
@@ -62,4 +54,12 @@ public class GroovyTypeDeclaration extends TypeDeclaration {
|
||||
return this.fieldDeclarations;
|
||||
}
|
||||
|
||||
public void addMethodDeclaration(GroovyMethodDeclaration methodDeclaration) {
|
||||
this.methodDeclarations.add(methodDeclaration);
|
||||
}
|
||||
|
||||
public List<GroovyMethodDeclaration> getMethodDeclarations() {
|
||||
return this.methodDeclarations;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,8 +20,7 @@ package io.spring.initializr.generator.language.java;
|
||||
* A Java expression.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public interface JavaExpression {
|
||||
public class JavaExpression {
|
||||
|
||||
}
|
||||
|
||||
@@ -20,9 +20,8 @@ package io.spring.initializr.generator.language.java;
|
||||
* A statement that contains a single expression.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public class JavaExpressionStatement implements JavaStatement {
|
||||
public class JavaExpressionStatement extends JavaStatement {
|
||||
|
||||
private final JavaExpression expression;
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package io.spring.initializr.generator.language.java;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -25,7 +24,7 @@ import io.spring.initializr.generator.language.Annotatable;
|
||||
import io.spring.initializr.generator.language.Annotation;
|
||||
|
||||
/**
|
||||
* Declaration, and potential initialization, of a field in Java.
|
||||
* Declaration of a field written in Java.
|
||||
*
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
@@ -41,33 +40,20 @@ public final class JavaFieldDeclaration implements Annotatable {
|
||||
|
||||
private final Object value;
|
||||
|
||||
private JavaFieldDeclaration(int modifiers, String name, String returnType, Object value) {
|
||||
this.modifiers = modifiers;
|
||||
this.name = name;
|
||||
this.returnType = returnType;
|
||||
this.value = value;
|
||||
private final boolean initialized;
|
||||
|
||||
private JavaFieldDeclaration(Builder builder) {
|
||||
this.modifiers = builder.modifiers;
|
||||
this.name = builder.name;
|
||||
this.returnType = builder.returnType;
|
||||
this.value = builder.value;
|
||||
this.initialized = builder.initialized;
|
||||
}
|
||||
|
||||
public static Builder field(String name) {
|
||||
return new Builder(name);
|
||||
}
|
||||
|
||||
String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
String getReturnType() {
|
||||
return this.returnType;
|
||||
}
|
||||
|
||||
int getModifiers() {
|
||||
return this.modifiers;
|
||||
}
|
||||
|
||||
Object getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void annotate(Annotation annotation) {
|
||||
this.annotations.add(annotation);
|
||||
@@ -78,6 +64,26 @@ public final class JavaFieldDeclaration implements Annotatable {
|
||||
return Collections.unmodifiableList(this.annotations);
|
||||
}
|
||||
|
||||
public int getModifiers() {
|
||||
return this.modifiers;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getReturnType() {
|
||||
return this.returnType;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
return this.initialized;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for creating a {@link JavaFieldDeclaration}.
|
||||
*/
|
||||
@@ -85,43 +91,34 @@ public final class JavaFieldDeclaration implements Annotatable {
|
||||
|
||||
private final String name;
|
||||
|
||||
private int modifiers = Modifier.PUBLIC;
|
||||
private String returnType;
|
||||
|
||||
private Object value = InitializedStatus.NOT_INITIALIZED;
|
||||
private int modifiers;
|
||||
|
||||
private Object value;
|
||||
|
||||
private boolean initialized;
|
||||
|
||||
private Builder(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Builder packagePrivate() {
|
||||
this.modifiers = 0;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder modifiers(int modifiers) {
|
||||
this.modifiers = modifiers;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder value(JavaExpression value) {
|
||||
public Builder value(Object value) {
|
||||
this.value = value;
|
||||
this.initialized = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JavaFieldDeclaration returning(String returnType) {
|
||||
return new JavaFieldDeclaration(this.modifiers, this.name, returnType, this.value);
|
||||
this.returnType = returnType;
|
||||
return new JavaFieldDeclaration(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Track if the value has been set or not. Using this because initializing a field to
|
||||
* null should be possible.
|
||||
*/
|
||||
enum InitializedStatus {
|
||||
|
||||
NOT_INITIALIZED;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.util.List;
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class JavaMethodInvocation implements JavaExpression, JavaStatement {
|
||||
public class JavaMethodInvocation extends JavaExpression {
|
||||
|
||||
private final String target;
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or 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.spring.initializr.generator.language.java;
|
||||
|
||||
/**
|
||||
* A primitive for the Java language.
|
||||
*
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public interface JavaPrimitive extends JavaExpression {
|
||||
|
||||
}
|
||||
@@ -1,271 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or 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.spring.initializr.generator.language.java;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Primitives for the java language.
|
||||
*
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public final class JavaPrimitives {
|
||||
|
||||
private JavaPrimitives() {
|
||||
// hide public constructor
|
||||
}
|
||||
|
||||
public static JavaPrimitive byteValue(Byte value) {
|
||||
return new JavaByte(value);
|
||||
}
|
||||
|
||||
public static JavaPrimitive shortValue(Short value) {
|
||||
return new JavaShort(value);
|
||||
}
|
||||
|
||||
public static JavaPrimitive integerValue(Integer value) {
|
||||
return new JavaInteger(value);
|
||||
}
|
||||
|
||||
public static JavaPrimitive longValue(Long value) {
|
||||
return new JavaLong(value);
|
||||
}
|
||||
|
||||
public static JavaPrimitive doubleValue(Double value) {
|
||||
return new JavaDouble(value);
|
||||
}
|
||||
|
||||
public static JavaPrimitive floatValue(Float value) {
|
||||
return new JavaFloat(value);
|
||||
}
|
||||
|
||||
public static JavaPrimitive charValue(String charValue) {
|
||||
return new JavaChar(charValue);
|
||||
}
|
||||
|
||||
public static JavaPrimitive booleanValue(Boolean value) {
|
||||
return new JavaBoolean(value);
|
||||
}
|
||||
|
||||
private static String valueOrNull(Object value, Supplier<String> nonNullSupplier) {
|
||||
if (value == null) {
|
||||
return "null";
|
||||
}
|
||||
return nonNullSupplier.get();
|
||||
}
|
||||
|
||||
public static final class JavaByte implements JavaPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "java.lang.Byte";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "byte";
|
||||
|
||||
protected final Byte value;
|
||||
|
||||
private JavaByte(Byte value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> Byte.toString(this.value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class JavaShort implements JavaPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "java.lang.Short";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "short";
|
||||
|
||||
protected final Short value;
|
||||
|
||||
private JavaShort(Short value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> Short.toString(this.value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class JavaInteger implements JavaPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "java.lang.Integer";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "int";
|
||||
|
||||
protected final Integer value;
|
||||
|
||||
private JavaInteger(Integer value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> Integer.toString(this.value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class JavaLong implements JavaPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "java.lang.Long";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "long";
|
||||
|
||||
protected final Long value;
|
||||
|
||||
private JavaLong(Long value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> this.value + "L");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class JavaDouble implements JavaPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "java.lang.Double";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "double";
|
||||
|
||||
protected final Double value;
|
||||
|
||||
private JavaDouble(Double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> Double.toString(this.value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class JavaFloat implements JavaPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "java.lang.Float";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "float";
|
||||
|
||||
protected final Float value;
|
||||
|
||||
private JavaFloat(Float value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> this.value + "f");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class JavaChar implements JavaPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "java.lang.Character";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "char";
|
||||
|
||||
protected final String value;
|
||||
|
||||
private JavaChar(String charString) {
|
||||
this.value = charString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> this.value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class JavaBoolean implements JavaPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "java.lang.Boolean";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "boolean";
|
||||
|
||||
protected final Boolean value;
|
||||
|
||||
private JavaBoolean(Boolean value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> Boolean.toString(this.value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -20,12 +20,17 @@ package io.spring.initializr.generator.language.java;
|
||||
* A return statement.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public class JavaReturnStatement extends JavaExpressionStatement {
|
||||
public class JavaReturnStatement extends JavaStatement {
|
||||
|
||||
private final JavaExpression expression;
|
||||
|
||||
public JavaReturnStatement(JavaExpression expression) {
|
||||
super(expression);
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public JavaExpression getExpression() {
|
||||
return this.expression;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
@@ -53,10 +52,10 @@ public class JavaSourceCodeWriter implements SourceCodeWriter<JavaSourceCode> {
|
||||
|
||||
private static final Map<Predicate<Integer>, String> TYPE_MODIFIERS;
|
||||
|
||||
private static final Map<Predicate<Integer>, String> METHOD_MODIFIERS;
|
||||
|
||||
private static final Map<Predicate<Integer>, String> FIELD_MODIFIERS;
|
||||
|
||||
private static final Map<Predicate<Integer>, String> METHOD_MODIFIERS;
|
||||
|
||||
static {
|
||||
Map<Predicate<Integer>, String> typeModifiers = new LinkedHashMap<>();
|
||||
typeModifiers.put(Modifier::isPublic, "public");
|
||||
@@ -67,11 +66,6 @@ public class JavaSourceCodeWriter implements SourceCodeWriter<JavaSourceCode> {
|
||||
typeModifiers.put(Modifier::isFinal, "final");
|
||||
typeModifiers.put(Modifier::isStrict, "strictfp");
|
||||
TYPE_MODIFIERS = typeModifiers;
|
||||
Map<Predicate<Integer>, String> methodModifiers = new LinkedHashMap<>(typeModifiers);
|
||||
methodModifiers.put(Modifier::isSynchronized, "synchronized");
|
||||
methodModifiers.put(Modifier::isNative, "native");
|
||||
METHOD_MODIFIERS = methodModifiers;
|
||||
|
||||
Map<Predicate<Integer>, String> fieldModifiers = new LinkedHashMap<>();
|
||||
fieldModifiers.put(Modifier::isPublic, "public");
|
||||
fieldModifiers.put(Modifier::isProtected, "protected");
|
||||
@@ -81,6 +75,10 @@ public class JavaSourceCodeWriter implements SourceCodeWriter<JavaSourceCode> {
|
||||
fieldModifiers.put(Modifier::isTransient, "transient");
|
||||
fieldModifiers.put(Modifier::isVolatile, "volatile");
|
||||
FIELD_MODIFIERS = fieldModifiers;
|
||||
Map<Predicate<Integer>, String> methodModifiers = new LinkedHashMap<>(typeModifiers);
|
||||
methodModifiers.put(Modifier::isSynchronized, "synchronized");
|
||||
methodModifiers.put(Modifier::isNative, "native");
|
||||
METHOD_MODIFIERS = methodModifiers;
|
||||
}
|
||||
|
||||
private final IndentingWriterFactory indentingWriterFactory;
|
||||
@@ -91,7 +89,7 @@ public class JavaSourceCodeWriter implements SourceCodeWriter<JavaSourceCode> {
|
||||
|
||||
@Override
|
||||
public void writeTo(Path directory, JavaSourceCode sourceCode) throws IOException {
|
||||
if (!directory.toFile().exists()) {
|
||||
if (!Files.exists(directory)) {
|
||||
Files.createDirectories(directory);
|
||||
}
|
||||
for (JavaCompilationUnit compilationUnit : sourceCode.getCompilationUnits()) {
|
||||
@@ -143,37 +141,63 @@ public class JavaSourceCodeWriter implements SourceCodeWriter<JavaSourceCode> {
|
||||
}
|
||||
}
|
||||
|
||||
private void writeFieldDeclaration(IndentingWriter writer, JavaFieldDeclaration fieldDeclaration) {
|
||||
writeAnnotations(writer, fieldDeclaration);
|
||||
writeFieldModifiers(writer, fieldDeclaration);
|
||||
writer.print(getUnqualifiedName(fieldDeclaration.getReturnType()));
|
||||
writer.print(" ");
|
||||
writer.print(fieldDeclaration.getName());
|
||||
if (!Objects.equals(JavaFieldDeclaration.InitializedStatus.NOT_INITIALIZED, fieldDeclaration.getValue())) {
|
||||
writer.print(" = ");
|
||||
writeFieldValue(writer, fieldDeclaration.getValue(), fieldDeclaration.getReturnType());
|
||||
private void writeAnnotations(IndentingWriter writer, Annotatable annotatable) {
|
||||
annotatable.getAnnotations().forEach((annotation) -> writeAnnotation(writer, annotation));
|
||||
}
|
||||
|
||||
private void writeAnnotation(IndentingWriter writer, Annotation annotation) {
|
||||
writer.print("@" + getUnqualifiedName(annotation.getName()));
|
||||
List<Annotation.Attribute> attributes = annotation.getAttributes();
|
||||
if (!attributes.isEmpty()) {
|
||||
writer.print("(");
|
||||
if (attributes.size() == 1 && attributes.get(0).getName().equals("value")) {
|
||||
writer.print(formatAnnotationAttribute(attributes.get(0)));
|
||||
}
|
||||
else {
|
||||
writer.print(attributes.stream()
|
||||
.map((attribute) -> attribute.getName() + " = " + formatAnnotationAttribute(attribute))
|
||||
.collect(Collectors.joining(", ")));
|
||||
}
|
||||
writer.print(")");
|
||||
}
|
||||
writer.println(";");
|
||||
writer.println();
|
||||
}
|
||||
|
||||
private void writeFieldValue(IndentingWriter writer, Object value, String returnType) {
|
||||
quote(writer, value, returnType);
|
||||
writer.print(String.valueOf(value));
|
||||
quote(writer, value, returnType);
|
||||
private String formatAnnotationAttribute(Annotation.Attribute attribute) {
|
||||
List<String> values = attribute.getValues();
|
||||
if (attribute.getType().equals(Class.class)) {
|
||||
return formatValues(values, (value) -> String.format("%s.class", getUnqualifiedName(value)));
|
||||
}
|
||||
if (Enum.class.isAssignableFrom(attribute.getType())) {
|
||||
return formatValues(values, (value) -> {
|
||||
String enumValue = value.substring(value.lastIndexOf(".") + 1);
|
||||
String enumClass = value.substring(0, value.lastIndexOf("."));
|
||||
return String.format("%s.%s", getUnqualifiedName(enumClass), enumValue);
|
||||
});
|
||||
}
|
||||
if (attribute.getType().equals(String.class)) {
|
||||
return formatValues(values, (value) -> String.format("\"%s\"", value));
|
||||
}
|
||||
return formatValues(values, (value) -> String.format("%s", value));
|
||||
}
|
||||
|
||||
private void quote(IndentingWriter writer, Object value, String returnType) {
|
||||
if (value instanceof Character || "char".equals(returnType) || "java.lang.Character".equals(returnType)) {
|
||||
writer.print("\'");
|
||||
}
|
||||
else if (value instanceof CharSequence) {
|
||||
writer.print("\"");
|
||||
}
|
||||
private String formatValues(List<String> values, Function<String, String> formatter) {
|
||||
String result = values.stream().map(formatter).collect(Collectors.joining(", "));
|
||||
return (values.size() > 1) ? "{ " + result + " }" : result;
|
||||
}
|
||||
|
||||
private void writeFieldModifiers(IndentingWriter writer, JavaFieldDeclaration fieldDeclaration) {
|
||||
private void writeFieldDeclaration(IndentingWriter writer, JavaFieldDeclaration fieldDeclaration) {
|
||||
writeAnnotations(writer, fieldDeclaration);
|
||||
writeModifiers(writer, FIELD_MODIFIERS, fieldDeclaration.getModifiers());
|
||||
writer.print(getUnqualifiedName(fieldDeclaration.getReturnType()));
|
||||
writer.print(" ");
|
||||
writer.print(fieldDeclaration.getName());
|
||||
if (fieldDeclaration.isInitialized()) {
|
||||
writer.print(" = ");
|
||||
writer.print(String.valueOf(fieldDeclaration.getValue()));
|
||||
}
|
||||
writer.println(";");
|
||||
writer.println();
|
||||
}
|
||||
|
||||
private void writeMethodDeclaration(IndentingWriter writer, JavaMethodDeclaration methodDeclaration) {
|
||||
@@ -190,13 +214,13 @@ public class JavaSourceCodeWriter implements SourceCodeWriter<JavaSourceCode> {
|
||||
writer.indented(() -> {
|
||||
List<JavaStatement> statements = methodDeclaration.getStatements();
|
||||
for (JavaStatement statement : statements) {
|
||||
if (statement instanceof JavaReturnStatement) {
|
||||
if (statement instanceof JavaExpressionStatement) {
|
||||
writeExpression(writer, ((JavaExpressionStatement) statement).getExpression());
|
||||
}
|
||||
else if (statement instanceof JavaReturnStatement) {
|
||||
writer.print("return ");
|
||||
writeExpression(writer, ((JavaReturnStatement) statement).getExpression());
|
||||
}
|
||||
else if (statement instanceof JavaExpressionStatement) {
|
||||
writeExpression(writer, ((JavaExpressionStatement) statement).getExpression());
|
||||
}
|
||||
writer.println(";");
|
||||
}
|
||||
});
|
||||
@@ -204,10 +228,6 @@ public class JavaSourceCodeWriter implements SourceCodeWriter<JavaSourceCode> {
|
||||
writer.println();
|
||||
}
|
||||
|
||||
private void writeMethodModifiers(IndentingWriter writer, JavaMethodDeclaration methodDeclaration) {
|
||||
writeModifiers(writer, METHOD_MODIFIERS, methodDeclaration.getModifiers());
|
||||
}
|
||||
|
||||
private void writeModifiers(IndentingWriter writer, Map<Predicate<Integer>, String> availableModifiers,
|
||||
int declaredModifiers) {
|
||||
String modifiers = availableModifiers.entrySet().stream()
|
||||
@@ -294,6 +314,13 @@ public class JavaSourceCodeWriter implements SourceCodeWriter<JavaSourceCode> {
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private String getUnqualifiedName(String name) {
|
||||
if (!name.contains(".")) {
|
||||
return name;
|
||||
}
|
||||
return name.substring(name.lastIndexOf(".") + 1);
|
||||
}
|
||||
|
||||
private boolean requiresImport(String name) {
|
||||
if (name == null || !name.contains(".")) {
|
||||
return false;
|
||||
@@ -302,79 +329,4 @@ public class JavaSourceCodeWriter implements SourceCodeWriter<JavaSourceCode> {
|
||||
return !"java.lang".equals(packageName);
|
||||
}
|
||||
|
||||
private void writeAnnotations(IndentingWriter writer, Annotatable annotatable) {
|
||||
writeAnnotations(writer, annotatable, true);
|
||||
}
|
||||
|
||||
private void writeAnnotations(IndentingWriter writer, Annotatable annotatable, boolean newLine) {
|
||||
for (Annotation annotation : annotatable.getAnnotations()) {
|
||||
writeAnnotation(writer, annotation, newLine);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeAnnotation(IndentingWriter writer, Annotation annotation, boolean newLine) {
|
||||
writer.print("@" + getUnqualifiedName(annotation.getName()));
|
||||
List<Annotation.Attribute> attributes = annotation.getAttributes();
|
||||
if (!attributes.isEmpty()) {
|
||||
writer.print("(");
|
||||
if (attributes.size() == 1 && attributes.get(0).getName().equals("value")) {
|
||||
writer.print(formatAnnotationAttribute(attributes.get(0)));
|
||||
}
|
||||
else {
|
||||
writer.print(attributes.stream()
|
||||
.map((attribute) -> attribute.getName() + " = " + formatAnnotationAttribute(attribute))
|
||||
.collect(Collectors.joining(", ")));
|
||||
}
|
||||
writer.print(")");
|
||||
}
|
||||
if (newLine) {
|
||||
writer.println();
|
||||
}
|
||||
else {
|
||||
writer.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
private void writeAnnotation(IndentingWriter writer, Annotation annotation) {
|
||||
writeAnnotation(writer, annotation, true);
|
||||
}
|
||||
|
||||
private String formatAnnotationAttribute(Annotation.Attribute attribute) {
|
||||
List<String> values = attribute.getValues();
|
||||
if (attribute.getType().equals(Class.class)) {
|
||||
return formatValues(values, (value) -> String.format(annotationFormatString(), getUnqualifiedName(value)));
|
||||
}
|
||||
if (Enum.class.isAssignableFrom(attribute.getType())) {
|
||||
return formatValues(values, (value) -> {
|
||||
String enumValue = value.substring(value.lastIndexOf(".") + 1);
|
||||
String enumClass = value.substring(0, value.lastIndexOf("."));
|
||||
return String.format("%s.%s", getUnqualifiedName(enumClass), enumValue);
|
||||
});
|
||||
}
|
||||
if (attribute.getType().equals(String.class)) {
|
||||
return formatValues(values, (value) -> String.format("\"%s\"", value));
|
||||
}
|
||||
return formatValues(values, (value) -> String.format("%s", value));
|
||||
}
|
||||
|
||||
private String formatValues(List<String> values, Function<String, String> formatter) {
|
||||
String result = values.stream().map(formatter).collect(Collectors.joining(", "));
|
||||
return (values.size() > 1) ? formatAnnotationArray(result) : result;
|
||||
}
|
||||
|
||||
private String formatAnnotationArray(String values) {
|
||||
return "{ " + values + " }";
|
||||
}
|
||||
|
||||
private String getUnqualifiedName(String name) {
|
||||
if (!name.contains(".")) {
|
||||
return name;
|
||||
}
|
||||
return name.substring(name.lastIndexOf(".") + 1);
|
||||
}
|
||||
|
||||
private String annotationFormatString() {
|
||||
return "%s.class";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,8 +20,7 @@ package io.spring.initializr.generator.language.java;
|
||||
* A statement in Java.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public interface JavaStatement {
|
||||
public class JavaStatement {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or 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.spring.initializr.generator.language.java;
|
||||
|
||||
/**
|
||||
* A String type in the Java language.
|
||||
*
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public final class JavaString implements JavaExpression {
|
||||
|
||||
/**
|
||||
* The class name of this type.
|
||||
*/
|
||||
public static final String CLASS_NAME = "java.lang.String";
|
||||
|
||||
private final String value;
|
||||
|
||||
private JavaString(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "\"" + this.value + "\"";
|
||||
}
|
||||
|
||||
public static JavaString stringValue(String value) {
|
||||
return new JavaString(value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,10 +31,10 @@ public class JavaTypeDeclaration extends TypeDeclaration {
|
||||
|
||||
private int modifiers;
|
||||
|
||||
private final List<JavaMethodDeclaration> methodDeclarations = new ArrayList<>();
|
||||
|
||||
private final List<JavaFieldDeclaration> fieldDeclarations = new ArrayList<>();
|
||||
|
||||
private final List<JavaMethodDeclaration> methodDeclarations = new ArrayList<>();
|
||||
|
||||
JavaTypeDeclaration(String name) {
|
||||
super(name);
|
||||
}
|
||||
@@ -47,14 +47,6 @@ public class JavaTypeDeclaration extends TypeDeclaration {
|
||||
return this.modifiers;
|
||||
}
|
||||
|
||||
public void addMethodDeclaration(JavaMethodDeclaration methodDeclaration) {
|
||||
this.methodDeclarations.add(methodDeclaration);
|
||||
}
|
||||
|
||||
public List<JavaMethodDeclaration> getMethodDeclarations() {
|
||||
return this.methodDeclarations;
|
||||
}
|
||||
|
||||
public void addFieldDeclaration(JavaFieldDeclaration fieldDeclaration) {
|
||||
this.fieldDeclarations.add(fieldDeclaration);
|
||||
}
|
||||
@@ -63,4 +55,12 @@ public class JavaTypeDeclaration extends TypeDeclaration {
|
||||
return this.fieldDeclarations;
|
||||
}
|
||||
|
||||
public void addMethodDeclaration(JavaMethodDeclaration methodDeclaration) {
|
||||
this.methodDeclarations.add(methodDeclaration);
|
||||
}
|
||||
|
||||
public List<JavaMethodDeclaration> getMethodDeclarations() {
|
||||
return this.methodDeclarations;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,6 @@ package io.spring.initializr.generator.language.kotlin;
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public interface KotlinExpression {
|
||||
public class KotlinExpression {
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ package io.spring.initializr.generator.language.kotlin;
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class KotlinExpressionStatement implements KotlinStatement {
|
||||
public class KotlinExpressionStatement extends KotlinStatement {
|
||||
|
||||
private final KotlinExpression expression;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package io.spring.initializr.generator.language.kotlin;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -23,15 +24,22 @@ import java.util.List;
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class KotlinFunctionInvocation implements KotlinExpression {
|
||||
public class KotlinFunctionInvocation extends KotlinExpression {
|
||||
|
||||
private final String target;
|
||||
|
||||
private final String name;
|
||||
|
||||
private final List<String> arguments;
|
||||
|
||||
public KotlinFunctionInvocation(String name, List<String> arguments) {
|
||||
public KotlinFunctionInvocation(String target, String name, String... arguments) {
|
||||
this.target = target;
|
||||
this.name = name;
|
||||
this.arguments = arguments;
|
||||
this.arguments = Arrays.asList(arguments);
|
||||
}
|
||||
|
||||
public String getTarget() {
|
||||
return this.target;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or 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.spring.initializr.generator.language.kotlin;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* A method invocation in Kotlin.
|
||||
*
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public class KotlinMethodInvocation implements KotlinExpression {
|
||||
|
||||
private final String target;
|
||||
|
||||
private final String name;
|
||||
|
||||
private final List<String> arguments;
|
||||
|
||||
public KotlinMethodInvocation(String target, String name, String... arguments) {
|
||||
this.target = target;
|
||||
this.name = name;
|
||||
this.arguments = Arrays.asList(arguments);
|
||||
}
|
||||
|
||||
public String getTarget() {
|
||||
return this.target;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public List<String> getArguments() {
|
||||
return this.arguments;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -56,6 +56,11 @@ public enum KotlinModifier {
|
||||
/**
|
||||
* Override a member.
|
||||
*/
|
||||
OVERRIDE
|
||||
OVERRIDE,
|
||||
|
||||
/**
|
||||
* Declare a late-initialized property.
|
||||
*/
|
||||
LATEINIT
|
||||
|
||||
}
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or 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.spring.initializr.generator.language.kotlin;
|
||||
|
||||
/**
|
||||
* A primitive for the Kotlin language.
|
||||
*
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public interface KotlinPrimitive extends KotlinExpression {
|
||||
|
||||
}
|
||||
@@ -1,271 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or 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.spring.initializr.generator.language.kotlin;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Kotlin primitives.
|
||||
*
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public final class KotlinPrimitives {
|
||||
|
||||
private KotlinPrimitives() {
|
||||
// hide public constructor
|
||||
}
|
||||
|
||||
public static KotlinPrimitive byteValue(Byte value) {
|
||||
return new KotlinByte(value);
|
||||
}
|
||||
|
||||
public static KotlinPrimitive shortValue(Short value) {
|
||||
return new KotlinShort(value);
|
||||
}
|
||||
|
||||
public static KotlinPrimitive integerValue(Integer value) {
|
||||
return new KotlinInt(value);
|
||||
}
|
||||
|
||||
public static KotlinPrimitive doubleValue(Double value) {
|
||||
return new KotlinDouble(value);
|
||||
}
|
||||
|
||||
public static KotlinPrimitive longValue(Long value) {
|
||||
return new KotlinLong(value);
|
||||
}
|
||||
|
||||
public static KotlinPrimitive floatValue(Float value) {
|
||||
return new KotlinFloat(value);
|
||||
}
|
||||
|
||||
public static KotlinPrimitive charValue(String charString) {
|
||||
return new KotlinChar(charString);
|
||||
}
|
||||
|
||||
public static KotlinPrimitive booleanValue(Boolean value) {
|
||||
return new KotlinBoolean(value);
|
||||
}
|
||||
|
||||
private static String valueOrNull(Object value, Supplier<String> nonNullSupplier) {
|
||||
if (value == null) {
|
||||
return "null";
|
||||
}
|
||||
return nonNullSupplier.get();
|
||||
}
|
||||
|
||||
public static final class KotlinByte implements KotlinPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_TYPE_CLASS = "kotlin.Byte";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "kotlin.Byte";
|
||||
|
||||
protected final Byte value;
|
||||
|
||||
private KotlinByte(Byte value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> Byte.toString(this.value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class KotlinShort implements KotlinPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "kotlin.Short";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "kotlin.Short";
|
||||
|
||||
protected final Short value;
|
||||
|
||||
private KotlinShort(Short value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> Short.toString(this.value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class KotlinInt implements KotlinPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "kotlin.Int";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "kotlin.Int";
|
||||
|
||||
protected final Integer value;
|
||||
|
||||
private KotlinInt(Integer value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> Integer.toString(this.value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class KotlinDouble implements KotlinPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "kotlin.Double";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "kotlin.Double";
|
||||
|
||||
protected final Double value;
|
||||
|
||||
private KotlinDouble(Double value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> Double.toString(this.value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class KotlinLong implements KotlinPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "kotlin.Long";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "kotlin.Long";
|
||||
|
||||
protected final Long value;
|
||||
|
||||
private KotlinLong(Long value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> this.value + "L");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class KotlinFloat implements KotlinPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "kotlin.Float";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "kotlin.Float";
|
||||
|
||||
protected final Float value;
|
||||
|
||||
private KotlinFloat(Float value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> this.value + "f");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class KotlinBoolean implements KotlinPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "kotlin.Boolean";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "kotlin.Boolean";
|
||||
|
||||
protected final Boolean value;
|
||||
|
||||
private KotlinBoolean(Boolean value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> Boolean.toString(this.value));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static final class KotlinChar implements KotlinPrimitive {
|
||||
|
||||
/**
|
||||
* The class name of the boxed type.
|
||||
*/
|
||||
public static final String BOXED_CLASS_NAME = "kotlin.Char";
|
||||
|
||||
/**
|
||||
* The name of the unboxed type.
|
||||
*/
|
||||
public static final String TYPE = "kotlin.Char";
|
||||
|
||||
protected final String value;
|
||||
|
||||
private KotlinChar(String charString) {
|
||||
this.value = charString;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return valueOrNull(this.value, () -> this.value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
package io.spring.initializr.generator.language.kotlin;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
@@ -25,7 +26,7 @@ import io.spring.initializr.generator.language.Annotatable;
|
||||
import io.spring.initializr.generator.language.Annotation;
|
||||
|
||||
/**
|
||||
* Declaration of a property in Kotlin.
|
||||
* Declaration of a property written in Kotlin.
|
||||
*
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
@@ -39,15 +40,18 @@ public final class KotlinPropertyDeclaration implements Annotatable {
|
||||
|
||||
private final String returnType;
|
||||
|
||||
private final List<KotlinModifier> modifiers;
|
||||
|
||||
private final KotlinExpressionStatement valueExpression;
|
||||
|
||||
private final Accessor getter;
|
||||
|
||||
private final Accessor setter;
|
||||
|
||||
private KotlinPropertyDeclaration(Builder builder) {
|
||||
private KotlinPropertyDeclaration(Builder<?> builder) {
|
||||
this.name = builder.name;
|
||||
this.returnType = builder.returnType;
|
||||
this.modifiers = new ArrayList<>(builder.modifiers);
|
||||
this.isVal = builder.isVal;
|
||||
this.valueExpression = builder.initializerStatement;
|
||||
this.getter = builder.getter;
|
||||
@@ -74,6 +78,10 @@ public final class KotlinPropertyDeclaration implements Annotatable {
|
||||
return this.returnType;
|
||||
}
|
||||
|
||||
public List<KotlinModifier> getModifiers() {
|
||||
return this.modifiers;
|
||||
}
|
||||
|
||||
KotlinExpressionStatement getValueExpression() {
|
||||
return this.valueExpression;
|
||||
}
|
||||
@@ -86,14 +94,6 @@ public final class KotlinPropertyDeclaration implements Annotatable {
|
||||
return this.setter;
|
||||
}
|
||||
|
||||
public boolean hasGetter() {
|
||||
return getGetter() != null;
|
||||
}
|
||||
|
||||
public boolean hasSetter() {
|
||||
return getSetter() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void annotate(Annotation annotation) {
|
||||
this.annotations.add(annotation);
|
||||
@@ -117,6 +117,8 @@ public final class KotlinPropertyDeclaration implements Annotatable {
|
||||
|
||||
private String returnType;
|
||||
|
||||
private List<KotlinModifier> modifiers = new ArrayList<>();
|
||||
|
||||
private KotlinExpressionStatement initializerStatement;
|
||||
|
||||
private Accessor getter;
|
||||
@@ -145,12 +147,17 @@ public final class KotlinPropertyDeclaration implements Annotatable {
|
||||
return self();
|
||||
}
|
||||
|
||||
public T modifiers(KotlinModifier... modifiers) {
|
||||
this.modifiers = Arrays.asList(modifiers);
|
||||
return self();
|
||||
}
|
||||
|
||||
public KotlinPropertyDeclaration emptyValue() {
|
||||
return new KotlinPropertyDeclaration(this);
|
||||
}
|
||||
|
||||
public KotlinPropertyDeclaration value(KotlinExpression expression) {
|
||||
this.initializerStatement = new KotlinExpressionStatement(expression);
|
||||
public KotlinPropertyDeclaration value(Object value) {
|
||||
this.initializerStatement = new KotlinExpressionStatement(new SimpleValueExpression(value));
|
||||
return new KotlinPropertyDeclaration(this);
|
||||
}
|
||||
|
||||
@@ -192,8 +199,6 @@ public final class KotlinPropertyDeclaration implements Annotatable {
|
||||
|
||||
private KotlinExpressionStatement body;
|
||||
|
||||
private boolean isPrivate = false;
|
||||
|
||||
private final T parent;
|
||||
|
||||
private final Consumer<Accessor> accessorFunction;
|
||||
@@ -203,17 +208,12 @@ public final class KotlinPropertyDeclaration implements Annotatable {
|
||||
this.accessorFunction = accessorFunction;
|
||||
}
|
||||
|
||||
public AccessorBuilder isPrivate() {
|
||||
this.isPrivate = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
public AccessorBuilder withAnnotation(Annotation annotation) {
|
||||
public AccessorBuilder<?> withAnnotation(Annotation annotation) {
|
||||
this.annotations.add(annotation);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AccessorBuilder withBody(KotlinExpressionStatement expressionStatement) {
|
||||
public AccessorBuilder<?> withBody(KotlinExpressionStatement expressionStatement) {
|
||||
this.body = expressionStatement;
|
||||
return this;
|
||||
}
|
||||
@@ -231,17 +231,9 @@ public final class KotlinPropertyDeclaration implements Annotatable {
|
||||
|
||||
private final KotlinExpressionStatement body;
|
||||
|
||||
private final boolean isPrivate;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Accessor(AccessorBuilder builder) {
|
||||
Accessor(AccessorBuilder<?> builder) {
|
||||
this.annotations.addAll(builder.annotations);
|
||||
this.body = builder.body;
|
||||
this.isPrivate = builder.isPrivate;
|
||||
}
|
||||
|
||||
boolean isPrivate() {
|
||||
return this.isPrivate;
|
||||
}
|
||||
|
||||
boolean isEmptyBody() {
|
||||
@@ -264,4 +256,19 @@ public final class KotlinPropertyDeclaration implements Annotatable {
|
||||
|
||||
}
|
||||
|
||||
private static class SimpleValueExpression extends KotlinExpression {
|
||||
|
||||
private final Object value;
|
||||
|
||||
SimpleValueExpression(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.valueOf(this.value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or 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.spring.initializr.generator.language.kotlin;
|
||||
|
||||
/**
|
||||
* Modifiers that can modify a Kotlin property.
|
||||
*
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public enum KotlinPropertyModifier {
|
||||
|
||||
/**
|
||||
* Represents a private property.
|
||||
*/
|
||||
PRIVATE,
|
||||
|
||||
/**
|
||||
* Represents a lateinit property.
|
||||
*/
|
||||
LATE_INIT
|
||||
|
||||
}
|
||||
@@ -17,23 +17,37 @@
|
||||
package io.spring.initializr.generator.language.kotlin;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Invocation of a function with a reified type parameter.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class KotlinReifiedFunctionInvocation extends KotlinFunctionInvocation implements KotlinExpression {
|
||||
public class KotlinReifiedFunctionInvocation extends KotlinExpression {
|
||||
|
||||
private final String name;
|
||||
|
||||
private final String targetClass;
|
||||
|
||||
private final List<String> arguments;
|
||||
|
||||
public KotlinReifiedFunctionInvocation(String name, String targetClass, String... arguments) {
|
||||
super(name, Arrays.asList(arguments));
|
||||
this.name = name;
|
||||
this.targetClass = targetClass;
|
||||
this.arguments = Arrays.asList(arguments);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getTargetClass() {
|
||||
return this.targetClass;
|
||||
}
|
||||
|
||||
public List<String> getArguments() {
|
||||
return this.arguments;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,12 +20,17 @@ package io.spring.initializr.generator.language.kotlin;
|
||||
* A return statement.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public class KotlinReturnStatement extends KotlinExpressionStatement {
|
||||
public class KotlinReturnStatement extends KotlinStatement {
|
||||
|
||||
private final KotlinExpression expression;
|
||||
|
||||
public KotlinReturnStatement(KotlinExpression expression) {
|
||||
super(expression);
|
||||
this.expression = expression;
|
||||
}
|
||||
|
||||
public KotlinExpression getExpression() {
|
||||
return this.expression;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public class KotlinSourceCodeWriter implements SourceCodeWriter<KotlinSourceCode
|
||||
|
||||
@Override
|
||||
public void writeTo(Path directory, KotlinSourceCode sourceCode) throws IOException {
|
||||
if (!directory.toFile().exists()) {
|
||||
if (!Files.exists(directory)) {
|
||||
Files.createDirectories(directory);
|
||||
}
|
||||
for (KotlinCompilationUnit compilationUnit : sourceCode.getCompilationUnits()) {
|
||||
@@ -123,6 +123,7 @@ public class KotlinSourceCodeWriter implements SourceCodeWriter<KotlinSourceCode
|
||||
|
||||
private void writeProperty(IndentingWriter writer, KotlinPropertyDeclaration propertyDeclaration) {
|
||||
writer.println();
|
||||
writeModifiers(writer, propertyDeclaration.getModifiers());
|
||||
if (propertyDeclaration.isVal()) {
|
||||
writer.print("val ");
|
||||
}
|
||||
@@ -137,11 +138,11 @@ public class KotlinSourceCodeWriter implements SourceCodeWriter<KotlinSourceCode
|
||||
writer.print(" = ");
|
||||
writeExpression(writer, propertyDeclaration.getValueExpression().getExpression());
|
||||
}
|
||||
if (propertyDeclaration.hasGetter()) {
|
||||
if (propertyDeclaration.getGetter() != null) {
|
||||
writer.println();
|
||||
writer.indented(() -> writeAccessor(writer, "get", propertyDeclaration.getGetter()));
|
||||
}
|
||||
if (propertyDeclaration.hasSetter()) {
|
||||
if (propertyDeclaration.getSetter() != null) {
|
||||
writer.println();
|
||||
writer.indented(() -> writeAccessor(writer, "set", propertyDeclaration.getSetter()));
|
||||
}
|
||||
@@ -155,9 +156,6 @@ public class KotlinSourceCodeWriter implements SourceCodeWriter<KotlinSourceCode
|
||||
writeAnnotation(writer, annotation, false);
|
||||
}
|
||||
}
|
||||
if (accessor.isPrivate()) {
|
||||
writer.print("private ");
|
||||
}
|
||||
writer.print(accessorName);
|
||||
if (!accessor.isEmptyBody()) {
|
||||
writer.print("() = ");
|
||||
@@ -185,19 +183,71 @@ public class KotlinSourceCodeWriter implements SourceCodeWriter<KotlinSourceCode
|
||||
List<KotlinStatement> statements = functionDeclaration.getStatements();
|
||||
writer.indented(() -> {
|
||||
for (KotlinStatement statement : statements) {
|
||||
if (statement instanceof KotlinReturnStatement) {
|
||||
if (statement instanceof KotlinExpressionStatement) {
|
||||
writeExpression(writer, ((KotlinExpressionStatement) statement).getExpression());
|
||||
}
|
||||
else if (statement instanceof KotlinReturnStatement) {
|
||||
writer.print("return ");
|
||||
writeExpression(writer, ((KotlinReturnStatement) statement).getExpression());
|
||||
}
|
||||
else if (statement instanceof KotlinExpressionStatement) {
|
||||
writeExpression(writer, ((KotlinExpressionStatement) statement).getExpression());
|
||||
}
|
||||
writer.println("");
|
||||
}
|
||||
});
|
||||
writer.println("}");
|
||||
}
|
||||
|
||||
private void writeAnnotations(IndentingWriter writer, Annotatable annotatable) {
|
||||
for (Annotation annotation : annotatable.getAnnotations()) {
|
||||
writeAnnotation(writer, annotation, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeAnnotation(IndentingWriter writer, Annotation annotation, boolean newLine) {
|
||||
writer.print("@" + getUnqualifiedName(annotation.getName()));
|
||||
List<Annotation.Attribute> attributes = annotation.getAttributes();
|
||||
if (!attributes.isEmpty()) {
|
||||
writer.print("(");
|
||||
if (attributes.size() == 1 && attributes.get(0).getName().equals("value")) {
|
||||
writer.print(formatAnnotationAttribute(attributes.get(0)));
|
||||
}
|
||||
else {
|
||||
writer.print(attributes.stream()
|
||||
.map((attribute) -> attribute.getName() + " = " + formatAnnotationAttribute(attribute))
|
||||
.collect(Collectors.joining(", ")));
|
||||
}
|
||||
writer.print(")");
|
||||
}
|
||||
if (newLine) {
|
||||
writer.println();
|
||||
}
|
||||
else {
|
||||
writer.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
private String formatAnnotationAttribute(Annotation.Attribute attribute) {
|
||||
List<String> values = attribute.getValues();
|
||||
if (attribute.getType().equals(Class.class)) {
|
||||
return formatValues(values, (value) -> String.format("%s::class", getUnqualifiedName(value)));
|
||||
}
|
||||
if (Enum.class.isAssignableFrom(attribute.getType())) {
|
||||
return formatValues(values, (value) -> {
|
||||
String enumValue = value.substring(value.lastIndexOf(".") + 1);
|
||||
String enumClass = value.substring(0, value.lastIndexOf("."));
|
||||
return String.format("%s.%s", getUnqualifiedName(enumClass), enumValue);
|
||||
});
|
||||
}
|
||||
if (attribute.getType().equals(String.class)) {
|
||||
return formatValues(values, (value) -> String.format("\"%s\"", value));
|
||||
}
|
||||
return formatValues(values, (value) -> String.format("%s", value));
|
||||
}
|
||||
|
||||
private String formatValues(List<String> values, Function<String, String> formatter) {
|
||||
String result = values.stream().map(formatter).collect(Collectors.joining(", "));
|
||||
return (values.size() > 1) ? "[" + result + "]" : result;
|
||||
}
|
||||
|
||||
private void writeModifiers(IndentingWriter writer, List<KotlinModifier> declaredModifiers) {
|
||||
String modifiers = declaredModifiers.stream().filter((entry) -> !entry.equals(KotlinModifier.PUBLIC)).sorted()
|
||||
.map((entry) -> entry.toString().toLowerCase(Locale.ENGLISH)).collect(Collectors.joining(" "));
|
||||
@@ -208,25 +258,18 @@ public class KotlinSourceCodeWriter implements SourceCodeWriter<KotlinSourceCode
|
||||
}
|
||||
|
||||
private void writeExpression(IndentingWriter writer, KotlinExpression expression) {
|
||||
if (expression instanceof KotlinMethodInvocation) {
|
||||
writeMethodInvocation(writer, (KotlinMethodInvocation) expression);
|
||||
if (expression instanceof KotlinFunctionInvocation) {
|
||||
writeFunctionInvocation(writer, (KotlinFunctionInvocation) expression);
|
||||
}
|
||||
else if (expression instanceof KotlinReifiedFunctionInvocation) {
|
||||
writeReifiedFunctionInvocation(writer, (KotlinReifiedFunctionInvocation) expression);
|
||||
}
|
||||
else if (expression instanceof KotlinFunctionInvocation) {
|
||||
writeFunctionInvocation(writer, (KotlinFunctionInvocation) expression);
|
||||
}
|
||||
else if (expression != null) {
|
||||
writer.print(expression.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void writeFunctionInvocation(IndentingWriter writer, KotlinFunctionInvocation functionInvocation) {
|
||||
writer.print(functionInvocation.getName() + "(" + String.join(", ", functionInvocation.getArguments()) + ")");
|
||||
}
|
||||
|
||||
private void writeMethodInvocation(IndentingWriter writer, KotlinMethodInvocation functionInvocation) {
|
||||
writer.print(getUnqualifiedName(functionInvocation.getTarget()) + "." + functionInvocation.getName() + "("
|
||||
+ String.join(", ", functionInvocation.getArguments()) + ")");
|
||||
}
|
||||
@@ -282,8 +325,8 @@ public class KotlinSourceCodeWriter implements SourceCodeWriter<KotlinSourceCode
|
||||
imports.addAll(getRequiredImports(functionDeclaration.getParameters(),
|
||||
(parameter) -> Collections.singleton(parameter.getType())));
|
||||
imports.addAll(getRequiredImports(
|
||||
getKotlinExpressions(functionDeclaration).filter(KotlinMethodInvocation.class::isInstance)
|
||||
.map(KotlinMethodInvocation.class::cast),
|
||||
getKotlinExpressions(functionDeclaration).filter(KotlinFunctionInvocation.class::isInstance)
|
||||
.map(KotlinFunctionInvocation.class::cast),
|
||||
(invocation) -> Collections.singleton(invocation.getTarget())));
|
||||
imports.addAll(getRequiredImports(
|
||||
getKotlinExpressions(functionDeclaration).filter(KotlinReifiedFunctionInvocation.class::isInstance)
|
||||
@@ -292,78 +335,6 @@ public class KotlinSourceCodeWriter implements SourceCodeWriter<KotlinSourceCode
|
||||
return imports;
|
||||
}
|
||||
|
||||
private Stream<KotlinExpression> getKotlinExpressions(KotlinFunctionDeclaration functionDeclaration) {
|
||||
return functionDeclaration.getStatements().stream().filter(KotlinExpressionStatement.class::isInstance)
|
||||
.map(KotlinExpressionStatement.class::cast).map(KotlinExpressionStatement::getExpression);
|
||||
}
|
||||
|
||||
private void writeAnnotations(IndentingWriter writer, Annotatable annotatable) {
|
||||
writeAnnotations(writer, annotatable, true);
|
||||
}
|
||||
|
||||
private void writeAnnotations(IndentingWriter writer, Annotatable annotatable, boolean newLine) {
|
||||
for (Annotation annotation : annotatable.getAnnotations()) {
|
||||
writeAnnotation(writer, annotation, newLine);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeAnnotation(IndentingWriter writer, Annotation annotation, boolean newLine) {
|
||||
writer.print("@" + getUnqualifiedName(annotation.getName()));
|
||||
List<Annotation.Attribute> attributes = annotation.getAttributes();
|
||||
if (!attributes.isEmpty()) {
|
||||
writer.print("(");
|
||||
if (attributes.size() == 1 && attributes.get(0).getName().equals("value")) {
|
||||
writer.print(formatAnnotationAttribute(attributes.get(0)));
|
||||
}
|
||||
else {
|
||||
writer.print(attributes.stream()
|
||||
.map((attribute) -> attribute.getName() + " = " + formatAnnotationAttribute(attribute))
|
||||
.collect(Collectors.joining(", ")));
|
||||
}
|
||||
writer.print(")");
|
||||
}
|
||||
if (newLine) {
|
||||
writer.println();
|
||||
}
|
||||
else {
|
||||
writer.print(" ");
|
||||
}
|
||||
}
|
||||
|
||||
private void writeAnnotation(IndentingWriter writer, Annotation annotation) {
|
||||
writeAnnotation(writer, annotation, true);
|
||||
}
|
||||
|
||||
private String formatAnnotationAttribute(Annotation.Attribute attribute) {
|
||||
List<String> values = attribute.getValues();
|
||||
if (attribute.getType().equals(Class.class)) {
|
||||
return formatValues(values, (value) -> String.format(annotationFormatString(), getUnqualifiedName(value)));
|
||||
}
|
||||
if (Enum.class.isAssignableFrom(attribute.getType())) {
|
||||
return formatValues(values, (value) -> {
|
||||
String enumValue = value.substring(value.lastIndexOf(".") + 1);
|
||||
String enumClass = value.substring(0, value.lastIndexOf("."));
|
||||
return String.format("%s.%s", getUnqualifiedName(enumClass), enumValue);
|
||||
});
|
||||
}
|
||||
if (attribute.getType().equals(String.class)) {
|
||||
return formatValues(values, (value) -> String.format("\"%s\"", value));
|
||||
}
|
||||
return formatValues(values, (value) -> String.format("%s", value));
|
||||
}
|
||||
|
||||
private String formatValues(List<String> values, Function<String, String> formatter) {
|
||||
String result = values.stream().map(formatter).collect(Collectors.joining(", "));
|
||||
return (values.size() > 1) ? formatAnnotationArray(result) : result;
|
||||
}
|
||||
|
||||
private String getUnqualifiedName(String name) {
|
||||
if (!name.contains(".")) {
|
||||
return name;
|
||||
}
|
||||
return name.substring(name.lastIndexOf(".") + 1);
|
||||
}
|
||||
|
||||
private Collection<String> determineImports(Annotation annotation) {
|
||||
List<String> imports = new ArrayList<>();
|
||||
imports.add(annotation.getName());
|
||||
@@ -379,6 +350,11 @@ public class KotlinSourceCodeWriter implements SourceCodeWriter<KotlinSourceCode
|
||||
return imports;
|
||||
}
|
||||
|
||||
private Stream<KotlinExpression> getKotlinExpressions(KotlinFunctionDeclaration functionDeclaration) {
|
||||
return functionDeclaration.getStatements().stream().filter(KotlinExpressionStatement.class::isInstance)
|
||||
.map(KotlinExpressionStatement.class::cast).map(KotlinExpressionStatement::getExpression);
|
||||
}
|
||||
|
||||
private <T> List<String> getRequiredImports(List<T> candidates, Function<T, Collection<String>> mapping) {
|
||||
return getRequiredImports(candidates.stream(), mapping);
|
||||
}
|
||||
@@ -388,20 +364,19 @@ public class KotlinSourceCodeWriter implements SourceCodeWriter<KotlinSourceCode
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private String getUnqualifiedName(String name) {
|
||||
if (!name.contains(".")) {
|
||||
return name;
|
||||
}
|
||||
return name.substring(name.lastIndexOf(".") + 1);
|
||||
}
|
||||
|
||||
private boolean requiresImport(String name) {
|
||||
if (name == null || !name.contains(".")) {
|
||||
return false;
|
||||
}
|
||||
String packageName = name.substring(0, name.lastIndexOf('.'));
|
||||
return !("java.lang".equals(packageName) || "kotlin".equals(packageName));
|
||||
}
|
||||
|
||||
private String annotationFormatString() {
|
||||
return "%s::class";
|
||||
}
|
||||
|
||||
private String formatAnnotationArray(String values) {
|
||||
return "[" + values + "]";
|
||||
return !"java.lang".equals(packageName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,6 @@ package io.spring.initializr.generator.language.kotlin;
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public interface KotlinStatement {
|
||||
public class KotlinStatement {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or 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.spring.initializr.generator.language.kotlin;
|
||||
|
||||
/**
|
||||
* Represents a Kotlin String type.
|
||||
*
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
public final class KotlinString implements KotlinExpression {
|
||||
|
||||
/**
|
||||
* The class name of this type.
|
||||
*/
|
||||
public static final String CLASS_NAME = "kotlin.String";
|
||||
|
||||
private final String value;
|
||||
|
||||
private KotlinString(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "\"" + this.value + "\"";
|
||||
}
|
||||
|
||||
public static KotlinString stringValue(String value) {
|
||||
return new KotlinString(value);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,10 +31,10 @@ public class KotlinTypeDeclaration extends TypeDeclaration {
|
||||
|
||||
private List<KotlinModifier> modifiers = new ArrayList<>();
|
||||
|
||||
private final List<KotlinFunctionDeclaration> functionDeclarations = new ArrayList<>();
|
||||
|
||||
private final List<KotlinPropertyDeclaration> propertyDeclarations = new ArrayList<>();
|
||||
|
||||
private final List<KotlinFunctionDeclaration> functionDeclarations = new ArrayList<>();
|
||||
|
||||
KotlinTypeDeclaration(String name) {
|
||||
super(name);
|
||||
}
|
||||
@@ -47,14 +47,6 @@ public class KotlinTypeDeclaration extends TypeDeclaration {
|
||||
return this.modifiers;
|
||||
}
|
||||
|
||||
public void addFunctionDeclaration(KotlinFunctionDeclaration methodDeclaration) {
|
||||
this.functionDeclarations.add(methodDeclaration);
|
||||
}
|
||||
|
||||
public List<KotlinFunctionDeclaration> getFunctionDeclarations() {
|
||||
return this.functionDeclarations;
|
||||
}
|
||||
|
||||
public void addPropertyDeclaration(KotlinPropertyDeclaration propertyDeclaration) {
|
||||
this.propertyDeclarations.add(propertyDeclaration);
|
||||
}
|
||||
@@ -63,4 +55,12 @@ public class KotlinTypeDeclaration extends TypeDeclaration {
|
||||
return this.propertyDeclarations;
|
||||
}
|
||||
|
||||
public void addFunctionDeclaration(KotlinFunctionDeclaration methodDeclaration) {
|
||||
this.functionDeclarations.add(methodDeclaration);
|
||||
}
|
||||
|
||||
public List<KotlinFunctionDeclaration> getFunctionDeclarations() {
|
||||
return this.functionDeclarations;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import java.util.List;
|
||||
import io.spring.initializr.generator.io.IndentingWriterFactory;
|
||||
import io.spring.initializr.generator.language.Annotation;
|
||||
import io.spring.initializr.generator.language.Parameter;
|
||||
import io.spring.initializr.generator.language.java.JavaPrimitives;
|
||||
import io.spring.initializr.generator.test.io.TextTestUtils;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
@@ -37,6 +36,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* Tests for {@link GroovySourceCodeWriter}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
class GroovySourceCodeWriterTests {
|
||||
|
||||
@@ -120,7 +120,7 @@ class GroovySourceCodeWriterTests {
|
||||
GroovySourceCode sourceCode = new GroovySourceCode();
|
||||
GroovyCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
GroovyTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addFieldDeclaration(GroovyFieldDeclaration.field("testString").returning(GroovyString.CLASS_NAME));
|
||||
test.addFieldDeclaration(GroovyFieldDeclaration.field("testString").returning("java.lang.String"));
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.groovy");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "", " String testString", "",
|
||||
"}");
|
||||
@@ -131,18 +131,18 @@ class GroovySourceCodeWriterTests {
|
||||
GroovySourceCode sourceCode = new GroovySourceCode();
|
||||
GroovyCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
GroovyTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addFieldDeclaration(GroovyFieldDeclaration.field("testInteger").value(GroovyPrimitives.integerValue(42))
|
||||
.returning(GroovyPrimitives.GroovyInteger.BOXED_CLASS_NAME));
|
||||
test.addFieldDeclaration(GroovyFieldDeclaration.field("testDouble").modifiers(Modifier.PRIVATE)
|
||||
.value(GroovyPrimitives.doubleValue(1986d)).returning(JavaPrimitives.JavaDouble.TYPE));
|
||||
test.addFieldDeclaration(GroovyFieldDeclaration.field("testLong").value(GroovyPrimitives.longValue(1986L))
|
||||
.returning(GroovyPrimitives.GroovyLong.TYPE));
|
||||
test.addFieldDeclaration(GroovyFieldDeclaration.field("testNullBoolean")
|
||||
.value(GroovyPrimitives.booleanValue(null)).returning(GroovyPrimitives.GroovyBoolean.BOXED_CLASS_NAME));
|
||||
test.addFieldDeclaration(GroovyFieldDeclaration.field("testNoInit").returning("boolean"));
|
||||
test.addFieldDeclaration(
|
||||
GroovyFieldDeclaration.field("testInteger").value("42").returning("java.lang.Integer"));
|
||||
test.addFieldDeclaration(GroovyFieldDeclaration.field("testDouble").modifiers(Modifier.PRIVATE).value("1986.0")
|
||||
.returning("double"));
|
||||
test.addFieldDeclaration(GroovyFieldDeclaration.field("testLong").value("1986L").returning("long"));
|
||||
test.addFieldDeclaration(
|
||||
GroovyFieldDeclaration.field("testNullBoolean").value(null).returning("java.lang.Boolean"));
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.groovy");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "", " Integer testInteger = 42",
|
||||
"", " private double testDouble = 1986.0", "", " long testLong = 1986L", "",
|
||||
" Boolean testNullBoolean = null", "", "}");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "", " boolean testNoInit", "",
|
||||
" Integer testInteger = 42", "", " private double testDouble = 1986.0", "",
|
||||
" long testLong = 1986L", "", " Boolean testNullBoolean = null", "", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -150,24 +150,37 @@ class GroovySourceCodeWriterTests {
|
||||
GroovySourceCode sourceCode = new GroovySourceCode();
|
||||
GroovyCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
GroovyTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addFieldDeclaration(GroovyFieldDeclaration.field("testString").modifiers(Modifier.PRIVATE)
|
||||
.returning(GroovyString.CLASS_NAME));
|
||||
test.addFieldDeclaration(
|
||||
GroovyFieldDeclaration.field("testString").modifiers(Modifier.PRIVATE).returning("java.lang.String"));
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.groovy");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "",
|
||||
" private String testString", "", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fieldImport() throws IOException {
|
||||
GroovySourceCode sourceCode = new GroovySourceCode();
|
||||
GroovyCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
GroovyTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addFieldDeclaration(
|
||||
GroovyFieldDeclaration.field("testString").modifiers(Modifier.PUBLIC).returning("com.example.One"));
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.groovy");
|
||||
assertThat(lines).containsExactly("package com.example", "", "import com.example.One", "", "class Test {", "",
|
||||
" public One testString", "", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fieldAnnotation() throws IOException {
|
||||
GroovySourceCode sourceCode = new GroovySourceCode();
|
||||
GroovyCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
GroovyTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addFieldDeclaration(GroovyFieldDeclaration.field("testString")
|
||||
.withAnnotation(Annotation.name("org.springframework.beans.factory.annotation.Autowired"))
|
||||
.returning(GroovyString.CLASS_NAME));
|
||||
GroovyFieldDeclaration field = GroovyFieldDeclaration.field("testString").returning("java.lang.String");
|
||||
field.annotate(Annotation.name("org.springframework.beans.factory.annotation.Autowired"));
|
||||
test.addFieldDeclaration(field);
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.groovy");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "", " @Autowired",
|
||||
" String testString", "", "}");
|
||||
assertThat(lines).containsExactly("package com.example", "",
|
||||
"import org.springframework.beans.factory.annotation.Autowired", "", "class Test {", "",
|
||||
" @Autowired", " String testString", "", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -89,7 +89,7 @@ class JavaSourceCodeWriterTests {
|
||||
JavaCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
JavaTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addMethodDeclaration(JavaMethodDeclaration.method("trim").returning("java.lang.String")
|
||||
.modifiers(Modifier.PUBLIC).parameters(new Parameter(JavaString.CLASS_NAME, "value"))
|
||||
.modifiers(Modifier.PUBLIC).parameters(new Parameter("java.lang.String", "value"))
|
||||
.body(new JavaReturnStatement(new JavaMethodInvocation("value", "trim"))));
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.java");
|
||||
assertThat(lines).containsExactly("package com.example;", "", "class Test {", "",
|
||||
@@ -103,12 +103,24 @@ class JavaSourceCodeWriterTests {
|
||||
JavaTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.modifiers(Modifier.PUBLIC);
|
||||
test.addFieldDeclaration(
|
||||
JavaFieldDeclaration.field("testString").modifiers(Modifier.PRIVATE).returning(JavaString.CLASS_NAME));
|
||||
JavaFieldDeclaration.field("testString").modifiers(Modifier.PRIVATE).returning("java.lang.String"));
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.java");
|
||||
assertThat(lines).containsExactly("package com.example;", "", "public class Test {", "",
|
||||
" private String testString;", "", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fieldImport() throws IOException {
|
||||
JavaSourceCode sourceCode = new JavaSourceCode();
|
||||
JavaCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
JavaTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addFieldDeclaration(
|
||||
JavaFieldDeclaration.field("testString").modifiers(Modifier.PUBLIC).returning("com.example.One"));
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.java");
|
||||
assertThat(lines).containsExactly("package com.example;", "", "import com.example.One;", "", "class Test {", "",
|
||||
" public One testString;", "", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fieldAnnotation() throws IOException {
|
||||
JavaSourceCode sourceCode = new JavaSourceCode();
|
||||
@@ -116,7 +128,7 @@ class JavaSourceCodeWriterTests {
|
||||
JavaTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.modifiers(Modifier.PUBLIC);
|
||||
JavaFieldDeclaration field = JavaFieldDeclaration.field("testString").modifiers(Modifier.PRIVATE)
|
||||
.returning(JavaString.CLASS_NAME);
|
||||
.returning("java.lang.String");
|
||||
field.annotate(Annotation.name("org.springframework.beans.factory.annotation.Autowired"));
|
||||
test.addFieldDeclaration(field);
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.java");
|
||||
@@ -132,19 +144,18 @@ class JavaSourceCodeWriterTests {
|
||||
JavaTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.modifiers(Modifier.PUBLIC);
|
||||
test.addFieldDeclaration(JavaFieldDeclaration.field("testString").modifiers(Modifier.PRIVATE)
|
||||
.value(JavaString.stringValue("Test String")).returning(JavaString.CLASS_NAME));
|
||||
.value("\"Test String\"").returning("java.lang.String"));
|
||||
test.addFieldDeclaration(JavaFieldDeclaration.field("testChar").modifiers(Modifier.PRIVATE | Modifier.TRANSIENT)
|
||||
.value(JavaPrimitives.charValue("\\u03a9")).returning(JavaPrimitives.JavaChar.TYPE));
|
||||
.value("'\\u03a9'").returning("char"));
|
||||
test.addFieldDeclaration(JavaFieldDeclaration.field("testInt").modifiers(Modifier.PRIVATE | Modifier.FINAL)
|
||||
.value(JavaPrimitives.integerValue(1337)).returning(JavaPrimitives.JavaInteger.TYPE));
|
||||
test.addFieldDeclaration(JavaFieldDeclaration.field("testDouble").modifiers(Modifier.PRIVATE)
|
||||
.value(JavaPrimitives.doubleValue(3.14)).returning(JavaPrimitives.JavaDouble.BOXED_CLASS_NAME));
|
||||
test.addFieldDeclaration(JavaFieldDeclaration.field("testLong").modifiers(Modifier.PRIVATE)
|
||||
.value(JavaPrimitives.longValue(1986L)).returning(JavaPrimitives.JavaLong.BOXED_CLASS_NAME));
|
||||
test.addFieldDeclaration(JavaFieldDeclaration.field("testFloat").value(JavaPrimitives.floatValue(99.999f))
|
||||
.returning(JavaPrimitives.JavaFloat.TYPE));
|
||||
test.addFieldDeclaration(JavaFieldDeclaration.field("testBool").packagePrivate()
|
||||
.value(JavaPrimitives.booleanValue(true)).returning(JavaPrimitives.JavaBoolean.TYPE));
|
||||
.value(1337).returning("int"));
|
||||
test.addFieldDeclaration(
|
||||
JavaFieldDeclaration.field("testDouble").modifiers(Modifier.PRIVATE).value("3.14").returning("Double"));
|
||||
test.addFieldDeclaration(
|
||||
JavaFieldDeclaration.field("testLong").modifiers(Modifier.PRIVATE).value("1986L").returning("Long"));
|
||||
test.addFieldDeclaration(
|
||||
JavaFieldDeclaration.field("testFloat").modifiers(Modifier.PUBLIC).value("99.999f").returning("float"));
|
||||
test.addFieldDeclaration(JavaFieldDeclaration.field("testBool").value("true").returning("boolean"));
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.java");
|
||||
assertThat(lines).containsExactly("package com.example;", "", "public class Test {", "",
|
||||
" private String testString = \"Test String\";", "",
|
||||
|
||||
@@ -35,6 +35,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
* Tests for {@link KotlinSourceCodeWriter}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
* @author Matt Berteaux
|
||||
*/
|
||||
class KotlinSourceCodeWriterTests {
|
||||
|
||||
@@ -89,7 +90,7 @@ class KotlinSourceCodeWriterTests {
|
||||
KotlinTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addFunctionDeclaration(KotlinFunctionDeclaration.function("reverse").returning("java.lang.String")
|
||||
.parameters(new Parameter("java.lang.String", "echo"))
|
||||
.body(new KotlinReturnStatement(new KotlinMethodInvocation("echo", "reversed"))));
|
||||
.body(new KotlinReturnStatement(new KotlinFunctionInvocation("echo", "reversed"))));
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.kt");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "",
|
||||
" fun reverse(echo: String): String {", " return echo.reversed()", " }", "", "}");
|
||||
@@ -103,12 +104,127 @@ class KotlinSourceCodeWriterTests {
|
||||
test.addFunctionDeclaration(KotlinFunctionDeclaration.function("toString")
|
||||
.modifiers(KotlinModifier.OVERRIDE, KotlinModifier.PUBLIC, KotlinModifier.OPEN)
|
||||
.returning("java.lang.String")
|
||||
.body(new KotlinReturnStatement(new KotlinMethodInvocation("super", "toString"))));
|
||||
.body(new KotlinReturnStatement(new KotlinFunctionInvocation("super", "toString"))));
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.kt");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "",
|
||||
" open override fun toString(): String {", " return super.toString()", " }", "", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void valProperty() throws IOException {
|
||||
KotlinSourceCode sourceCode = new KotlinSourceCode();
|
||||
KotlinCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
KotlinTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addPropertyDeclaration(
|
||||
KotlinPropertyDeclaration.val("testProp").returning("java.lang.String").emptyValue());
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.kt");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "", " val testProp: String", "",
|
||||
"}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void valPropertyImport() throws IOException {
|
||||
KotlinSourceCode sourceCode = new KotlinSourceCode();
|
||||
KotlinCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
KotlinTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addPropertyDeclaration(
|
||||
KotlinPropertyDeclaration.val("testProp").returning("com.example.One").emptyValue());
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.kt");
|
||||
assertThat(lines).containsExactly("package com.example", "", "import com.example.One", "", "class Test {", "",
|
||||
" val testProp: One", "", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void valGetterProperty() throws IOException {
|
||||
KotlinSourceCode sourceCode = new KotlinSourceCode();
|
||||
KotlinCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
KotlinTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addPropertyDeclaration(
|
||||
KotlinPropertyDeclaration.val("testProp").returning("java.lang.String").value("\"This is a TEST\""));
|
||||
test.addPropertyDeclaration(KotlinPropertyDeclaration.val("withGetter").returning("java.lang.String").getter()
|
||||
.withBody(new KotlinExpressionStatement(new KotlinFunctionInvocation("testProp", "toLowerCase")))
|
||||
.buildAccessor().emptyValue());
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.kt");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "",
|
||||
" val testProp: String = \"This is a TEST\"", "", " val withGetter: String",
|
||||
" get() = testProp.toLowerCase()", "", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void varProperty() throws IOException {
|
||||
KotlinSourceCode sourceCode = new KotlinSourceCode();
|
||||
KotlinCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
KotlinTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addPropertyDeclaration(
|
||||
KotlinPropertyDeclaration.var("testProp").returning("java.lang.String").value("\"This is a test\""));
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.kt");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "",
|
||||
" var testProp: String = \"This is a test\"", "", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void varSetterProperty() throws IOException {
|
||||
KotlinSourceCode sourceCode = new KotlinSourceCode();
|
||||
KotlinCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
KotlinTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addPropertyDeclaration(KotlinPropertyDeclaration.var("testProp").returning("java.lang.String").setter()
|
||||
.buildAccessor().value("\"This is a test\""));
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.kt");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "",
|
||||
" var testProp: String = \"This is a test\"", " set", "", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void varAnnotateSetterProperty() throws IOException {
|
||||
KotlinSourceCode sourceCode = new KotlinSourceCode();
|
||||
KotlinCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
KotlinTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addPropertyDeclaration(KotlinPropertyDeclaration.var("testProp").returning("java.lang.String").setter()
|
||||
.withAnnotation(Annotation.name("org.springframework.beans.factory.annotation.Autowired"))
|
||||
.buildAccessor().value("\"This is a test\""));
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.kt");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "",
|
||||
" var testProp: String = \"This is a test\"", " @Autowired set", "", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void varProperties() throws IOException {
|
||||
KotlinSourceCode sourceCode = new KotlinSourceCode();
|
||||
KotlinCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
KotlinTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addPropertyDeclaration(KotlinPropertyDeclaration.var("testProp").returning("Int").value(42));
|
||||
test.addPropertyDeclaration(KotlinPropertyDeclaration.var("testDouble").returning("Double").value("1986.0"));
|
||||
test.addPropertyDeclaration(KotlinPropertyDeclaration.var("testFloat").value("99.999f"));
|
||||
test.addPropertyDeclaration(KotlinPropertyDeclaration.var("testLong").returning("Long").value("1986L"));
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.kt");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "", " var testProp: Int = 42",
|
||||
"", " var testDouble: Double = 1986.0", "", " var testFloat = 99.999f", "",
|
||||
" var testLong: Long = 1986L", "", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void varEmptyProperty() throws IOException {
|
||||
KotlinSourceCode sourceCode = new KotlinSourceCode();
|
||||
KotlinCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
KotlinTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addPropertyDeclaration(KotlinPropertyDeclaration.var("testProp").returning("Int").empty());
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.kt");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "", " var testProp: Int", "",
|
||||
"}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void varLateinitProperty() throws IOException {
|
||||
KotlinSourceCode sourceCode = new KotlinSourceCode();
|
||||
KotlinCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
KotlinTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addPropertyDeclaration(
|
||||
KotlinPropertyDeclaration.var("testProp").modifiers(KotlinModifier.LATEINIT).returning("Int").empty());
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.kt");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "",
|
||||
" lateinit var testProp: Int", "", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void springBootApplication() throws IOException {
|
||||
KotlinSourceCode sourceCode = new KotlinSourceCode();
|
||||
@@ -178,102 +294,6 @@ class KotlinSourceCodeWriterTests {
|
||||
"@TestApplication(target = One::class, unit = ChronoUnit.NANOS)", "class Test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void valProperty() throws IOException {
|
||||
KotlinSourceCode sourceCode = new KotlinSourceCode();
|
||||
KotlinCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
KotlinTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addPropertyDeclaration(
|
||||
KotlinPropertyDeclaration.val("testProp").returning(KotlinString.CLASS_NAME).emptyValue());
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.kt");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "", " val testProp: String", "",
|
||||
"}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void valGetterProperty() throws IOException {
|
||||
KotlinSourceCode sourceCode = new KotlinSourceCode();
|
||||
KotlinCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
KotlinTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addPropertyDeclaration(KotlinPropertyDeclaration.val("testProp").returning(KotlinString.CLASS_NAME)
|
||||
.value(KotlinString.stringValue("This is a TEST")));
|
||||
test.addPropertyDeclaration(KotlinPropertyDeclaration.val("withGetter").returning(KotlinString.CLASS_NAME)
|
||||
.getter().withBody(new KotlinExpressionStatement(new KotlinMethodInvocation("testProp", "toLowerCase")))
|
||||
.buildAccessor().emptyValue());
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.kt");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "",
|
||||
" val testProp: String = \"This is a TEST\"", "", " val withGetter: String",
|
||||
" get() = testProp.toLowerCase()", "", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void varProperty() throws IOException {
|
||||
KotlinSourceCode sourceCode = new KotlinSourceCode();
|
||||
KotlinCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
KotlinTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addPropertyDeclaration(KotlinPropertyDeclaration.var("testProp").returning(KotlinString.CLASS_NAME)
|
||||
.value(KotlinString.stringValue("This is a test")));
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.kt");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "",
|
||||
" var testProp: String = \"This is a test\"", "", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void varPrivateSetterProperty() throws IOException {
|
||||
KotlinSourceCode sourceCode = new KotlinSourceCode();
|
||||
KotlinCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
KotlinTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addPropertyDeclaration(KotlinPropertyDeclaration.var("testProp").returning(KotlinString.CLASS_NAME)
|
||||
.setter().isPrivate().buildAccessor().value(KotlinString.stringValue("This is a test")));
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.kt");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "",
|
||||
" var testProp: String = \"This is a test\"", " private set", "", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void varAnnotateSetterProperty() throws IOException {
|
||||
KotlinSourceCode sourceCode = new KotlinSourceCode();
|
||||
KotlinCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
KotlinTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addPropertyDeclaration(KotlinPropertyDeclaration.var("testProp").returning(KotlinString.CLASS_NAME)
|
||||
.setter().withAnnotation(Annotation.name("org.springframework.beans.factory.annotation.Autowired"))
|
||||
.buildAccessor().value(KotlinString.stringValue("This is a test")));
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.kt");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "",
|
||||
" var testProp: String = \"This is a test\"", " @Autowired set", "", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void varProperties() throws IOException {
|
||||
KotlinSourceCode sourceCode = new KotlinSourceCode();
|
||||
KotlinCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
KotlinTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addPropertyDeclaration(KotlinPropertyDeclaration.var("testProp")
|
||||
.returning(KotlinPrimitives.KotlinInt.BOXED_CLASS_NAME).value(KotlinPrimitives.integerValue(42)));
|
||||
test.addPropertyDeclaration(KotlinPropertyDeclaration.var("testDouble")
|
||||
.returning(KotlinPrimitives.KotlinDouble.BOXED_CLASS_NAME).value(KotlinPrimitives.doubleValue(1986d)));
|
||||
test.addPropertyDeclaration(
|
||||
KotlinPropertyDeclaration.var("testFloat").value(KotlinPrimitives.floatValue(99.999f)));
|
||||
test.addPropertyDeclaration(KotlinPropertyDeclaration.var("testLong")
|
||||
.returning(KotlinPrimitives.KotlinLong.BOXED_CLASS_NAME).value(KotlinPrimitives.longValue(1986L)));
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.kt");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "", " var testProp: Int = 42",
|
||||
"", " var testDouble: Double = 1986.0", "", " var testFloat = 99.999f", "",
|
||||
" var testLong: Long = 1986L", "", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void varEmptyProperty() throws IOException {
|
||||
KotlinSourceCode sourceCode = new KotlinSourceCode();
|
||||
KotlinCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
KotlinTypeDeclaration test = compilationUnit.createTypeDeclaration("Test");
|
||||
test.addPropertyDeclaration(KotlinPropertyDeclaration.var("testProp")
|
||||
.returning(KotlinPrimitives.KotlinInt.BOXED_CLASS_NAME).empty());
|
||||
List<String> lines = writeSingleType(sourceCode, "com/example/Test.kt");
|
||||
assertThat(lines).containsExactly("package com.example", "", "class Test {", "", " var testProp: Int", "",
|
||||
"}");
|
||||
}
|
||||
|
||||
private List<String> writeClassAnnotation(Annotation annotation) throws IOException {
|
||||
KotlinSourceCode sourceCode = new KotlinSourceCode();
|
||||
KotlinCompilationUnit compilationUnit = sourceCode.createCompilationUnit("com.example", "Test");
|
||||
|
||||
Reference in New Issue
Block a user