Skip to content

Commit

Permalink
created sketch of type handling
Browse files Browse the repository at this point in the history
removed unnecessary abstraction reuse for declaring type
  • Loading branch information
elucash committed Jul 7, 2016
1 parent cdd241f commit 0c5e9fa
Show file tree
Hide file tree
Showing 7 changed files with 1,974 additions and 1,664 deletions.
2 changes: 1 addition & 1 deletion encode/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
<parent>
<artifactId>immutables</artifactId>
<groupId>org.immutables</groupId>
<version>2.2.10-SNAPSHOT</version>
<version>2.2.11-SNAPSHOT</version>
</parent>
<artifactId>encode</artifactId>
<description></description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,10 +208,11 @@ private char get(int i) {
}
}

static abstract class Term {
static abstract class Term extends Eq<Term> {
private final String string;

Term(String string) {
super(string);
this.string = string;
}

Expand All @@ -237,19 +238,8 @@ public String toString() {
}

@Override
public int hashCode() {
return string.hashCode();
}

@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() == obj.getClass()) {
return ((Term) obj).string.equals(string);
}
return true;
protected boolean eq(Term other) {
return string.equals(other.string);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.immutables.value.processor.encode;

import com.google.common.collect.ImmutableMap;
import java.util.Map;
import javax.annotation.Nullable;
import org.immutables.value.processor.encode.Type.Array;
import org.immutables.value.processor.encode.Type.Defined;
import org.immutables.value.processor.encode.Type.Nonprimitive;
import org.immutables.value.processor.encode.Type.Primitive;
import org.immutables.value.processor.encode.Type.Reference;
import org.immutables.value.processor.encode.Type.Variable;
import org.immutables.value.processor.encode.Type.Wildcard;

class DefaultTypeFactory implements Type.Factory {
private static final Map<String, Type> PREDEFINED_TYPES;
static {
ImmutableMap.Builder<String, Type> predefined =
ImmutableMap.<String, Type>builder().put(Type.OBJECT.name, Type.OBJECT);
for (Primitive p : Primitive.values()) {
predefined.put(p.typename, p);
}
PREDEFINED_TYPES = predefined.build();
}

@Override
public Type named(String name) {
@Nullable Type type = PREDEFINED_TYPES.get(name);
if (type != null) return type;
return defined(name);
}

private Type defined(String name) {
return null;
}

@Override
public Type.Parameterized parameterized(Reference raw, Iterable<? extends Nonprimitive> arguments) {
return null;
}

@Override
public Array array(Type element) {
return null;
}

@Override
public Wildcard.Super superWildcard(Defined lowerBound) {
return null;
}

@Override
public Wildcard.Extends extendsWildcard(Defined upperBound) {
return null;
}

@Override
public Variable variable(String name) {
return null; // TODO auto
}

@Override
public Reference unresolved(String name) {
return null; // TODO auto
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,106 +6,105 @@
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.Modifier;
import javax.lang.model.element.NestingKind;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementFilter;
import org.immutables.generator.AbstractTemplate;
import org.immutables.generator.Generator;
import org.immutables.generator.SourceExtraction;
import org.immutables.generator.Templates;
import org.immutables.value.processor.meta.Proto;
import org.immutables.value.processor.meta.Proto.DeclaringType;
import org.immutables.value.processor.meta.Reporter;

@Generator.Template
public abstract class Encodings extends AbstractTemplate {
@Generator.Typedef
Encoding Encoding;

public abstract Templates.Invokable generate();

final Reporter reporter = Reporter.from(processing());
final List<Encoding> encodings = new ArrayList<>();

Encodings() {
// we just opportunistically reuse declaring type/package model to use some
// of the infrastructure without needing much of the lazy detection code there.
Proto.DeclaringFactory factory = new Proto.DeclaringFactory(processing());
for (TypeElement a : annotations()) {
for (TypeElement t : ElementFilter.typesIn(round().getElementsAnnotatedWith(a))) {
encodings.add(new Encoding(factory.typeFor(t)));
}
}
}

class Encoding {
private final DeclaringType type;
private Object impl;

Encoding(DeclaringType type) {
this.type = type;
if (type.element().getKind() != ElementKind.CLASS || !type.isTopLevel()) {
type.report().error("Encoding type '%s' should be top-level class", type.simpleName());
}
if (type.sourceCode().length() == 0) {
reporter.error("No source code can be extracted @Encoding. Probably, compilation mode is not supported");
}

for (Element e : type.element().getEnclosedElements()) {
processMember(e);
}
}

private void processMember(Element member) {
if (member.getKind() == ElementKind.FIELD) {
if (processField((VariableElement) member))
return;
}
if (member.getKind() == ElementKind.METHOD) {
if (processMethod((ExecutableElement) member))
return;
}
if (member.getKind() == ElementKind.CLASS) {
if (processClass((TypeElement) member))
return;
}

reporter.withElement(member)
.warning("Unrecognized element '%s' will be ignored", member.getSimpleName());
}

private boolean processMethod(ExecutableElement method) {
return false;
}

private boolean processField(VariableElement field) {
if (ImplMirror.isPresent(field)) {
if (impl != null) {
reporter.withElement(field).error(
"@Encoding.Impl duplicate field '%s' cannot have more than one implementation field",
field.getSimpleName());
return true;
}
if (field.getModifiers().contains(Modifier.STATIC)) {
reporter.withElement(field).error(
"@Encoding.Impl field '%s' cannot be static",
field.getSimpleName());
return true;
}
}
return false;
}

private boolean processClass(TypeElement type) {
if (type.getSimpleName().contentEquals("Builder")) {

}
return false;
}
}

class Impl {
Impl() {

}
}
@Generator.Typedef
Encoding Encoding;

public abstract Templates.Invokable generate();

final Reporter reporter = Reporter.from(processing());
final List<Encoding> encodings = new ArrayList<>();

Encodings() {
for (TypeElement a : annotations()) {
for (TypeElement t : ElementFilter.typesIn(round().getElementsAnnotatedWith(a))) {
encodings.add(new Encoding(t));
}
}
}

class Encoding {
private final CharSequence source;

private Object impl;

Encoding(TypeElement type) {
if (type.getKind() != ElementKind.CLASS || type.getNestingKind() != NestingKind.TOP_LEVEL) {
reporter.withElement(type).error("Encoding type '%s' should be top-level class", type.getSimpleName());
}
source = SourceExtraction.extract(processing(), type);
if (source.length() == 0) {
reporter.withElement(type)
.error("No source code can be extracted @Encoding. Probably, compilation mode is not supported");
}

for (Element e : type.getEnclosedElements()) {
processMember(e);
}
}

private void processMember(Element member) {
if (member.getKind() == ElementKind.FIELD) {
if (processField((VariableElement) member))
return;
}
if (member.getKind() == ElementKind.METHOD) {
if (processMethod((ExecutableElement) member))
return;
}
if (member.getKind() == ElementKind.CLASS) {
if (processClass((TypeElement) member))
return;
}

reporter.withElement(member)
.warning("Unrecognized element '%s' will be ignored", member.getSimpleName());
}

private boolean processMethod(ExecutableElement method) {
return false;
}

private boolean processField(VariableElement field) {
if (ImplMirror.isPresent(field)) {
if (impl != null) {
reporter.withElement(field).error(
"@Encoding.Impl duplicate field '%s' cannot have more than one implementation field",
field.getSimpleName());
return true;
}
if (field.getModifiers().contains(Modifier.STATIC)) {
reporter.withElement(field).error(
"@Encoding.Impl field '%s' cannot be static",
field.getSimpleName());
return true;
}
}
return false;
}

private boolean processClass(TypeElement type) {
if (type.getSimpleName().contentEquals("Builder")) {

}
return false;
}
}

class Impl {
Impl() {

}
}
}
33 changes: 33 additions & 0 deletions value-processor/src/org/immutables/value/processor/encode/Eq.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package org.immutables.value.processor.encode;

import java.util.Objects;

public abstract class Eq<Q extends Eq<Q>> {
private final int hash;

protected Eq(Object... hash) {
this.hash = Objects.hash(hash);
}

protected abstract boolean eq(Q other);

@SuppressWarnings("unchecked")
@Override
public final boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() == obj.getClass()) {
return eq((Q) obj);
}
return false;
}

@Override
public final int hashCode() {
return hash;
}
}
Loading

0 comments on commit 0c5e9fa

Please sign in to comment.