Skip to content

Commit

Permalink
Added JSON representation for constructor signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
spoto committed Jan 17, 2024
1 parent 95d3a8a commit 30c089f
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
import io.hotmoka.beans.api.signatures.ConstructorSignature;
import io.hotmoka.beans.api.types.ClassType;
import io.hotmoka.beans.api.types.StorageType;
import io.hotmoka.beans.internal.gson.ConstructorSignatureDecoder;
import io.hotmoka.beans.internal.gson.ConstructorSignatureEncoder;
import io.hotmoka.beans.internal.gson.ConstructorSignatureJson;
import io.hotmoka.beans.internal.signatures.ConstructorSignatureImpl;
import io.hotmoka.marshalling.api.UnmarshallingContext;

Expand Down Expand Up @@ -65,6 +68,43 @@ public static ConstructorSignature from(UnmarshallingContext context) throws IOE
}

/**
* Gson encoder.
*/
public static class Encoder extends ConstructorSignatureEncoder {

/**
* Creates a new encoder.
*/
public Encoder() {}
}

/**
* Gson decoder.
*/
public static class Decoder extends ConstructorSignatureDecoder {

/**
* Creates a new decoder.
*/
public Decoder() {}
}

/**
* Json representation.
*/
public static class Json extends ConstructorSignatureJson {

/**
* Creates the Json representation for the given constructor signature.
*
* @param constructor the constructor signature
*/
public Json(ConstructorSignature constructor) {
super(constructor);
}
}

/**
* The constructor of an externally owned account.
*/
public final static ConstructorSignature EOA_CONSTRUCTOR = ConstructorSignatureImpl.EOA_CONSTRUCTOR;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ public static MethodSignature from(UnmarshallingContext context) throws IOExcept
/**
* The method {@code get} of the account ledger.
*/
public final static NonVoidMethodSignature GET_FROM_ACCOUNTS_LEDGER = AbstractMethodSignature.GET_FROM_ACCOUNTS_LEDGER; // TODO: check name
public final static NonVoidMethodSignature GET_FROM_ACCOUNTS_LEDGER = AbstractMethodSignature.GET_FROM_ACCOUNTS_LEDGER;

/**
* The method {@code getGasPrice} of the gas station.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
Copyright 2024 Fausto Spoto
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.hotmoka.beans.internal.gson;

import io.hotmoka.beans.ConstructorSignatures;
import io.hotmoka.beans.api.signatures.ConstructorSignature;
import io.hotmoka.websockets.beans.MappedDecoder;

/**
* A decoder for {@link ConstructorSignature}.
*/
public class ConstructorSignatureDecoder extends MappedDecoder<ConstructorSignature, ConstructorSignatures.Json> {

public ConstructorSignatureDecoder() {
super(ConstructorSignatures.Json.class);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
Copyright 2024 Fausto Spoto
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.hotmoka.beans.internal.gson;

import io.hotmoka.beans.ConstructorSignatures;
import io.hotmoka.beans.api.signatures.ConstructorSignature;
import io.hotmoka.websockets.beans.MappedEncoder;

/**
* An encoder for {@link ConstructorSignature}.
*/
public class ConstructorSignatureEncoder extends MappedEncoder<ConstructorSignature, ConstructorSignatures.Json> {

public ConstructorSignatureEncoder() {
super(ConstructorSignatures.Json::new);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
Copyright 2024 Fausto Spoto
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.hotmoka.beans.internal.gson;

import java.util.stream.Stream;

import io.hotmoka.beans.ConstructorSignatures;
import io.hotmoka.beans.StorageTypes;
import io.hotmoka.beans.api.signatures.ConstructorSignature;
import io.hotmoka.beans.api.types.StorageType;
import io.hotmoka.websockets.beans.api.JsonRepresentation;

/**
* The JSON representation of a {@link ConstructorSignature}.
*/
public abstract class ConstructorSignatureJson implements JsonRepresentation<ConstructorSignature> {
private final String definingClass;
private final String[] formals;

protected ConstructorSignatureJson(ConstructorSignature constructor) {
this.definingClass = constructor.getDefiningClass().getName();
this.formals = constructor.getFormals().map(StorageType::getName).toArray(String[]::new);
}

@Override
public ConstructorSignature unmap() {
return ConstructorSignatures.of(StorageTypes.classNamed(definingClass), Stream.of(formals).map(StorageTypes::named).toArray(StorageType[]::new));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import io.hotmoka.beans.FieldSignatures;
import io.hotmoka.beans.StorageTypes;
import io.hotmoka.beans.api.signatures.FieldSignature;
import io.hotmoka.beans.api.types.ClassType;
import io.hotmoka.websockets.beans.api.JsonRepresentation;

/**
Expand All @@ -38,7 +37,6 @@ protected FieldSignatureJson(FieldSignature field) {

@Override
public FieldSignature unmap() {
// this cast might actually fail if the JSON is inconsistent
return FieldSignatures.of((ClassType) StorageTypes.named(definingClass), name, StorageTypes.named(type));
return FieldSignatures.of(StorageTypes.classNamed(definingClass), name, StorageTypes.named(type));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,10 @@ protected final String commaSeparatedFormals() {

@Override
public boolean equals(Object other) {
return other instanceof CodeSignature cs && cs.getDefiningClass().equals(definingClass) && Arrays.equals(cs.getFormals().toArray(StorageType[]::new), formals); // TODO: optimize
if (other instanceof AbstractCodeSignature acs)
return acs.definingClass.equals(definingClass) && Arrays.equals(acs.formals, formals); // optimization
else
return other instanceof CodeSignature cs && cs.getDefiningClass().equals(definingClass) && Arrays.equals(cs.getFormals().toArray(StorageType[]::new), formals);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,14 @@ public void into(MarshallingContext context) throws IOException {
public static Update from(UnmarshallingContext context) throws IOException {
var selector = context.readByte();
switch (selector) {
// TODO: cast -> IOException
case ClassTag.SELECTOR: return new ClassTag(StorageReferenceImpl.fromWithoutSelector(context), (ClassType) StorageTypes.from(context), TransactionReferences.from(context));
case ClassTag.SELECTOR: {
try {
return new ClassTag(StorageReferenceImpl.fromWithoutSelector(context), (ClassType) StorageTypes.from(context), TransactionReferences.from(context));
}
catch (ClassCastException e) {
throw new IOException("Failed unmrshalling a class tag", e);
}
}
case UpdateOfBigInteger.SELECTOR_BALANCE: return new UpdateOfBigInteger(StorageReferenceImpl.fromWithoutSelector(context), FieldSignatures.BALANCE_FIELD, context.readBigInteger());
case UpdateOfBigInteger.SELECTOR_GAS_PRICE: return new UpdateOfBigInteger(StorageReferenceImpl.fromWithoutSelector(context), FieldSignatures.GENERIC_GAS_STATION_GAS_PRICE_FIELD, context.readBigInteger());
case UpdateOfBigInteger.SELECTOR_UBI_VALUE: return new UpdateOfBigInteger(StorageReferenceImpl.fromWithoutSelector(context), FieldSignatures.UNSIGNED_BIG_INTEGER_VALUE_FIELD, context.readBigInteger());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
Copyright 2024 Fausto Spoto
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.hotmoka.beans.tests;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import io.hotmoka.beans.ConstructorSignatures;
import io.hotmoka.beans.StorageTypes;
import io.hotmoka.testing.AbstractLoggedTests;
import jakarta.websocket.DecodeException;
import jakarta.websocket.EncodeException;

public class ConstructorSignatureTests extends AbstractLoggedTests {

@Test
@DisplayName("constructor signatures are correctly encoded into Json and decoded from Json")
public void encodeDecodeWorksForConstructorSignature() throws EncodeException, DecodeException {
var constructor1 = ConstructorSignatures.of("io.hotmoka.MyClass", StorageTypes.named("io.hotmoka.OtherClass"), StorageTypes.CHAR, StorageTypes.DOUBLE, StorageTypes.named("io.hotmoka.Something"));
String encoded = new ConstructorSignatures.Encoder().encode(constructor1);
var constructor2 = new ConstructorSignatures.Decoder().decode(encoded);
assertEquals(constructor1, constructor2);
}
}

0 comments on commit 30c089f

Please sign in to comment.