Skip to content

Commit

Permalink
refinements and more tests for jdk optional unboxing, safer identifiers
Browse files Browse the repository at this point in the history
(prevents keyword clashes for simplest cases) #240
  • Loading branch information
elucash committed Jan 24, 2016
1 parent 3041855 commit 89c58eb
Show file tree
Hide file tree
Showing 8 changed files with 195 additions and 8 deletions.
17 changes: 15 additions & 2 deletions generator-processor/pom.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>immutables</artifactId>
<groupId>org.immutables</groupId>
Expand Down Expand Up @@ -56,6 +57,19 @@
<id>pargen</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.immutables.tools</groupId>
<artifactId>maven-shade-plugin</artifactId>
Expand All @@ -67,7 +81,6 @@
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>true</createDependencyReducedPom>
<shadedArtifactAttached>true</shadedArtifactAttached>
<createSourcesJar>true</createSourcesJar>
<shadedClassifierName>pargen</shadedClassifierName>
Expand Down
9 changes: 8 additions & 1 deletion value-fixture/pom.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
Expand All @@ -24,6 +25,12 @@
<classifier>annotations</classifier>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.immutables</groupId>
<artifactId>serial</artifactId>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.immutables</groupId>
<artifactId>value-processor</artifactId>
Expand Down
@@ -1,5 +1,6 @@
package org.immutables.fixture.jackson;

import java.util.Optional;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import java.util.List;
import org.immutables.value.Value;
Expand All @@ -14,3 +15,16 @@
public interface PackageHidden {
List<String> getStrings();
}

@Value.Immutable(builder = false)
@Value.Style(
jdkOnly = true,
overshadowImplementation = true,
implementationNestedInBuilder = true,
visibility = Value.Style.ImplementationVisibility.PACKAGE)
@JsonDeserialize(as = ImmutablePackageNoBuilderHidden.class)
interface PackageNoBuilderHidden {
List<String> getStrings();

Optional<Integer> getInt();
}
43 changes: 43 additions & 0 deletions value-fixture/src/org/immutables/fixture/jdkonly/JdkOptionals.java
@@ -0,0 +1,43 @@
package org.immutables.fixture.jdkonly;

import java.io.Serializable;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.OptionalLong;
import org.immutables.gson.Gson;
import org.immutables.serial.Serial;
import org.immutables.value.Value;

@Serial.Structural
@Value.Immutable(builder = false, singleton = true, intern = true, prehash = true)
@Gson.TypeAdapters
public interface JdkOptionals {
@Value.Parameter
Optional<String> v2();

@Value.Parameter
OptionalInt i1();

@Value.Parameter
OptionalLong l1();

@Value.Parameter
OptionalDouble d1();
}

@Value.Immutable
@Value.Style(privateNoargConstructor = true)
interface JdkOptionalsSer extends Serializable {
@Value.Parameter
Optional<String> v2();

@Value.Parameter
OptionalInt i1();

@Value.Parameter
OptionalLong l1();

@Value.Parameter
OptionalDouble d1();
}
@@ -0,0 +1,77 @@
package org.immutables.fixture.jdkonly;

import java.util.OptionalLong;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.Optional;
import org.junit.Test;
import static org.immutables.check.Checkers.check;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

// tests how unboxing of jdk optionals is implemented
public class JdkOptionalTest {

@Test
public void equals() {
ImmutableJdkOptionals o1 = ImmutableJdkOptionals.of()
.withV2("v2")
.withI1(1)
.withD1(1.0);

ImmutableJdkOptionals o2 = ImmutableJdkOptionals.of(
Optional.of("v2"),
OptionalInt.of(1),
OptionalLong.empty(),
OptionalDouble.of(1.0));

check(o1).is(o2);
check(o1.hashCode()).is(o2.hashCode());
}

@Test
public void serializeStructural() throws Exception {
ImmutableJdkOptionals o1 = ImmutableJdkOptionals.of()
.withV2("v2")
.withI1(1);

check(deserialize(serialize(o1))).is(o1);
}

@Test
public void serializeStructuralSingleton() throws Exception {
ImmutableJdkOptionals o1 = ImmutableJdkOptionals.of();
check(deserialize(serialize(o1))).same(o1);
}

@Test
public void serializeRegular() throws Exception {
ImmutableJdkOptionalsSer o0 = ImmutableJdkOptionalsSer.builder()
.d1(1.0)
.l1(2L)
.v2("e4")
.build();

Serializable o1 = deserialize(serialize(o0));
check(o1).is(o0);
check(o1.hashCode()).is(o0.hashCode());
}

private Serializable deserialize(byte[] bytes) throws Exception {
ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
ObjectInputStream objectStream = new ObjectInputStream(stream);
return (Serializable) objectStream.readObject();
}

private byte[] serialize(Serializable instance) throws Exception {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
ObjectOutputStream objectStream = new ObjectOutputStream(stream);
objectStream.writeObject(instance);
objectStream.close();
return stream.toByteArray();
}

}
Expand Up @@ -115,8 +115,9 @@ import [starImport];
[/if]
[generateImmutableMembers type]
[generateLazyValues type]
[generateInterning type]
[generateSingletonInstance type]
[generateConstructionAndInterning type]
[generateConstruction type]
[generateImmutableCopyOf type]
[generateSerialization type]
[if type.useBuilder and (not type.constitution.isOutsideBuilder)]
Expand Down Expand Up @@ -350,7 +351,7 @@ private static class SerialForm implements java.io.Serializable {
if (elements.length == 1) {
return elements['[0]'];
}
throw new [type.throwForInvalidImmutableState]("Cannot decide scalar value for attribute '"
throw new [type.throwForInvalidImmutableState]("Cannot extract scalar value for attribute '"
+ attribute + "' from array of length " + elements.length);
}
return value;
Expand Down Expand Up @@ -389,7 +390,7 @@ private Object writeReplace() {
[/if]
[/template]

[template generateConstructionAndInterning Type type]
[template generateInterning Type type]
[if type.useInterned or type.generateOrdinalValue]
[if not type.useSingletonOnly]

Expand Down Expand Up @@ -477,6 +478,9 @@ private Object writeReplace() {
private static final [guava].collect.Interner<InternProxy> INTERNER = [guava].collect.Interners.newStrongInterner();
[/if]
[/if]
[/template]

[template generateConstruction Type type]
[if type.useConstructor and (not type.factoryOf.new)]
[if type.requiresAlternativeStrictConstructor]

Expand Down Expand Up @@ -1354,7 +1358,9 @@ return [type.factoryOf]([output.linesShortable][for v in type.settableAttributes
[/template]

[template emptyImmutableInstanceInferred Type type Attribute v][output.trim]
[if v.optionalType]
[if v.jdkOptional]
null
[else if v.optionalType]
[optionalEmpty v]
[else if v.mapType]
[if v.generateJdkOnly]
Expand Down
@@ -0,0 +1,24 @@
package org.immutables.value.processor.meta;

import com.google.common.collect.ImmutableSet;

class Keywords {
private static final ImmutableSet<String> keywords = ImmutableSet.of(
"abstract", "assert", "boolean",
"break", "byte", "case", "catch", "char", "class", "const",
"continue", "default", "do", "double", "else", "extends", "false",
"final", "finally", "float", "for", "goto", "if", "implements",
"import", "instanceof", "int", "interface", "long", "native",
"new", "null", "package", "private", "protected", "public",
"return", "short", "static", "strictfp", "super", "switch",
"synchronized", "this", "throw", "throws", "transient", "true",
"try", "void", "volatile", "while");

static boolean is(String identifier) {
return keywords.contains(identifier);
}

static String safeIdentifier(String identifier, String fallback) {
return is(identifier) ? fallback : identifier;
}
}
Expand Up @@ -16,7 +16,6 @@
package org.immutables.value.processor.meta;

import org.immutables.generator.Naming;

import com.google.common.base.CaseFormat;

public final class Styles {
Expand Down Expand Up @@ -98,6 +97,10 @@ private UsingName(String name, Scheme scheme, String forcedRaw) {
}

private String detectRawFromGet() {
return Keywords.safeIdentifier(detectRawFrom(name), name);
}

private String detectRawFrom(String name) {
if (!forcedRaw.isEmpty()) {
return forcedRaw;
}
Expand Down

0 comments on commit 89c58eb

Please sign in to comment.