Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix model generation failure with defaultable record field #255

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

import io.ballerina.architecturemodelgenerator.core.ArchitectureModel.PackageId;
import io.ballerina.architecturemodelgenerator.core.Constants.CardinalityValue;
import io.ballerina.architecturemodelgenerator.core.diagnostics.ArchitectureModelDiagnostic;
import io.ballerina.architecturemodelgenerator.core.diagnostics.DiagnosticMessage;
import io.ballerina.architecturemodelgenerator.core.diagnostics.DiagnosticNode;
import io.ballerina.architecturemodelgenerator.core.generators.GeneratorUtils;
import io.ballerina.architecturemodelgenerator.core.generators.ModelGenerator;
import io.ballerina.architecturemodelgenerator.core.generators.entity.nodevisitors.TypeDefinitionNodeVisitor;
Expand All @@ -43,8 +46,11 @@
import io.ballerina.compiler.syntax.tree.BasicLiteralNode;
import io.ballerina.compiler.syntax.tree.IdentifierToken;
import io.ballerina.compiler.syntax.tree.MappingFieldNode;
import io.ballerina.compiler.syntax.tree.MetadataNode;
import io.ballerina.compiler.syntax.tree.Node;
import io.ballerina.compiler.syntax.tree.QualifiedNameReferenceNode;
import io.ballerina.compiler.syntax.tree.RecordFieldNode;
import io.ballerina.compiler.syntax.tree.RecordFieldWithDefaultValueNode;
import io.ballerina.compiler.syntax.tree.RecordTypeDescriptorNode;
import io.ballerina.compiler.syntax.tree.SpecificFieldNode;
import io.ballerina.compiler.syntax.tree.SyntaxKind;
Expand Down Expand Up @@ -118,21 +124,37 @@ private Entity getType(RecordTypeSymbol recordTypeSymbol, RecordTypeDescriptorNo
List<String> inclusionList = new ArrayList<>();
Map<String, RecordFieldSymbol> recordFieldSymbolMap =
getOriginalFieldMap(recordTypeSymbol, inclusionList, entityName);
List<ArchitectureModelDiagnostic> diagnostics = new ArrayList<>();
for (RecordFieldSymbol recordFieldSymbol : recordFieldSymbolMap.values()) {
RecordFieldNode recordFieldNode = null;
Node recordFieldNode = null;
if (recordFieldSymbol.getName().isPresent() && recordNode != null) {
recordFieldNode = (RecordFieldNode) recordNode.fields().stream().filter(node ->
node.kind().equals(SyntaxKind.RECORD_FIELD) &&
((RecordFieldNode) node).fieldName().text()
.equals(recordFieldSymbol.getName().get()))
.findFirst().orElse(null);
recordFieldNode = recordNode.fields().stream().filter(node -> {
if (node.kind().equals(SyntaxKind.RECORD_FIELD) &&
((RecordFieldNode) node).fieldName().text().equals(recordFieldSymbol.getName().get())) {
return true;
} else {
return node.kind().equals(SyntaxKind.RECORD_FIELD_WITH_DEFAULT_VALUE) &&
((RecordFieldWithDefaultValueNode) node).fieldName().text()
.equals(recordFieldSymbol.getName().get());
}
}).findFirst().orElse(null);
}

if (recordFieldNode == null) {
DiagnosticMessage message = DiagnosticMessage.failedToGenerate(DiagnosticNode.ENTITIES,
"Could not find the field named " + recordFieldSymbol.getName().get() + ".");
ArchitectureModelDiagnostic diagnostic = new ArchitectureModelDiagnostic(
message.getCode(), message.getDescription(), message.getSeverity(), null, null
);
diagnostics.add(diagnostic);
} else {
attributeList.add(getAttribute(recordFieldSymbol, recordFieldNode, entityName));
}
attributeList.add(getAttribute(recordFieldSymbol, recordFieldNode, entityName));
}
return new Entity(attributeList, inclusionList, isAnonymous, elementLocation, Collections.emptyList());
return new Entity(attributeList, inclusionList, isAnonymous, elementLocation, diagnostics);
}

private Attribute getAttribute(RecordFieldSymbol recordFieldSymbol, RecordFieldNode recordFieldNode,
private Attribute getAttribute(RecordFieldSymbol recordFieldSymbol, Node recordFieldNode,
String entityName) {
TypeDescKind fieldTypeDescKind = recordFieldSymbol.typeDescriptor().typeKind();
TypeSymbol fieldTypeSymbol = recordFieldSymbol.typeDescriptor();
Expand All @@ -145,12 +167,17 @@ private Attribute getAttribute(RecordFieldSymbol recordFieldSymbol, RecordFieldN
boolean nillable = isNillable(recordFieldSymbol.typeDescriptor());
String inlineRecordName = entityName + fieldName.substring(0, 1).toUpperCase(Locale.ROOT) +
fieldName.substring(1);
boolean isReadOnly = recordFieldNode.readonlyKeyword().isPresent();
boolean isReadOnly = recordFieldNode.kind().equals(SyntaxKind.RECORD_FIELD) ?
((RecordFieldNode) recordFieldNode).readonlyKeyword().isPresent() :
((RecordFieldWithDefaultValueNode) recordFieldNode).readonlyKeyword().isPresent();

Node typeName = recordFieldNode.kind().equals(SyntaxKind.RECORD_FIELD) ?
((RecordFieldNode) recordFieldNode).typeName() :
((RecordFieldWithDefaultValueNode) recordFieldNode).typeName();
if (fieldTypeDescKind.equals(TypeDescKind.RECORD)) {
RecordTypeSymbol inlineRecordTypeSymbol = (RecordTypeSymbol) fieldTypeSymbol;
fieldType = TypeDescKind.RECORD.getName();
RecordTypeDescriptorNode recordTypeDescNode = (RecordTypeDescriptorNode) recordFieldNode.typeName();
RecordTypeDescriptorNode recordTypeDescNode = (RecordTypeDescriptorNode) typeName;
this.types.put(inlineRecordName, getType(inlineRecordTypeSymbol, recordTypeDescNode, inlineRecordName,
getElementLocation(recordFieldSymbol), true));
String associateCardinality = optional ? CardinalityValue.ZERO_OR_ONE.getValue() :
Expand All @@ -162,10 +189,10 @@ private Attribute getAttribute(RecordFieldSymbol recordFieldSymbol, RecordFieldN
getInlineRecordTypeSymbol((ArrayTypeSymbol) fieldTypeSymbol).isPresent()) {
RecordTypeSymbol inlineRecordTypeSymbol =
getInlineRecordTypeSymbol((ArrayTypeSymbol) fieldTypeSymbol).get();
int arraySize = ((ArrayTypeDescriptorNode) recordFieldNode.typeName()).dimensions().size();
int arraySize = ((ArrayTypeDescriptorNode) typeName).dimensions().size();
fieldType = TypeDescKind.RECORD.getName() + ARRAY.repeat(arraySize);
RecordTypeDescriptorNode recordTypeDescNode =
(RecordTypeDescriptorNode) ((ArrayTypeDescriptorNode) recordFieldNode.typeName()).memberTypeDesc();
(RecordTypeDescriptorNode) ((ArrayTypeDescriptorNode) typeName).memberTypeDesc();
this.types.put(inlineRecordName, getType(inlineRecordTypeSymbol, recordTypeDescNode, inlineRecordName,
getElementLocation(recordFieldSymbol), true));
List<String> associateCardinalities = getArrayAssociateCardinalities(recordFieldNode);
Expand Down Expand Up @@ -288,10 +315,14 @@ private String getAssociateCardinality(boolean isArray, boolean isOptional, bool
}
}

private List<String> getArrayAssociateCardinalities(RecordFieldNode recordFieldNode) {
private List<String> getArrayAssociateCardinalities(Node recordFieldNode) {
Optional<MetadataNode> metadata = recordFieldNode.kind().equals(SyntaxKind.RECORD_FIELD) ?
((RecordFieldNode) recordFieldNode).metadata() :
((RecordFieldWithDefaultValueNode) recordFieldNode).metadata();

List<String> associateCardinalities = new LinkedList<>();
if (recordFieldNode != null && recordFieldNode.metadata().isPresent()) {
for (AnnotationNode annotationNode : recordFieldNode.metadata().get().annotations()) {
if (metadata.isPresent()) {
for (AnnotationNode annotationNode : metadata.get().annotations()) {
if (annotationNode.annotReference().kind().equals(SyntaxKind.QUALIFIED_NAME_REFERENCE)) {
QualifiedNameReferenceNode annotRef = (QualifiedNameReferenceNode) annotationNode.annotReference();
if (annotRef.modulePrefix().text().equals(CONSTRAINT_KEYWORD) &&
Expand Down Expand Up @@ -386,7 +417,7 @@ private String getAssociateEntityName(TypeReferenceTypeSymbol typeReferenceTypeS
return referenceType;
}

private List<Association> getAssociations(TypeSymbol fieldTypeDescriptor, RecordFieldNode recordFieldNode,
private List<Association> getAssociations(TypeSymbol fieldTypeDescriptor, Node recordFieldNode,
String entityName, boolean optional, boolean isNillable) {

List<Association> associations = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public type Adult record {
*User;
string occupation;
string officeContactNo?;
string personalContactNo = "";
};

public type Profile record {
Expand Down
Loading