Compare commits

..

12 Commits

Author SHA1 Message Date
Jordan Zimmerman
491ed4f6e0 [maven-release-plugin] prepare release record-builder-1.14.ea 2020-12-11 19:27:34 -05:00
Jordan Zimmerman
16751508cc Update README.md 2020-12-11 13:54:05 -05:00
Jordan Zimmerman
ee7f81c7b8 Switch to Github Actions 2020-12-11 13:52:58 -05:00
Jordan Zimmerman
015287608b Update maven.yml 2020-12-11 13:51:51 -05:00
Jordan Zimmerman
467bcc9041 Create maven.yml 2020-12-11 13:50:22 -05:00
Jordan Zimmerman
666bc334ad Merge pull request #16 from mbarbero/master
Stop relying on toString() to detect package name.
2020-12-11 13:39:30 -05:00
Mikaël Barbero
9c8e3626ba Stop relying on toString() to detect package name.
Fix for #15
2020-12-11 18:18:32 +00:00
Jordan Zimmerman
24b85e7ad5 [maven-release-plugin] prepare for next development iteration 2020-11-29 08:27:34 -05:00
Jordan Zimmerman
861e2e745a [maven-release-plugin] prepare release record-builder-1.13.ea 2020-11-29 08:27:25 -05:00
Jordan Zimmerman
1fc7c9a4b3 Make sure the downcast variable name doesn't collide with a record component name 2020-11-28 22:39:00 -05:00
Jordan Zimmerman
570514e077 buildPackageName() can't assume that the immediate enclosing element is the package. It may be a nested class, etc. 2020-11-28 22:38:48 -05:00
Jordan Zimmerman
9d8b9e65bc [maven-release-plugin] prepare for next development iteration 2020-11-28 08:44:33 -05:00
13 changed files with 130 additions and 29 deletions

24
.github/workflows/maven.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
name: Java CI with Maven
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up JDK
uses: actions/setup-java@v1
with:
java-version: 15
- name: Build with Maven
run: mvn -B package --file pom.xml

View File

@@ -1,3 +0,0 @@
language: java
jdk:
- openjdk15

View File

@@ -1,4 +1,4 @@
[![Build Status](https://travis-ci.org/Randgalt/record-builder.svg?branch=master)](https://travis-ci.org/Randgalt/record-builder)
[![Build Status](https://github.com/Randgalt/record-builder/workflows/Java%20CI%20with%20Maven/badge.svg)](https://github.com/Randgalt/record-builder/actions)
[![Maven Central](https://img.shields.io/maven-central/v/io.soabase.record-builder/record-builder.svg)](https://search.maven.org/search?q=g:io.soabase.record-builder%20a:record-builder)
# RecordBuilder - Early Access

View File

@@ -5,7 +5,7 @@
<groupId>io.soabase.record-builder</groupId>
<artifactId>record-builder</artifactId>
<packaging>pom</packaging>
<version>1.12.ea</version>
<version>1.14.ea</version>
<modules>
<module>record-builder-core</module>
@@ -71,7 +71,7 @@
<url>https://github.com/randgalt/record-builder</url>
<connection>scm:git:https://github.com/randgalt/record-builder.git</connection>
<developerConnection>scm:git:git@github.com:randgalt/record-builder.git</developerConnection>
<tag>record-builder-1.12.ea</tag>
<tag>record-builder-1.14.ea</tag>
</scm>
<issueManagement>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>io.soabase.record-builder</groupId>
<artifactId>record-builder</artifactId>
<version>1.12.ea</version>
<version>1.14.ea</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>io.soabase.record-builder</groupId>
<artifactId>record-builder</artifactId>
<version>1.12.ea</version>
<version>1.14.ea</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -86,8 +86,9 @@ public class ElementUtils {
break;
}
}
String name = typeElement.getEnclosingElement().toString();
return !name.equals("unnamed package") ? name : "";
String name = typeElement.getQualifiedName().toString();
int index = name.lastIndexOf(".");
return (index > -1) ? name.substring(0, index) : "";
}
public static ClassType getClassType(String packageName, String simpleName, List<? extends TypeParameterElement> typeParameters) {

View File

@@ -53,6 +53,7 @@ class InternalRecordBuilderProcessor
private final List<ClassType> recordComponents;
private final TypeSpec builderType;
private final TypeSpec.Builder builder;
private final String uniqueVarName;
InternalRecordBuilderProcessor(TypeElement record, RecordBuilderMetaData metaData, Optional<String> packageNameOpt)
{
@@ -62,6 +63,7 @@ class InternalRecordBuilderProcessor
builderClassType = ElementUtils.getClassType(packageName, getBuilderName(record, metaData, recordClassType, metaData.suffix()), record.getTypeParameters());
typeVariables = record.getTypeParameters().stream().map(TypeVariableName::get).collect(Collectors.toList());
recordComponents = record.getRecordComponents().stream().map(ElementUtils::getClassType).collect(Collectors.toList());
uniqueVarName = getUniqueVarName();
builder = TypeSpec.classBuilder(builderClassType.name())
.addModifiers(Modifier.PUBLIC)
@@ -139,8 +141,8 @@ class InternalRecordBuilderProcessor
}
*/
var codeBlockBuilder = CodeBlock.builder()
.add("$T r = $L(this);\n", recordClassType.typeName(), metaData.downCastMethodName())
.add("$T builder = $L.$L(r);\n", builderClassType.typeName(), builderClassType.name(), metaData.copyMethodName())
.add("$T $L = $L(this);\n", recordClassType.typeName(), uniqueVarName, metaData.downCastMethodName())
.add("$T builder = $L.$L($L);\n", builderClassType.typeName(), builderClassType.name(), metaData.copyMethodName(), uniqueVarName)
.add("consumer.accept(builder);\n")
.add("return builder.build();\n");
var consumerType = ParameterizedTypeName.get(ClassName.get(Consumer.class), builderClassType.typeName());
@@ -167,8 +169,8 @@ class InternalRecordBuilderProcessor
}
*/
var codeBlockBuilder = CodeBlock.builder()
.add("$T r = $L(this);\n", recordClassType.typeName(), metaData.downCastMethodName())
.add("return $L.$L(r);", builderClassType.name(), metaData.copyMethodName());
.add("$T $L = $L(this);\n", recordClassType.typeName(), uniqueVarName, metaData.downCastMethodName())
.add("return $L.$L($L);", builderClassType.name(), metaData.copyMethodName(), uniqueVarName);
var methodSpec = MethodSpec.methodBuilder(metaData.withClassMethodPrefix())
.addAnnotation(generatedRecordBuilderAnnotation)
.addJavadoc("Return a new record builder using the current values")
@@ -179,6 +181,20 @@ class InternalRecordBuilderProcessor
classBuilder.addMethod(methodSpec);
}
private String getUniqueVarName()
{
return getUniqueVarName("");
}
private String getUniqueVarName(String prefix)
{
var name = prefix + "r";
var alreadyExists = recordComponents.stream()
.map(ClassType::name)
.anyMatch(n -> n.equals(name));
return alreadyExists ? getUniqueVarName(prefix + "_") : name;
}
private void add1WithMethod(TypeSpec.Builder classBuilder, ClassType component, int index)
{
/*
@@ -191,7 +207,7 @@ class InternalRecordBuilderProcessor
*/
var codeBlockBuilder = CodeBlock.builder();
if (recordComponents.size() > 1) {
codeBlockBuilder.add("$T r = $L(this);\n", recordClassType.typeName(), metaData.downCastMethodName());
codeBlockBuilder.add("$T $L = $L(this);\n", recordClassType.typeName(), uniqueVarName, metaData.downCastMethodName());
}
codeBlockBuilder.add("return new $T(", recordClassType.typeName());
IntStream.range(0, recordComponents.size()).forEach(parameterIndex -> {
@@ -203,7 +219,7 @@ class InternalRecordBuilderProcessor
codeBlockBuilder.add(parameterComponent.name());
}
else {
codeBlockBuilder.add("r.$L()", parameterComponent.name());
codeBlockBuilder.add("$L.$L()", uniqueVarName, parameterComponent.name());
}
});
codeBlockBuilder.add(");");
@@ -352,14 +368,14 @@ class InternalRecordBuilderProcessor
*/
var codeBuilder = CodeBlock.builder();
codeBuilder.add("return (this == o) || (");
codeBuilder.add("(o instanceof $L b)", builderClassType.name());
codeBuilder.add("(o instanceof $L $L)", builderClassType.name(), uniqueVarName);
recordComponents.forEach(recordComponent -> {
String name = recordComponent.name();
if (recordComponent.typeName().isPrimitive()) {
codeBuilder.add("\n&& ($L == b.$L)", name, name);
codeBuilder.add("\n&& ($L == $L.$L)", name, uniqueVarName, name);
}
else {
codeBuilder.add("\n&& $T.equals($L, b.$L)", Objects.class, name, name);
codeBuilder.add("\n&& $T.equals($L, $L.$L)", Objects.class, name, uniqueVarName, name);
}
});
codeBuilder.add(")");

View File

@@ -117,15 +117,18 @@ public class RecordBuilderProcessor extends AbstractProcessor {
else
{
var packageName = buildPackageName(packagePattern, element, typeElement);
if ( annotationClass.equals(RECORD_INTERFACE_INCLUDE) )
if (packageName != null)
{
var addRecordBuilderOpt = ElementUtils.getAnnotationValue(values, "addRecordBuilder");
var addRecordBuilder = addRecordBuilderOpt.map(ElementUtils::getBooleanAttribute).orElse(true);
processRecordInterface(typeElement, addRecordBuilder, metaData, Optional.of(packageName));
}
else
{
processRecordBuilder(typeElement, metaData, Optional.of(packageName));
if ( annotationClass.equals(RECORD_INTERFACE_INCLUDE) )
{
var addRecordBuilderOpt = ElementUtils.getAnnotationValue(values, "addRecordBuilder");
var addRecordBuilder = addRecordBuilderOpt.map(ElementUtils::getBooleanAttribute).orElse(true);
processRecordInterface(typeElement, addRecordBuilder, metaData, Optional.of(packageName));
}
else
{
processRecordBuilder(typeElement, metaData, Optional.of(packageName));
}
}
}
}
@@ -134,13 +137,28 @@ public class RecordBuilderProcessor extends AbstractProcessor {
}
private String buildPackageName(String packagePattern, Element builderElement, TypeElement includedClass) {
String replaced = packagePattern.replace("*", ((PackageElement)includedClass.getEnclosingElement()).getQualifiedName().toString());
PackageElement includedClassPackage = findPackageElement(includedClass, includedClass);
if (includedClassPackage == null) {
return null;
}
String replaced = packagePattern.replace("*", includedClassPackage.getQualifiedName().toString());
if (builderElement instanceof PackageElement) {
return replaced.replace("@", ((PackageElement)builderElement).getQualifiedName().toString());
}
return replaced.replace("@", ((PackageElement)builderElement.getEnclosingElement()).getQualifiedName().toString());
}
private PackageElement findPackageElement(Element actualElement, Element includedClass) {
if (includedClass == null) {
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Element has not package", actualElement);
return null;
}
if (includedClass.getEnclosingElement() instanceof PackageElement) {
return (PackageElement)includedClass.getEnclosingElement();
}
return findPackageElement(actualElement, includedClass.getEnclosingElement());
}
private void processRecordInterface(TypeElement element, boolean addRecordBuilder, RecordBuilderMetaData metaData, Optional<String> packageName) {
if ( !element.getKind().isInterface() )
{

View File

@@ -3,7 +3,7 @@
<parent>
<groupId>io.soabase.record-builder</groupId>
<artifactId>record-builder</artifactId>
<version>1.12.ea</version>
<version>1.14.ea</version>
</parent>
<modelVersion>4.0.0</modelVersion>

View File

@@ -15,10 +15,14 @@
*/
package io.soabase.recordbuilder.test;
import io.soabase.recordbuilder.core.RecordBuilder;
import io.soabase.recordbuilder.core.RecordInterface;
@RecordInterface.Include({
Thingy.class
})
@RecordBuilder.Include({
Nested.NestedRecord.class
})
public class Builder {
}

View File

@@ -0,0 +1,20 @@
/**
* Copyright 2019 Jordan Zimmerman
*
* 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
*
* http://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.soabase.recordbuilder.test;
public class Nested {
record NestedRecord(int x, int y){}
}

View File

@@ -0,0 +1,21 @@
/**
* Copyright 2019 Jordan Zimmerman
*
* 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
*
* http://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.soabase.recordbuilder.test;
import io.soabase.recordbuilder.core.RecordBuilder;
@RecordBuilder
public record RecordWithAnR(int r, String b) {}