You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Should be able to deserialise a map that uses abstract types as values.
Current Behavior
Error: Cannot instantiate the abstract type "Animal" in the "[email protected]" namespace.
at Factory.newResource (/home/runner/AccordProjectConcerto-Polymorphic-Maps/node_modules/@accordproject/concerto-core/lib/factory.js:96:19)
at Factory.newConcept (/home/runner/AccordProjectConcerto-Polymorphic-Maps/node_modules/@accordproject/concerto-core/lib/factory.js:177:21)
at JSONPopulator.processMapType (/home/runner/AccordProjectConcerto-Polymorphic-Maps/node_modules/@accordproject/concerto-core/lib/serializer/jsonpopulator.js:220:50)
at /home/runner/AccordProjectConcerto-Polymorphic-Maps/node_modules/@accordproject/concerto-core/lib/serializer/jsonpopulator.js:195:30
at Map.forEach (<anonymous>)
at JSONPopulator.visitMapDeclaration (/home/runner/AccordProjectConcerto-Polymorphic-Maps/node_modules/@accordproject/concerto-core/lib/serializer/jsonpopulator.js:183:17)
at JSONPopulator.visit (/home/runner/AccordProjectConcerto-Polymorphic-Maps/node_modules/@accordproject/concerto-core/lib/serializer/jsonpopulator.js:125:25)
at MapDeclaration.accept (/home/runner/AccordProjectConcerto-Polymorphic-Maps/node_modules/@accordproject/concerto-core/lib/introspect/decorated.js:70:24)
at JSONPopulator.convertItem (/home/runner/AccordProjectConcerto-Polymorphic-Maps/node_modules/@accordproject/concerto-core/lib/serializer/jsonpopulator.js:297:34)
Possible Solution
I think the bug is in processMapType. We are calling newConcept with the name of the map value type, whereas we should be using the $class in value, and we should check that value is assignable to map value.
E.g. see this code in ResourceValidator:
// is it compatible?
if(!ModelUtil.isAssignableTo(classDeclaration.getModelFile(), classDeclaration.getFullyQualifiedName(), field)) {
ResourceValidator.reportInvalidFieldAssignment(parameters.rootResourceIdentifier, propName, obj, field);
}
processMapType(mapDeclaration, parameters, value, type) {
let decl = mapDeclaration.getModelFile()
.getAllDeclarations()
.find(decl => decl.name === type);
// if its a ClassDeclaration, populate the Concept.
if (decl?.isClassDeclaration()) {
let subResource = parameters.factory.newConcept(decl.getNamespace(),
decl.getName(), decl.getIdentifierFieldName() );
parameters.jsonStack.push(value);
parameters.resourceStack.push(subResource);
return decl.accept(this, parameters);
}
// otherwise its a scalar value, we only need to return the primitve value of the scalar.
return value;
}
Bug Report 🐛
Possibly an enhancement?
Today I tried to use a map with an abstract type as the value:
Code:
Expected Behavior
Should be able to deserialise a map that uses abstract types as values.
Current Behavior
Possible Solution
I think the bug is in processMapType. We are calling
newConcept
with the name of the map value type, whereas we should be using the $class invalue
, and we should check thatvalue
is assignable to map value.E.g. see this code in ResourceValidator:
Steps to Reproduce
Context (Environment)
Concerto v3.14.2
Detailed Description
Possible Implementation
The text was updated successfully, but these errors were encountered: