Skip to content

Commit

Permalink
codegen: Create models for representing anonymous implementations (#434)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pyknic authored and minborg committed May 12, 2017
1 parent a231858 commit 87a5075
Show file tree
Hide file tree
Showing 12 changed files with 234 additions and 35 deletions.
Expand Up @@ -110,6 +110,4 @@ public boolean equals(Object obj) {
} }
return Objects.equals(this.constructors, other.constructors); return Objects.equals(this.constructors, other.constructors);
} }


} }
@@ -0,0 +1,83 @@
package com.speedment.common.codegen.internal.model.value;

import com.speedment.common.codegen.internal.util.Copier;
import com.speedment.common.codegen.model.ClassOrInterface;
import com.speedment.common.codegen.model.Generic;
import com.speedment.common.codegen.model.Value;
import com.speedment.common.codegen.model.trait.HasCopy;
import com.speedment.common.codegen.model.value.AnonymousValue;

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

/**
* Default implementation of the {@link AnonymousValue} interface.
*
* @author Emil Forslund
* @since 2.4.6
*/
public final class AnonymousValueImpl<T extends ClassOrInterface<T>>
implements AnonymousValue<T> {

private final List<Value<?>> args;
private final List<Generic> generics;
private T classOrInterface;

public AnonymousValueImpl() {
this.args = new ArrayList<>();
this.generics = new ArrayList<>();
}

private AnonymousValueImpl(AnonymousValue<T> prototype) {
this.args = Copier.copy(prototype.getValues(), HasCopy::copy);
this.generics = Copier.copy(prototype.getGenerics());
this.classOrInterface = Copier.copy(prototype.getValue());
}

@Override
public List<Value<?>> getValues() {
return args;
}

@Override
public List<Generic> getGenerics() {
return generics;
}

@Override
public T getValue() {
return classOrInterface;
}

@Override
public AnonymousValue<T> setValue(T value) {
classOrInterface = value;
return this;
}

@Override
public Value<T> copy() {
return new AnonymousValueImpl<>(this);
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof AnonymousValue)) return false;

final AnonymousValue<?> that = (AnonymousValue<?>) o;
if (!args.equals(that.getValues())) return false;
else if (!getGenerics().equals(that.getGenerics())) return false;
return classOrInterface != null
? classOrInterface.equals(that.getValue())
: that.getValue() == null;
}

@Override
public int hashCode() {
int result = args.hashCode();
result = 31 * result + getGenerics().hashCode();
result = 31 * result + (classOrInterface != null ? classOrInterface.hashCode() : 0);
return result;
}
}
Expand Up @@ -16,10 +16,23 @@
*/ */
package com.speedment.common.codegen.model; package com.speedment.common.codegen.model;



import com.speedment.common.codegen.internal.model.value.AnonymousValueImpl;
import com.speedment.common.codegen.internal.model.value.*; import com.speedment.common.codegen.internal.model.value.ArrayValueImpl;
import com.speedment.common.codegen.internal.model.value.BooleanValueImpl;
import com.speedment.common.codegen.internal.model.value.EnumValueImpl;
import com.speedment.common.codegen.internal.model.value.NullValueImpl;
import com.speedment.common.codegen.internal.model.value.NumberValueImpl;
import com.speedment.common.codegen.internal.model.value.ReferenceValueImpl;
import com.speedment.common.codegen.internal.model.value.TextValueImpl;
import com.speedment.common.codegen.model.trait.HasCopy; import com.speedment.common.codegen.model.trait.HasCopy;
import com.speedment.common.codegen.model.value.*; import com.speedment.common.codegen.model.value.AnonymousValue;
import com.speedment.common.codegen.model.value.ArrayValue;
import com.speedment.common.codegen.model.value.BooleanValue;
import com.speedment.common.codegen.model.value.EnumValue;
import com.speedment.common.codegen.model.value.NullValue;
import com.speedment.common.codegen.model.value.NumberValue;
import com.speedment.common.codegen.model.value.ReferenceValue;
import com.speedment.common.codegen.model.value.TextValue;


import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.List; import java.util.List;
Expand Down Expand Up @@ -47,41 +60,96 @@ public interface Value<V> extends HasCopy<Value<V>> {
* @return the inner value * @return the inner value
*/ */
V getValue(); V getValue();


/**
* Returns a new {@link ArrayValue} with no values set.
*
* @return an {@code ArrayValue}
*/
static ArrayValue ofArray() { static ArrayValue ofArray() {
return new ArrayValueImpl(); return new ArrayValueImpl();
} }


/**
* Returns a new {@link ArrayValue} with the specified values set.
*
* @return an {@code ArrayValue}
*/
static ArrayValue ofArray(List<Value<?>> arrayValue) { static ArrayValue ofArray(List<Value<?>> arrayValue) {
return new ArrayValueImpl(arrayValue); return new ArrayValueImpl(arrayValue);
} }


/**
* Returns a new {@link BooleanValue} with the specified value.
*
* @param val the boolean
* @return the boolean value
*/
static BooleanValue ofBoolean(Boolean val) { static BooleanValue ofBoolean(Boolean val) {
return new BooleanValueImpl(val); return new BooleanValueImpl(val);
} }


static EnumValue ofEnum(Type type, String value) { /**
return new EnumValueImpl(type, value); * Returns a new {@link EnumValue} with the specified constant selected.
*
* @param type the enum type
* @param constant the selected constant
* @return the boolean value
*/
static EnumValue ofEnum(Type type, String constant) {
return new EnumValueImpl(type, constant);
} }


// static EnumValue ofEnum(EnumValue prototype) { /**
// return new EnumValueImpl(prototype); * Returns a new {@code NullValue} representing {@code null}.
// } *

* @return a {@code NullValue}
*/
static NullValue ofNull() { static NullValue ofNull() {
return new NullValueImpl(); return new NullValueImpl();
} }


/**
* Returns a new {@link NumberValue}.
*
* @param num the represented number
* @return the created number value
*/
static NumberValue ofNumber(Number num) { static NumberValue ofNumber(Number num) {
return new NumberValueImpl(num); return new NumberValueImpl(num);
} }


/**
* Returns a new {@link ReferenceValue} representing a reference to an
* object.
*
* @param reference the code to show
* @return the reference value
*/
static ReferenceValue ofReference(String reference) { static ReferenceValue ofReference(String reference) {
return new ReferenceValueImpl(reference); return new ReferenceValueImpl(reference);
} }


/**
* Returns a new {@link TextValue} representing a string text.
*
* @param text the text
* @return the text value
*/
static TextValue ofText(String text) { static TextValue ofText(String text) {
return new TextValueImpl(text); return new TextValueImpl(text);
} }


/**
* Returns a new {@link AnonymousValue} representing the anonymous
* implementation of a class or interface as the value of a field.
*
* @param classOrInterface the class or interface to implement
* @param <T> the type (class, interface, enum etc)
* @return the anonymous value
*/
static <T extends ClassOrInterface<T>> AnonymousValue<T> ofAnonymous(T classOrInterface) {
return new AnonymousValueImpl<T>()
.setValue(classOrInterface);
}
} }
@@ -0,0 +1,37 @@
package com.speedment.common.codegen.model.trait;

import com.speedment.common.codegen.model.Value;

import java.util.List;

/**
* Trait representing a type that has multiple {@link Value values}, like a
* method or constructor invocation.
*
* @author Emil Forslund
* @since 2.4.6
*/
public interface HasValues<T extends HasValues<T>> {

/**
* Adds the specified {@link Value} to this model.
*
* @param generic the new child
* @return a reference to this
*/
@SuppressWarnings("unchecked")
default <E> T add(final Value<E> generic) {
getValues().add(generic);
return (T) this;
}

/**
* Returns a list of all the values in this model.
* <p>
* The list returned must be mutable for changes!
*
* @return the values
*/
List<Value<?>> getValues();

}
@@ -0,0 +1,22 @@
package com.speedment.common.codegen.model.value;

import com.speedment.common.codegen.model.ClassOrInterface;
import com.speedment.common.codegen.model.Value;
import com.speedment.common.codegen.model.trait.HasGenerics;
import com.speedment.common.codegen.model.trait.HasValues;

/**
* A value representing a reference to an abstract implementation used
* anonymously to set a field.
*
* @author Emil Forslund
* @since 2.4.6
*/
public interface AnonymousValue<T extends ClassOrInterface<T>>
extends Value<T>,
HasGenerics<AnonymousValue<T>>,
HasValues<AnonymousValue<T>> {

@Override
AnonymousValue<T> setValue(T value);
}
Expand Up @@ -24,5 +24,4 @@
* *
* @author Emil Forslund * @author Emil Forslund
*/ */
public interface ArrayValue extends Value<List<Value<?>>> { public interface ArrayValue extends Value<List<Value<?>>> {}
}
Expand Up @@ -22,5 +22,4 @@
* *
* @author Emil Forslund * @author Emil Forslund
*/ */
public interface BooleanValue extends Value<Boolean> { public interface BooleanValue extends Value<Boolean> {}
}
Expand Up @@ -23,5 +23,4 @@
* *
* @author Emil Forslund * @author Emil Forslund
*/ */
public interface EnumValue extends Value<String>, HasType<EnumValue> { public interface EnumValue extends Value<String>, HasType<EnumValue> {}
}
Expand Up @@ -18,10 +18,8 @@


import com.speedment.common.codegen.model.Value; import com.speedment.common.codegen.model.Value;



/** /**
* *
* @author Emil Forslund * @author Emil Forslund
*/ */
public interface NullValue extends Value<Number> { public interface NullValue extends Value<Number> {}
}
Expand Up @@ -22,5 +22,4 @@
* *
* @author Emil Forslund * @author Emil Forslund
*/ */
public interface NumberValue extends Value<Number> { public interface NumberValue extends Value<Number> {}
}
Expand Up @@ -22,6 +22,4 @@
* *
* @author Emil Forslund * @author Emil Forslund
*/ */
public interface ReferenceValue extends Value<String> { public interface ReferenceValue extends Value<String> {}

}
Expand Up @@ -22,5 +22,4 @@
* *
* @author Emil Forslund * @author Emil Forslund
*/ */
public interface TextValue extends Value<String> { public interface TextValue extends Value<String> {}
}

0 comments on commit 87a5075

Please sign in to comment.