Skip to content

Commit

Permalink
add support of code generation for array types
Browse files Browse the repository at this point in the history
  • Loading branch information
kalaninja committed May 10, 2022
1 parent 942bf3c commit 61c3e09
Show file tree
Hide file tree
Showing 17 changed files with 218 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ public boolean isAssignable(@NonNull TypeMirror candidate, @NonNull TypeMirror s
public boolean isSubtype(@NonNull TypeMirror candidate, @NonNull TypeMirror supertype) {
return typeUtils.isSubtype(candidate, supertype);
}

public boolean isGeneric(@NonNull TypeMirror type) {
return ((TypeElement) typeUtils.asElement(type))
.getTypeParameters()
.size() > 0;
return !(type.getKind().isPrimitive() ||
((TypeElement) typeUtils.asElement(type))
.getTypeParameters()
.size() == 0);
}

public TypeMirror erasure(@NonNull TypeMirror type) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.strategyobject.substrateclient.common.codegen;

import javax.lang.model.type.TypeMirror;

public class TypeNotSupportedException extends IllegalArgumentException {
public TypeNotSupportedException(TypeMirror type) {
super("Type is not supported: " + type);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public TypeTraverser(Class<T> clazz) {

protected abstract T whenPrimitiveType(@NonNull PrimitiveType type, TypeMirror override);

protected abstract T whenArrayNonGenericType(@NonNull ArrayType type, TypeMirror override);

protected abstract T whenNonGenericType(@NonNull DeclaredType type, TypeMirror override);

protected abstract T whenGenericType(@NonNull DeclaredType type, TypeMirror override, @NonNull T[] subtypes);
Expand All @@ -40,8 +42,12 @@ public T traverse(@NonNull TypeMirror type) {
return whenPrimitiveType((PrimitiveType) type, null);
}

if (type instanceof ArrayType) {
return whenArrayNonGenericType((ArrayType) type, null);
}

if (!(type instanceof DeclaredType)) {
throw new IllegalArgumentException("Type is not supported: " + type);
throw new TypeNotSupportedException(type);
}

val declaredType = (DeclaredType) type;
Expand All @@ -54,6 +60,7 @@ public T traverse(@NonNull TypeMirror type) {
typeArguments.stream()
.map(this::traverse)
.toArray(x -> (T[]) Array.newInstance(clazz, typeArguments.size())));

}

@SuppressWarnings({"unchecked", "UnstableApiUsage"})
Expand All @@ -66,8 +73,12 @@ public T traverse(@NonNull TypeMirror type, @NonNull TypeTraverser.TypeTreeNode
return whenPrimitiveType((PrimitiveType) type, typeOverride.type);
}

if (type instanceof ArrayType) {
return whenArrayNonGenericType((ArrayType) type, typeOverride.type);
}

if (!(type instanceof DeclaredType)) {
throw new IllegalArgumentException("Type is not supported: " + type);
throw new TypeNotSupportedException(type);
}

val declaredType = (DeclaredType) type;
Expand Down Expand Up @@ -107,8 +118,12 @@ public T traverse(@NonNull TypeTraverser.TypeTreeNode typeOverride) {
return whenPrimitiveType((PrimitiveType) typeOverride.type, typeOverride.type);
}

if (typeOverride.type instanceof ArrayType) {
return whenArrayNonGenericType((ArrayType) typeOverride.type, typeOverride.type);
}

if (!(typeOverride.type instanceof DeclaredType)) {
throw new IllegalArgumentException("Type is not supported: " + typeOverride.type);
throw new TypeNotSupportedException(typeOverride.type);
}

val declaredType = (DeclaredType) typeOverride.type;
Expand Down Expand Up @@ -146,7 +161,6 @@ private boolean typeIsOverriddenByNonGeneric(int typeOverrideSize) {
return typeOverrideSize == 0;
}


public static class TypeTreeNode {
@Getter
private final TypeMirror type;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.strategyobject.substrateclient.rpc.codegen.decoder;

import com.squareup.javapoet.CodeBlock;
import com.strategyobject.substrateclient.common.codegen.ProcessorContext;
import com.strategyobject.substrateclient.common.codegen.TypeNotSupportedException;
import com.strategyobject.substrateclient.common.codegen.TypeTraverser;
import com.strategyobject.substrateclient.rpc.core.DecoderPair;
import com.strategyobject.substrateclient.rpc.core.RpcDecoder;
Expand All @@ -10,34 +12,30 @@
import lombok.NonNull;
import lombok.var;

import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.util.Types;
import javax.lang.model.type.*;
import java.util.Map;

import static com.strategyobject.substrateclient.rpc.codegen.Constants.PAIR_FACTORY_METHOD;
import static com.strategyobject.substrateclient.rpc.codegen.Constants.RESOLVE_AND_INJECT_METHOD;

public class DecoderCompositor extends TypeTraverser<CodeBlock> {
private final Types typeUtils;
private final ProcessorContext context;
private final Map<String, Integer> typeVarMap;
private final String decoderAccessor;
private final String readerAccessor;
private final String readerMethod;
private final String decoderRegistryVarName;
private final String scaleRegistryVarName;

public DecoderCompositor(@NonNull Types typeUtils,
public DecoderCompositor(@NonNull ProcessorContext context,
@NonNull Map<String, Integer> typeVarMap,
@NonNull String decoderAccessor,
@NonNull String readerAccessor,
@NonNull String readerMethod,
@NonNull String decoderRegistryVarName,
@NonNull String scaleRegistryVarName) {
super(CodeBlock.class);
this.typeUtils = typeUtils;
this.context = context;
this.typeVarMap = typeVarMap;
this.decoderAccessor = decoderAccessor;
this.readerAccessor = readerAccessor;
Expand All @@ -62,6 +60,15 @@ protected CodeBlock whenPrimitiveType(@NonNull PrimitiveType type, TypeMirror _o
return getNonGenericCodeBlock(type);
}

@Override
protected CodeBlock whenArrayNonGenericType(@NonNull ArrayType type, TypeMirror _override) {
if (context.isGeneric(type.getComponentType())) {
throw new TypeNotSupportedException(type);
}

return getNonGenericCodeBlock(type);
}

@Override
protected CodeBlock whenNonGenericType(@NonNull DeclaredType type, TypeMirror _override) {
return getNonGenericCodeBlock(type);
Expand All @@ -79,7 +86,7 @@ private CodeBlock getNonGenericCodeBlock(TypeMirror type) {

@Override
protected CodeBlock whenGenericType(@NonNull DeclaredType type, TypeMirror _override, @NonNull CodeBlock[] subtypes) {
TypeMirror resolveType = typeUtils.erasure(type);
TypeMirror resolveType = context.erasure(type);

var builder = CodeBlock.builder()
.add("$T.$L(", DecoderPair.class, PAIR_FACTORY_METHOD)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ private void addMethodBody(MethodSpec.Builder methodSpec, ProcessorContext conte
}

private void setFields(MethodSpec.Builder methodSpec, ProcessorContext context) throws ProcessingException {
val decoderCompositor = new DecoderCompositor(context.getTypeUtils(),
val decoderCompositor = new DecoderCompositor(
context,
typeVarMap,
String.format("%s[$L].%s", DECODERS_ARG, DECODER_UNSAFE_ACCESSOR),
String.format("%s[$L].%s", DECODERS_ARG, READER_UNSAFE_ACCESSOR),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.squareup.javapoet.CodeBlock;
import com.strategyobject.substrateclient.common.codegen.ProcessorContext;
import com.strategyobject.substrateclient.common.codegen.TypeNotSupportedException;
import com.strategyobject.substrateclient.common.codegen.TypeTraverser;
import com.strategyobject.substrateclient.rpc.core.EncoderPair;
import com.strategyobject.substrateclient.rpc.core.RpcEncoder;
Expand All @@ -12,10 +13,7 @@
import lombok.val;
import lombok.var;

import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.type.*;
import java.util.Map;

import static com.strategyobject.substrateclient.rpc.codegen.Constants.*;
Expand Down Expand Up @@ -70,6 +68,15 @@ protected CodeBlock whenPrimitiveType(@NonNull PrimitiveType type, TypeMirror _o
return getNonGenericCodeBlock(type);
}

@Override
protected CodeBlock whenArrayNonGenericType(@NonNull ArrayType type, TypeMirror _override) {
if (context.isGeneric(type.getComponentType())) {
throw new TypeNotSupportedException(type);
}

return getNonGenericCodeBlock(type);
}

@Override
protected CodeBlock whenNonGenericType(@NonNull DeclaredType type, TypeMirror _override) {
return getNonGenericCodeBlock(type);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@ private CodeBlock getDecodeCodeBlock(AnnotatedConstruct annotated,
}

private CodeBlock getRpcDecodeCodeBlock(TypeMirror resultType, String arg, ProcessorContext context) {
val decoderCompositor = new DecoderCompositor(context.getTypeUtils(),
val decoderCompositor = new DecoderCompositor(
context,
EMPTY_TYPE_VAR_MAP,
String.format("%s[$L].%s", DECODERS_ARG, DECODER_UNSAFE_ACCESSOR),
String.format("%s[$L].%s", DECODERS_ARG, READER_UNSAFE_ACCESSOR),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
import com.google.common.base.Strings;
import com.squareup.javapoet.CodeBlock;
import com.strategyobject.substrateclient.common.codegen.ProcessorContext;
import com.strategyobject.substrateclient.common.codegen.TypeNotSupportedException;
import com.strategyobject.substrateclient.common.codegen.TypeTraverser;
import lombok.NonNull;
import lombok.var;

import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.type.*;
import java.util.Map;

public class ReaderCompositor extends TypeTraverser<CodeBlock> {
Expand Down Expand Up @@ -59,6 +57,15 @@ protected CodeBlock whenPrimitiveType(@NonNull PrimitiveType type, TypeMirror ov
return getNonGenericCodeBlock(type, override);
}

@Override
protected CodeBlock whenArrayNonGenericType(@NonNull ArrayType type, TypeMirror override) {
if (context.isGeneric(type.getComponentType())) {
throw new TypeNotSupportedException(type);
}

return getNonGenericCodeBlock(type, override);
}

@Override
protected CodeBlock whenNonGenericType(@NonNull DeclaredType type, TypeMirror override) {
return getNonGenericCodeBlock(type, override);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@

import com.squareup.javapoet.CodeBlock;
import com.strategyobject.substrateclient.common.codegen.ProcessorContext;
import com.strategyobject.substrateclient.common.codegen.TypeNotSupportedException;
import com.strategyobject.substrateclient.common.codegen.TypeTraverser;
import lombok.NonNull;
import lombok.var;

import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.PrimitiveType;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.type.TypeVariable;
import javax.lang.model.type.*;
import java.util.Map;

import static com.strategyobject.substrateclient.scale.codegen.ScaleProcessorHelper.SCALE_SELF_WRITABLE;
Expand Down Expand Up @@ -62,6 +60,15 @@ protected CodeBlock whenPrimitiveType(@NonNull PrimitiveType type, TypeMirror ov
return getNonGenericCodeBlock(type, override);
}

@Override
protected CodeBlock whenArrayNonGenericType(@NonNull ArrayType type, TypeMirror override) {
if (context.isGeneric(type.getComponentType())) {
throw new TypeNotSupportedException(type);
}

return getNonGenericCodeBlock(type, override);
}

@Override
protected CodeBlock whenNonGenericType(@NonNull DeclaredType type, TypeMirror override) {
return getNonGenericCodeBlock(type, override);
Expand Down
12 changes: 11 additions & 1 deletion scale/scale-codegen/src/test/resources/Annotated.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ public class Annotated<T1, T2, T3> {
@Scale(OptionBool.class)
private Optional<Boolean> testOptionBool;


@ScaleGeneric(
template = "Option<I32>",
types = {
Expand Down Expand Up @@ -110,6 +109,9 @@ public class Annotated<T1, T2, T3> {
@Scale
private NestedClass<T2> testNestedField;

@Scale(byte[].class)
private byte[] testByteArray;

public Boolean getTestBool() {
return testBool;
}
Expand Down Expand Up @@ -297,4 +299,12 @@ public void setTestNestedField(NestedClass<T2> testNestedField) {
public static class NestedClass<T> {
public T nestedField;
}

public byte[] getTestByteArray() {
return testByteArray;
}

public void setTestByteArray(byte[] testByteArray) {
this.testByteArray = testByteArray;
}
}
10 changes: 10 additions & 0 deletions scale/scale-codegen/src/test/resources/NonAnnotated.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public class NonAnnotated<T1, T2, T3> {

private NestedClass<T2> testNestedField;

private byte[] testByteArray;

public Boolean getTestBool() {
return testBool;
}
Expand Down Expand Up @@ -134,4 +136,12 @@ public void setTestNestedField(NestedClass<T2> testNestedField) {
public static class NestedClass<T> {
public T nestedField;
}

public byte[] getTestByteArray() {
return testByteArray;
}

public void setTestByteArray(byte[] testByteArray) {
this.testByteArray = testByteArray;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.strategyobject.substrateclient.scale.readers;

import com.google.common.base.Preconditions;
import com.strategyobject.substrateclient.common.io.Streamer;
import com.strategyobject.substrateclient.scale.ScaleReader;
import lombok.NonNull;
import lombok.val;

import java.io.IOException;
import java.io.InputStream;

public class ByteArrayReader implements ScaleReader<byte[]> {
@Override
public byte[] read(@NonNull InputStream stream, ScaleReader<?>... readers) throws IOException {
Preconditions.checkArgument(readers == null || readers.length == 0);

val len = CompactIntegerReader.readInternal(stream);
return Streamer.readBytes(len, stream);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public final class ScaleReaderRegistry {
private final Map<Class<?>, ScaleReader<?>> readers;

private ScaleReaderRegistry() {
readers = new ConcurrentHashMap<>(34);
readers = new ConcurrentHashMap<>(32);

register(new BoolReader(), ScaleType.Bool.class, Boolean.class, boolean.class);
register(new CompactBigIntegerReader(), ScaleType.CompactBigInteger.class);
Expand Down Expand Up @@ -59,6 +59,7 @@ private ScaleReaderRegistry() {
register(new Union12Reader(), Union12.class, ScaleType.Union12.class);
register(new VecReader(), ScaleType.Vec.class, List.class);
register(new VoidReader(), Void.class);
register(new ByteArrayReader(), byte[].class);

registerAnnotatedFrom(ROOT_PREFIX);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ private ScaleWriterRegistry() {
register(new SelfWriter(), ScaleSelfWritable.class);
register(new PublicKeyWriter(), PublicKey.class);
register(new SignatureDataWriter(), SignatureData.class);
register(new ByteArrayWriter(), byte[].class);

registerAnnotatedFrom(ROOT_PREFIX);
}
Expand Down
Loading

0 comments on commit 61c3e09

Please sign in to comment.