From 5b8006c9fe8a77bb471dbcd79e3f465babc9c830 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Sat, 17 Dec 2022 23:18:55 +0530 Subject: [PATCH 01/58] Set owner of generated type definitions --- .../ballerinalang/compiler/util/ImmutableTypeCloner.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/util/ImmutableTypeCloner.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/util/ImmutableTypeCloner.java index 7a860921cb56..cb23129d1de1 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/util/ImmutableTypeCloner.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/util/ImmutableTypeCloner.java @@ -33,6 +33,7 @@ import org.wso2.ballerinalang.compiler.semantics.model.symbols.BAttachedFunction; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BObjectTypeSymbol; +import org.wso2.ballerinalang.compiler.semantics.model.symbols.BPackageSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BRecordTypeSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BTypeSymbol; @@ -567,16 +568,17 @@ private static BIntersectionType defineImmutableRecordType(Location pos, BRecord SymbolEnv env, SymbolTable symTable, BLangAnonymousModelHelper anonymousModelHelper, Names names, Types types, Set unresolvedTypes) { - PackageID pkgID = env.enclPkg.symbol.pkgID; + BPackageSymbol packageSymbol = env.enclPkg.symbol; + PackageID pkgID = packageSymbol.pkgID; BTypeSymbol recordTypeSymbol = origRecordType.tsymbol; BRecordTypeSymbol recordSymbol = Symbols.createRecordSymbol(recordTypeSymbol.flags | Flags.READONLY, getImmutableTypeName(names, getSymbolFQN(recordTypeSymbol)), - pkgID, null, env.scope.owner, pos, recordTypeSymbol.origin); + pkgID, null, packageSymbol, pos, recordTypeSymbol.origin); BInvokableType bInvokableType = new BInvokableType(new ArrayList<>(), symTable.nilType, null); BInvokableSymbol initFuncSymbol = Symbols.createFunctionSymbol( - Flags.PUBLIC, Names.EMPTY, Names.EMPTY, env.enclPkg.symbol.pkgID, bInvokableType, env.scope.owner, + Flags.PUBLIC, Names.EMPTY, Names.EMPTY, env.enclPkg.symbol.pkgID, bInvokableType, packageSymbol, false, symTable.builtinPos, VIRTUAL); initFuncSymbol.retType = symTable.nilType; recordSymbol.initializerFunc = new BAttachedFunction(Names.INIT_FUNCTION_SUFFIX, initFuncSymbol, From 34f322f33b62a54cf994bb6d0c343bc4331b1bb5 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Sat, 17 Dec 2022 23:28:47 +0530 Subject: [PATCH 02/58] Add type details to `NewStructure` instruction --- .../ballerinalang/compiler/bir/BIRGen.java | 201 ++++++++++++++++-- .../compiler/bir/model/BIRNonTerminator.java | 8 +- 2 files changed, 183 insertions(+), 26 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index 1efbd9d829a7..e8001f086971 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -18,19 +18,32 @@ package org.wso2.ballerinalang.compiler.bir; +import io.ballerina.identifier.Utils; import io.ballerina.tools.diagnostics.Location; import io.ballerina.tools.text.LinePosition; import io.ballerina.tools.text.LineRange; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.stream.Collectors; +import javax.xml.XMLConstants; import org.ballerinalang.model.TreeBuilder; import org.ballerinalang.model.elements.Flag; import org.ballerinalang.model.elements.PackageID; import org.ballerinalang.model.symbols.AnnotationAttachmentSymbol; +import org.ballerinalang.model.symbols.SymbolKind; import org.ballerinalang.model.symbols.SymbolOrigin; import org.ballerinalang.model.tree.BlockNode; import org.ballerinalang.model.tree.NodeKind; import org.ballerinalang.model.tree.OperatorKind; import org.ballerinalang.model.tree.TopLevelNode; import org.ballerinalang.model.tree.expressions.RecordLiteralNode; +import org.ballerinalang.model.types.TypeKind; import org.wso2.ballerinalang.compiler.bir.model.BIRNode; import org.wso2.ballerinalang.compiler.bir.model.BIRNode.BIRAnnotation; import org.wso2.ballerinalang.compiler.bir.model.BIRNode.BIRAnnotationAttachment; @@ -70,6 +83,7 @@ import org.wso2.ballerinalang.compiler.semantics.model.symbols.BObjectTypeSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BResourceFunction; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BServiceSymbol; +import org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructureTypeSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BTypeDefinitionSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BTypeSymbol; @@ -100,6 +114,7 @@ import org.wso2.ballerinalang.compiler.tree.BLangResourceFunction; import org.wso2.ballerinalang.compiler.tree.BLangService; import org.wso2.ballerinalang.compiler.tree.BLangSimpleVariable; +import org.wso2.ballerinalang.compiler.tree.BLangTableKeyTypeConstraint; import org.wso2.ballerinalang.compiler.tree.BLangTypeDefinition; import org.wso2.ballerinalang.compiler.tree.BLangVariable; import org.wso2.ballerinalang.compiler.tree.BLangXMLNS; @@ -190,8 +205,23 @@ import org.wso2.ballerinalang.compiler.tree.statements.BLangWhile; import org.wso2.ballerinalang.compiler.tree.statements.BLangWorkerSend; import org.wso2.ballerinalang.compiler.tree.statements.BLangXMLNSStatement; +import org.wso2.ballerinalang.compiler.tree.types.BLangArrayType; +import org.wso2.ballerinalang.compiler.tree.types.BLangBuiltInRefTypeNode; +import org.wso2.ballerinalang.compiler.tree.types.BLangConstrainedType; +import org.wso2.ballerinalang.compiler.tree.types.BLangErrorType; +import org.wso2.ballerinalang.compiler.tree.types.BLangFiniteTypeNode; +import org.wso2.ballerinalang.compiler.tree.types.BLangFunctionTypeNode; +import org.wso2.ballerinalang.compiler.tree.types.BLangIntersectionTypeNode; +import org.wso2.ballerinalang.compiler.tree.types.BLangObjectTypeNode; +import org.wso2.ballerinalang.compiler.tree.types.BLangRecordTypeNode; +import org.wso2.ballerinalang.compiler.tree.types.BLangStreamType; import org.wso2.ballerinalang.compiler.tree.types.BLangStructureTypeNode; +import org.wso2.ballerinalang.compiler.tree.types.BLangTableTypeNode; +import org.wso2.ballerinalang.compiler.tree.types.BLangTupleTypeNode; import org.wso2.ballerinalang.compiler.tree.types.BLangType; +import org.wso2.ballerinalang.compiler.tree.types.BLangUnionTypeNode; +import org.wso2.ballerinalang.compiler.tree.types.BLangUserDefinedType; +import org.wso2.ballerinalang.compiler.tree.types.BLangValueType; import org.wso2.ballerinalang.compiler.util.BArrayState; import org.wso2.ballerinalang.compiler.util.ClosureVarSymbol; import org.wso2.ballerinalang.compiler.util.CompilerContext; @@ -203,18 +233,6 @@ import org.wso2.ballerinalang.compiler.util.Unifier; import org.wso2.ballerinalang.util.Flags; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.stream.Collectors; - -import javax.xml.XMLConstants; - import static org.ballerinalang.model.tree.NodeKind.CLASS_DEFN; import static org.ballerinalang.model.tree.NodeKind.INVOCATION; import static org.ballerinalang.model.tree.NodeKind.STATEMENT_EXPRESSION; @@ -248,6 +266,8 @@ public class BIRGen extends BLangNodeVisitor { // This map is used to create dependencies for imported module global variables private Map dummyGlobalVarMapForLocks = new HashMap<>(); + private Map typeDescMap = new HashMap<>(); + // This is to cache the lockstmt to BIR Lock private Map lockStmtMap = new HashMap<>(); @@ -356,6 +376,7 @@ private void generateClassDefinitions(List topLevelNodes) { @Override public void visit(BLangTypeDefinition astTypeDefinition) { +// astTypeDefinition.typeNode.accept(this); BType type = getDefinedType(astTypeDefinition); BSymbol symbol = astTypeDefinition.symbol; Name displayName = symbol.name; @@ -1101,6 +1122,10 @@ public void visit(BLangSimpleVariableDef astVarDefStmt) { this.currentScope = newScope; } + if (astVarDefStmt.var.typeNode != null) { + astVarDefStmt.var.typeNode.accept(this); + } + if (astVarDefStmt.var.expr == null) { return; } @@ -1134,6 +1159,105 @@ public void visit(BLangSimpleVariable varNode) { env.enclPkg.isListenerAvailable |= Symbols.isFlagOn(varNode.symbol.flags, Flags.LISTENER); } + public void visit(BLangUserDefinedType userDefinedType) { + if (Types.getReferredType(userDefinedType.getBType()).getKind() == TypeKind.RECORD) { + visitTypedesc(userDefinedType.pos, userDefinedType.getBType(), Collections.emptyList()); + } + } + + public void visit(BLangValueType valueType) { + } + + @Override + public void visit(BLangUnionTypeNode unionTypeNode) { + unionTypeNode.memberTypeNodes.forEach(typeNode -> typeNode.accept(this)); + } + + @Override + public void visit(BLangRecordTypeNode recordTypeNode) { + for (BLangSimpleVariable field : recordTypeNode.fields) { + if (field.typeNode != null) { + field.typeNode.accept(this); + } + } + if (recordTypeNode.restFieldType != null) { + recordTypeNode.restFieldType.accept(this); + } + } + + @Override + public void visit(BLangArrayType arrayType) { + arrayType.elemtype.accept(this); + } + + @Override + public void visit(BLangConstrainedType constrainedType) { + constrainedType.constraint.accept(this); + } + + @Override + public void visit(BLangErrorType errorType) { + if (errorType.detailType != null) { + errorType.detailType.accept(this); + } + } + + @Override + public void visit(BLangFunctionTypeNode functionTypeNode) { + } + + @Override + public void visit(BLangBuiltInRefTypeNode builtInRefTypeNode) { + } + + @Override + public void visit(BLangTableTypeNode tableTypeNode) { + tableTypeNode.constraint.accept(this); + if (tableTypeNode.tableKeyTypeConstraint != null) { + tableTypeNode.tableKeyTypeConstraint.accept(this); + } + } + + @Override + public void visit(BLangTupleTypeNode tupleTypeNode) { + tupleTypeNode.memberTypeNodes.forEach(member -> member.accept(this)); + if (tupleTypeNode.restParamType != null) { + tupleTypeNode.restParamType.accept(this); + } + } + + @Override + public void visit(BLangStreamType streamType) { + streamType.type.accept(this); + streamType.constraint.accept(this); + if (streamType.error != null) { + streamType.error.accept(this); + } + } + + + @Override + public void visit(BLangTableKeyTypeConstraint keyTypeConstraint) { + keyTypeConstraint.keyType.accept(this); + } + + @Override + public void visit(BLangObjectTypeNode objectTypeNode) { + for (BLangSimpleVariable field : objectTypeNode.fields) { + if (field.typeNode != null) { + field.typeNode.accept(this); + } + } + } + + @Override + public void visit(BLangFiniteTypeNode finiteTypeNode) { + } + + @Override + public void visit(BLangIntersectionTypeNode intersectionTypeNode) { + } + @Override public void visit(BLangAssignment astAssignStmt) { astAssignStmt.expr.accept(this); @@ -1599,7 +1723,7 @@ public void visit(BLangMapLiteral astMapLiteralExpr) { BIROperand toVarRef = new BIROperand(tempVarDcl); setScopeAndEmit(new BIRNonTerminator.NewStructure(astMapLiteralExpr.pos, toVarRef, this.env.targetOperand, - generateMappingConstructorEntries(astMapLiteralExpr.fields))); + generateMappingConstructorEntries(astMapLiteralExpr.fields), astMapLiteralExpr.getBType())); this.env.targetOperand = toVarRef; } @@ -1619,20 +1743,37 @@ public void visit(BLangTypeConversionExpr astTypeConversionExpr) { this.env.targetOperand = toVarRef; } + private boolean isNonReferredRecord(BType type) { + type = Types.getReferredType(type); + return type.tsymbol != null && type.tag == TypeTags.RECORD && + type.tsymbol.owner.getKind() == SymbolKind.PACKAGE; + } + @Override public void visit(BLangStructLiteral astStructLiteralExpr) { - List varDcls = mapToVarDcls(astStructLiteralExpr.enclMapSymbols); - visitTypedesc(astStructLiteralExpr.pos, astStructLiteralExpr.getBType(), varDcls); - - BIRVariableDcl tempVarDcl = new BIRVariableDcl(astStructLiteralExpr.getBType(), - this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind.TEMP); + BType type = astStructLiteralExpr.getBType(); + BIRVariableDcl tempVarDcl = new BIRVariableDcl(type, this.env.nextLocalVarId(names), VarScope.FUNCTION, + VarKind.TEMP); this.env.enclFunc.localVars.add(tempVarDcl); BIROperand toVarRef = new BIROperand(tempVarDcl); - - BIRNonTerminator.NewStructure instruction = - new BIRNonTerminator.NewStructure(astStructLiteralExpr.pos, toVarRef, this.env.targetOperand, - generateMappingConstructorEntries(astStructLiteralExpr.fields)); + BIRNonTerminator.NewStructure instruction; + if (isNonReferredRecord(type)) { + instruction = new BIRNonTerminator.NewStructure(astStructLiteralExpr.pos, toVarRef, toVarRef, + generateMappingConstructorEntries(astStructLiteralExpr.fields), type); + } else if (typeDescMap.containsKey(toNameString(type))) { + instruction = new BIRNonTerminator.NewStructure(astStructLiteralExpr.pos, toVarRef, + typeDescMap.get(toNameString(type)), + generateMappingConstructorEntries(astStructLiteralExpr.fields), type); + } else { + if (type.getKind() == TypeKind.RECORD) { + visitTypedesc(astStructLiteralExpr.pos, type, mapToVarDcls(((BRecordType)type).enclMapSymbols)); + } else { + visitTypedesc(astStructLiteralExpr.pos, type, Collections.emptyList()); + } + instruction = new BIRNonTerminator.NewStructure(astStructLiteralExpr.pos, toVarRef, this.env.targetOperand, + generateMappingConstructorEntries(astStructLiteralExpr.fields), type); + } setScopeAndEmit(instruction); this.env.targetOperand = toVarRef; @@ -2002,7 +2143,8 @@ public void visit(BLangWaitForAllExpr.BLangWaitLiteral waitLiteral) { this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind.TEMP); this.env.enclFunc.localVars.add(tempVarDcl); BIROperand toVarRef = new BIROperand(tempVarDcl); - setScopeAndEmit(new BIRNonTerminator.NewStructure(waitLiteral.pos, toVarRef, this.env.targetOperand)); + setScopeAndEmit(new BIRNonTerminator.NewStructure(waitLiteral.pos, toVarRef, this.env.targetOperand, + waitLiteral.getBType())); this.env.targetOperand = toVarRef; List keys = new ArrayList<>(); @@ -2275,6 +2417,19 @@ private void visitTypedesc(Location pos, BType type, List varDcls) { BIROperand toVarRef = new BIROperand(tempVarDcl); setScopeAndEmit(new BIRNonTerminator.NewTypeDesc(pos, toVarRef, type, varDcls)); this.env.targetOperand = toVarRef; + if (type.tsymbol != null && type.tsymbol.owner.getKind() != SymbolKind.PACKAGE) { + typeDescMap.put(toNameString(type), toVarRef); + } + } + + public static String toNameString(BType t) { + BTypeSymbol typeSymbol = t.tsymbol; + if ((typeSymbol.kind == SymbolKind.RECORD || typeSymbol.kind == SymbolKind.OBJECT) && + ((BStructureTypeSymbol) typeSymbol).typeDefinitionSymbol != null) { + return Utils.encodeNonFunctionIdentifier(((BStructureTypeSymbol) typeSymbol) + .typeDefinitionSymbol.name.value); + } + return Utils.encodeNonFunctionIdentifier(typeSymbol.name.value); } @Override diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNonTerminator.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNonTerminator.java index acf2df8dcfca..9cf22898633d 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNonTerminator.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNonTerminator.java @@ -192,20 +192,22 @@ public BIROperand[] getRhsOperands() { public static class NewStructure extends BIRNonTerminator { public BIROperand rhsOp; public List initialValues; + public BType type; - public NewStructure(Location pos, BIROperand lhsOp, BIROperand rhsOp) { + public NewStructure(Location pos, BIROperand lhsOp, BIROperand rhsOp, BType type) { super(pos, InstructionKind.NEW_STRUCTURE); this.lhsOp = lhsOp; this.rhsOp = rhsOp; this.initialValues = new ArrayList<>(); + this.type = type; } - public NewStructure(Location pos, BIROperand lhsOp, BIROperand rhsOp, - List initialValues) { + public NewStructure(Location pos, BIROperand lhsOp, BIROperand rhsOp, List initialValues, BType type) { super(pos, InstructionKind.NEW_STRUCTURE); this.lhsOp = lhsOp; this.rhsOp = rhsOp; this.initialValues = initialValues; + this.type = type; } @Override From 013bafeabe79dc95d9d6239fbb6959f2f0bbee94 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Sat, 17 Dec 2022 23:30:27 +0530 Subject: [PATCH 03/58] Add details of enclosure map symbols to record type --- .../ballerinalang/compiler/desugar/ClosureDesugar.java | 8 ++++++-- .../compiler/semantics/model/types/BRecordType.java | 5 +++++ .../compiler/tree/expressions/BLangRecordLiteral.java | 2 -- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java index 8cbd27935aed..c9949182ad20 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java @@ -24,6 +24,7 @@ import org.ballerinalang.model.tree.NodeKind; import org.ballerinalang.model.tree.TopLevelNode; import org.ballerinalang.model.tree.expressions.RecordLiteralNode; +import org.ballerinalang.model.types.TypeKind; import org.wso2.ballerinalang.compiler.semantics.analyzer.SymbolResolver; import org.wso2.ballerinalang.compiler.semantics.analyzer.Types; import org.wso2.ballerinalang.compiler.semantics.model.Scope; @@ -40,6 +41,7 @@ import org.wso2.ballerinalang.compiler.semantics.model.types.BInvokableType; import org.wso2.ballerinalang.compiler.semantics.model.types.BMapType; import org.wso2.ballerinalang.compiler.semantics.model.types.BObjectType; +import org.wso2.ballerinalang.compiler.semantics.model.types.BRecordType; import org.wso2.ballerinalang.compiler.semantics.model.types.BType; import org.wso2.ballerinalang.compiler.tree.BLangAnnotation; import org.wso2.ballerinalang.compiler.tree.BLangAnnotationAttachment; @@ -1963,8 +1965,10 @@ public void visit(BLangRecordLiteral.BLangMapLiteral mapLiteral) { public void visit(BLangRecordLiteral.BLangStructLiteral structLiteral) { SymbolEnv symbolEnv = env.createClone(); BLangFunction enclInvokable = (BLangFunction) symbolEnv.enclInvokable; - structLiteral.enclMapSymbols = collectClosureMapSymbols(symbolEnv, enclInvokable, false); - + if (structLiteral.getBType().getKind() == TypeKind.RECORD) { + ((BRecordType) structLiteral.getBType()).enclMapSymbols = + collectClosureMapSymbols(symbolEnv, enclInvokable, false); + } for (RecordLiteralNode.RecordField field : structLiteral.fields) { if (field.isKeyValueField()) { BLangRecordLiteral.BLangRecordKeyValueField keyValueField = diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/model/types/BRecordType.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/model/types/BRecordType.java index a84630a5509d..3495ba5fe25e 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/model/types/BRecordType.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/model/types/BRecordType.java @@ -21,10 +21,13 @@ import org.ballerinalang.model.types.TypeKind; import org.wso2.ballerinalang.compiler.semantics.model.TypeVisitor; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BTypeSymbol; +import org.wso2.ballerinalang.compiler.semantics.model.symbols.BVarSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.Symbols; import org.wso2.ballerinalang.compiler.util.TypeTags; import org.wso2.ballerinalang.util.Flags; +import java.util.TreeMap; + import java.util.Optional; /** @@ -50,6 +53,8 @@ public class BRecordType extends BStructureType implements RecordType { public BRecordType mutableType; private BIntersectionType intersectionType = null; + public TreeMap enclMapSymbols; + public BRecordType(BTypeSymbol tSymbol) { super(TypeTags.RECORD, tSymbol); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/tree/expressions/BLangRecordLiteral.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/tree/expressions/BLangRecordLiteral.java index 71c9b809f57d..b1f1e09bcf21 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/tree/expressions/BLangRecordLiteral.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/tree/expressions/BLangRecordLiteral.java @@ -33,7 +33,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.TreeMap; import java.util.stream.Collectors; import static org.ballerinalang.model.tree.NodeKind.RECORD_LITERAL_KEY_VALUE; @@ -293,7 +292,6 @@ public String toString() { public static class BLangStructLiteral extends BLangRecordLiteral { public BAttachedFunction initializer; - public TreeMap enclMapSymbols; public BLangStructLiteral(Location pos, BType structType, BTypeSymbol typeSymbol, List fields) { super(pos); From cd8d4a85e1c71cc0619e83d7769ec28134746825 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Sat, 17 Dec 2022 23:54:18 +0530 Subject: [PATCH 04/58] Use record reference type when creating mapping value --- .../bir/codegen/JvmInstructionGen.java | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java index d33946f06111..86af13910567 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java @@ -21,6 +21,7 @@ import io.ballerina.identifier.Utils; import org.ballerinalang.compiler.BLangCompilerException; import org.ballerinalang.model.elements.PackageID; +import org.ballerinalang.model.symbols.SymbolKind; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.wso2.ballerinalang.compiler.bir.codegen.internal.AsyncDataCollector; @@ -47,7 +48,6 @@ import org.wso2.ballerinalang.compiler.semantics.model.types.BIntersectionType; import org.wso2.ballerinalang.compiler.semantics.model.types.BObjectType; import org.wso2.ballerinalang.compiler.semantics.model.types.BType; -import org.wso2.ballerinalang.compiler.semantics.model.types.BTypeReferenceType; import org.wso2.ballerinalang.compiler.util.TypeTags; import org.wso2.ballerinalang.util.Flags; @@ -1321,8 +1321,14 @@ private int getJVMIndexOfVarRef(BIRNode.BIRVariableDcl varDcl) { } void generateMapNewIns(BIRNonTerminator.NewStructure mapNewIns, int localVarOffset) { - - this.loadVar(mapNewIns.rhsOp.variableDcl); + if (isNonReferredRecord(mapNewIns.type)) { + PackageID packageID = mapNewIns.lhsOp.variableDcl.type.tsymbol.pkgID; + String typeOwner = JvmCodeGenUtil.getPackageName(packageID) + MODULE_INIT_CLASS_NAME; + String fieldName = jvmTypeGen.getTypedescFieldName(toNameString(mapNewIns.type)); + mv.visitFieldInsn(GETSTATIC, typeOwner, fieldName, GET_TYPEDESC); + } else { + this.loadVar(mapNewIns.rhsOp.variableDcl); + } this.mv.visitVarInsn(ALOAD, localVarOffset); List initialValues = mapNewIns.initialValues; @@ -2087,7 +2093,7 @@ void generateNegateIns(BIRNonTerminator.UnaryOP unaryOp) { void generateNewTypedescIns(BIRNonTerminator.NewTypeDesc newTypeDesc) { List closureVars = newTypeDesc.closureVars; if (isNonReferredRecord(newTypeDesc.type)) { - BType type = JvmCodeGenUtil.getReferredType(newTypeDesc.type); + BType type = Types.getReferredType(newTypeDesc.type); PackageID packageID = type.tsymbol.pkgID; String typeOwner = JvmCodeGenUtil.getPackageName(packageID) + MODULE_INIT_CLASS_NAME; String fieldName = jvmTypeGen.getTypedescFieldName(toNameString(type)); @@ -2099,12 +2105,9 @@ void generateNewTypedescIns(BIRNonTerminator.NewTypeDesc newTypeDesc) { } private boolean isNonReferredRecord(BType type) { - if (type.tag != TypeTags.TYPEREFDESC) { - return false; - } - BType referredType = ((BTypeReferenceType) type).referredType; - return referredType.tag == TypeTags.RECORD && - type.getQualifiedTypeName().equals(referredType.getQualifiedTypeName()); + type = Types.getReferredType(type); + return type.tsymbol != null && type.tag == TypeTags.RECORD && + type.tsymbol.owner.getKind() == SymbolKind.PACKAGE; } private void generateNewTypedescCreate(BType btype, List closureVars) { From 679b9fa1acf3db8689641dd0e5722f2e23878f85 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Sun, 18 Dec 2022 00:17:34 +0530 Subject: [PATCH 05/58] Create runtime type instance only for the user defined type definitions --- .../compiler/bir/codegen/split/types/JvmRecordTypeGen.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/types/JvmRecordTypeGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/types/JvmRecordTypeGen.java index 9f3619b569ab..7d580f6f9fe9 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/types/JvmRecordTypeGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/types/JvmRecordTypeGen.java @@ -19,6 +19,7 @@ import io.ballerina.identifier.Utils; import org.ballerinalang.model.elements.PackageID; +import org.ballerinalang.model.symbols.SymbolKind; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.wso2.ballerinalang.compiler.bir.codegen.BallerinaClassWriter; @@ -170,7 +171,9 @@ public void createRecordType(MethodVisitor mv, BRecordType recordType, String ty // initialize the record type mv.visitMethodInsn(INVOKESPECIAL, RECORD_TYPE_IMPL, JVM_INIT_METHOD, RECORD_TYPE_IMPL_INIT, false); - + if (recordType.tsymbol.owner != null && recordType.tsymbol.owner.getKind() != SymbolKind.PACKAGE) { + return; + } mv.visitInsn(DUP); String packageName = JvmCodeGenUtil.getPackageName(recordType.tsymbol.pkgID); String className = getTypeDescClassName(packageName, toNameString(recordType)); From dd896970c1737a086f0be9fb604150cc27b9ca07 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Sun, 18 Dec 2022 00:53:31 +0530 Subject: [PATCH 06/58] Fix checkstyle issues --- .../ballerinalang/compiler/bir/BIRGen.java | 31 ++++++++++--------- .../compiler/bir/model/BIRNonTerminator.java | 3 +- .../semantics/model/types/BRecordType.java | 2 +- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index e8001f086971..b0220f2e7b71 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -22,16 +22,6 @@ import io.ballerina.tools.diagnostics.Location; import io.ballerina.tools.text.LinePosition; import io.ballerina.tools.text.LineRange; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeMap; -import java.util.stream.Collectors; -import javax.xml.XMLConstants; import org.ballerinalang.model.TreeBuilder; import org.ballerinalang.model.elements.Flag; import org.ballerinalang.model.elements.PackageID; @@ -233,6 +223,18 @@ import org.wso2.ballerinalang.compiler.util.Unifier; import org.wso2.ballerinalang.util.Flags; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.stream.Collectors; + +import javax.xml.XMLConstants; + import static org.ballerinalang.model.tree.NodeKind.CLASS_DEFN; import static org.ballerinalang.model.tree.NodeKind.INVOCATION; import static org.ballerinalang.model.tree.NodeKind.STATEMENT_EXPRESSION; @@ -376,7 +378,6 @@ private void generateClassDefinitions(List topLevelNodes) { @Override public void visit(BLangTypeDefinition astTypeDefinition) { -// astTypeDefinition.typeNode.accept(this); BType type = getDefinedType(astTypeDefinition); BSymbol symbol = astTypeDefinition.symbol; Name displayName = symbol.name; @@ -1159,12 +1160,14 @@ public void visit(BLangSimpleVariable varNode) { env.enclPkg.isListenerAvailable |= Symbols.isFlagOn(varNode.symbol.flags, Flags.LISTENER); } + @Override public void visit(BLangUserDefinedType userDefinedType) { if (Types.getReferredType(userDefinedType.getBType()).getKind() == TypeKind.RECORD) { visitTypedesc(userDefinedType.pos, userDefinedType.getBType(), Collections.emptyList()); } } + @Override public void visit(BLangValueType valueType) { } @@ -1235,7 +1238,6 @@ public void visit(BLangStreamType streamType) { } } - @Override public void visit(BLangTableKeyTypeConstraint keyTypeConstraint) { keyTypeConstraint.keyType.accept(this); @@ -1723,7 +1725,8 @@ public void visit(BLangMapLiteral astMapLiteralExpr) { BIROperand toVarRef = new BIROperand(tempVarDcl); setScopeAndEmit(new BIRNonTerminator.NewStructure(astMapLiteralExpr.pos, toVarRef, this.env.targetOperand, - generateMappingConstructorEntries(astMapLiteralExpr.fields), astMapLiteralExpr.getBType())); + generateMappingConstructorEntries(astMapLiteralExpr.fields), + astMapLiteralExpr.getBType())); this.env.targetOperand = toVarRef; } @@ -1767,7 +1770,7 @@ public void visit(BLangStructLiteral astStructLiteralExpr) { generateMappingConstructorEntries(astStructLiteralExpr.fields), type); } else { if (type.getKind() == TypeKind.RECORD) { - visitTypedesc(astStructLiteralExpr.pos, type, mapToVarDcls(((BRecordType)type).enclMapSymbols)); + visitTypedesc(astStructLiteralExpr.pos, type, mapToVarDcls(((BRecordType) type).enclMapSymbols)); } else { visitTypedesc(astStructLiteralExpr.pos, type, Collections.emptyList()); } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNonTerminator.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNonTerminator.java index 9cf22898633d..dd971817b246 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNonTerminator.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNonTerminator.java @@ -202,7 +202,8 @@ public NewStructure(Location pos, BIROperand lhsOp, BIROperand rhsOp, BType type this.type = type; } - public NewStructure(Location pos, BIROperand lhsOp, BIROperand rhsOp, List initialValues, BType type) { + public NewStructure(Location pos, BIROperand lhsOp, BIROperand rhsOp, + List initialValues, BType type) { super(pos, InstructionKind.NEW_STRUCTURE); this.lhsOp = lhsOp; this.rhsOp = rhsOp; diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/model/types/BRecordType.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/model/types/BRecordType.java index 3495ba5fe25e..a5b1284a9d13 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/model/types/BRecordType.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/model/types/BRecordType.java @@ -26,9 +26,9 @@ import org.wso2.ballerinalang.compiler.util.TypeTags; import org.wso2.ballerinalang.util.Flags; +import java.util.Optional; import java.util.TreeMap; -import java.util.Optional; /** * {@code BRecordType} represents record type in Ballerina. From c3c76900779b175a5a004c59ae525a2cac6405c1 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 3 Jan 2023 16:37:15 +0530 Subject: [PATCH 07/58] Generate separate method to create typedesc instances --- .../ballerinalang/compiler/bir/BIRGen.java | 2 +- .../compiler/bir/codegen/JvmConstants.java | 1 + .../bir/codegen/JvmInstructionGen.java | 2 +- .../bir/codegen/split/JvmCreateTypeGen.java | 54 ++++++++++++++++++- .../codegen/split/types/JvmRecordTypeGen.java | 26 +-------- 5 files changed, 57 insertions(+), 28 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index 744cbaf0e5ab..a433d85f3f2f 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -725,8 +725,8 @@ public void visit(BLangFunction astFunc) { this.env.enclBasicBlocks = birFunc.basicBlocks; birFunc.basicBlocks.add(entryBB); this.env.enclBB = entryBB; + this.typeDescMap = new HashMap<>(); addToTrapStack(entryBB); - astFunc.body.accept(this); birFunc.basicBlocks.add(this.env.returnBB); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmConstants.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmConstants.java index cd26c528e205..e5663d32bc67 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmConstants.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmConstants.java @@ -360,6 +360,7 @@ public class JvmConstants { public static final String CREATE_TYPES_METHOD = "$createTypes"; public static final String CREATE_TYPE_CONSTANTS_METHOD = "$createTypeConstants"; public static final String CREATE_TYPE_INSTANCES_METHOD = "$createTypeInstances"; + public static final String CREATE_TYPEDESC_INSTANCES_METHOD = "$createTypedescInstances"; public static final String GLOBAL_LOCK_NAME = "lock"; public static final String SERVICE_EP_AVAILABLE = "$serviceEPAvailable"; public static final String LOCK_STORE_VAR_NAME = "$LOCK_STORE"; diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java index ae9ddba9e72c..7e09bee989c5 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java @@ -2094,7 +2094,7 @@ void generateNegateIns(BIRNonTerminator.UnaryOP unaryOp) { void generateNewTypedescIns(BIRNonTerminator.NewTypeDesc newTypeDesc) { List closureVars = newTypeDesc.closureVars; if (isNonReferredRecord(newTypeDesc.type)) { - BType type = Types.getReferredType(newTypeDesc.type); + BType type = newTypeDesc.type; PackageID packageID = type.tsymbol.pkgID; String typeOwner = JvmCodeGenUtil.getPackageName(packageID) + MODULE_INIT_CLASS_NAME; String fieldName = jvmTypeGen.getTypedescFieldName(toNameString(type)); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java index c3c0829b132c..b80fbefdc275 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java @@ -18,6 +18,7 @@ package org.wso2.ballerinalang.compiler.bir.codegen.split; import org.ballerinalang.model.elements.PackageID; +import org.ballerinalang.model.symbols.SymbolKind; import org.ballerinalang.model.types.SelectivelyImmutableReferenceType; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Label; @@ -42,6 +43,7 @@ import org.wso2.ballerinalang.compiler.semantics.analyzer.TypeHashVisitor; import org.wso2.ballerinalang.compiler.semantics.analyzer.Types; import org.wso2.ballerinalang.compiler.semantics.model.SymbolTable; +import org.wso2.ballerinalang.compiler.semantics.model.symbols.BSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.Symbols; import org.wso2.ballerinalang.compiler.semantics.model.types.BErrorType; import org.wso2.ballerinalang.compiler.semantics.model.types.BField; @@ -51,6 +53,7 @@ import org.wso2.ballerinalang.compiler.semantics.model.types.BTupleType; import org.wso2.ballerinalang.compiler.semantics.model.types.BType; import org.wso2.ballerinalang.compiler.semantics.model.types.BTypeIdSet; +import org.wso2.ballerinalang.compiler.semantics.model.types.BTypeReferenceType; import org.wso2.ballerinalang.compiler.semantics.model.types.BUnionType; import org.wso2.ballerinalang.compiler.semantics.model.types.NamedNode; import org.wso2.ballerinalang.compiler.util.TypeTags; @@ -72,6 +75,7 @@ import static org.objectweb.asm.Opcodes.ACC_PUBLIC; import static org.objectweb.asm.Opcodes.ACC_STATIC; import static org.objectweb.asm.Opcodes.ACC_SUPER; +import static org.objectweb.asm.Opcodes.ACONST_NULL; import static org.objectweb.asm.Opcodes.ALOAD; import static org.objectweb.asm.Opcodes.ARETURN; import static org.objectweb.asm.Opcodes.DUP; @@ -92,6 +96,7 @@ import static org.objectweb.asm.Opcodes.V1_8; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil.createDefaultCase; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil.getModuleLevelClassName; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil.toNameString; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.B_ARRAY_TYPE_INIT_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.B_ARRAY_TYPE_POPULATE_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.B_ERROR_TYPE_INIT_METHOD; @@ -102,6 +107,7 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.B_TYPEREF_TYPE_POPULATE_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.B_UNION_TYPE_INIT_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.B_UNION_TYPE_POPULATE_METHOD; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CREATE_TYPEDESC_INSTANCES_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CREATE_TYPES_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CREATE_TYPE_CONSTANTS_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CREATE_TYPE_INSTANCES_METHOD; @@ -122,11 +128,14 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ADD_TYPE_ID; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ANY_TO_JBOOLEAN; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_TYPE; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_TYPEDESC; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_FIELD_IMPL; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.MAP_PUT; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.SET_IMMUTABLE_TYPE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.SET_LINKED_HASH_MAP; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.TYPE_DESC_CONSTRUCTOR; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmTypeGen.getTypeFieldName; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmValueGen.getTypeDescClassName; /** * BIR types to JVM byte code generation class. @@ -213,6 +222,7 @@ void generateCreateTypesMethod(ClassWriter cw, List typeDefs, String moduleInitClass, SymbolTable symbolTable) { createTypeConstants(cw); createTypesInstance(cw, typeDefs, moduleInitClass); + createTypedescInstances(cw, typeDefs, moduleInitClass); Map populateTypeFuncNames = populateTypes(cw, typeDefs, moduleInitClass, symbolTable); MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, CREATE_TYPES_METHOD, "()V", null, null); @@ -224,6 +234,9 @@ void generateCreateTypesMethod(ClassWriter cw, List typeDefs, // Invoke create-type-constants method mv.visitMethodInsn(INVOKESTATIC, typesClass, CREATE_TYPE_CONSTANTS_METHOD, "()V", false); + // Invoke create-typedesc-instances method + mv.visitMethodInsn(INVOKESTATIC, typesClass, CREATE_TYPEDESC_INSTANCES_METHOD, "()V", false); + // Invoke the populate-type functions for (Map.Entry entry : populateTypeFuncNames.entrySet()) { String funcName = entry.getKey(); @@ -247,6 +260,45 @@ private void createTypesInstance(ClassWriter cw, List typeDef mv.visitEnd(); } + private void createTypedescInstances(ClassWriter cw, List typeDefs, String moduleInitClass) { + MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, CREATE_TYPEDESC_INSTANCES_METHOD, + "()V", null, null); + mv.visitCode(); + for (BIRTypeDefinition optionalTypeDef : typeDefs) { + BType bType = JvmCodeGenUtil.getReferredType(optionalTypeDef.type); + if (bType.tag == TypeTags.RECORD) { + BRecordType recordType = (BRecordType) bType; + BSymbol owner = recordType.tsymbol.owner; + if (owner != null && owner.getKind() != SymbolKind.PACKAGE) { + continue; + } + String packageName = JvmCodeGenUtil.getPackageName(recordType.tsymbol.pkgID); + String className = getTypeDescClassName(packageName, toNameString(recordType)); + mv.visitTypeInsn(NEW, className); + mv.visitInsn(DUP); + BType referenceType = optionalTypeDef.referenceType; + if (referenceType == null) { + jvmTypeGen.loadType(mv, JvmCodeGenUtil.getReferredType(optionalTypeDef.type)); + } else { + BType referredType = ((BTypeReferenceType) referenceType).referredType; + if (referredType.tag == TypeTags.TYPEREFDESC) { + jvmTypeGen.loadType(mv, referenceType); + } else { + jvmTypeGen.loadType(mv, referredType); + } + } + mv.visitInsn(ACONST_NULL); + mv.visitMethodInsn(INVOKESPECIAL, className, JVM_INIT_METHOD, TYPE_DESC_CONSTRUCTOR, false); + mv.visitFieldInsn(PUTSTATIC, moduleInitClass, + jvmTypeGen.getTypedescFieldName(optionalTypeDef.internalName.value), GET_TYPEDESC); + } + } + + mv.visitInsn(RETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + private int createTypesInstanceSplits(ClassWriter cw, List typeDefs, String typeOwnerClass) { if (typeDefs.isEmpty()) { @@ -273,7 +325,7 @@ private int createTypesInstanceSplits(ClassWriter cw, List ty } switch (bType.tag) { case TypeTags.RECORD: - jvmRecordTypeGen.createRecordType(mv, (BRecordType) bType, typeOwnerClass, name); + jvmRecordTypeGen.createRecordType(mv, (BRecordType) bType); break; case TypeTags.OBJECT: jvmObjectTypeGen.createObjectType(mv, (BObjectType) bType); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/types/JvmRecordTypeGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/types/JvmRecordTypeGen.java index 7d580f6f9fe9..2f1dc5a7ba86 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/types/JvmRecordTypeGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/types/JvmRecordTypeGen.java @@ -19,11 +19,9 @@ import io.ballerina.identifier.Utils; import org.ballerinalang.model.elements.PackageID; -import org.ballerinalang.model.symbols.SymbolKind; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.wso2.ballerinalang.compiler.bir.codegen.BallerinaClassWriter; -import org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil; import org.wso2.ballerinalang.compiler.bir.codegen.JvmPackageGen; import org.wso2.ballerinalang.compiler.bir.codegen.JvmTypeGen; import org.wso2.ballerinalang.compiler.bir.codegen.split.JvmConstantsGen; @@ -39,21 +37,16 @@ import static org.objectweb.asm.ClassWriter.COMPUTE_FRAMES; import static org.objectweb.asm.Opcodes.ACC_PUBLIC; import static org.objectweb.asm.Opcodes.ACC_SUPER; -import static org.objectweb.asm.Opcodes.ACONST_NULL; import static org.objectweb.asm.Opcodes.CHECKCAST; import static org.objectweb.asm.Opcodes.DUP; -import static org.objectweb.asm.Opcodes.DUP_X1; import static org.objectweb.asm.Opcodes.GETSTATIC; import static org.objectweb.asm.Opcodes.INVOKESPECIAL; import static org.objectweb.asm.Opcodes.INVOKESTATIC; import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; import static org.objectweb.asm.Opcodes.NEW; import static org.objectweb.asm.Opcodes.PUTFIELD; -import static org.objectweb.asm.Opcodes.PUTSTATIC; -import static org.objectweb.asm.Opcodes.SWAP; import static org.objectweb.asm.Opcodes.V1_8; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil.getModuleLevelClassName; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil.toNameString; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.JVM_INIT_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.LINKED_HASH_MAP; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MODULE_RECORD_TYPES_CLASS_NAME; @@ -61,12 +54,9 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.RECORD_TYPE_IMPL; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_MODULE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_TYPE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_TYPEDESC; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.RECORD_TYPE_IMPL_INIT; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.SET_LINKED_HASH_MAP; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.SET_MAP; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.TYPE_DESC_CONSTRUCTOR; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmValueGen.getTypeDescClassName; /** * BIR record type to JVM byte code generation class. @@ -143,10 +133,8 @@ private void addRecordRestField(MethodVisitor mv, BType restFieldType) { * * @param mv method visitor * @param recordType record type - * @param typeOwnerClass record type owner class - * @param internalName record type internal name */ - public void createRecordType(MethodVisitor mv, BRecordType recordType, String typeOwnerClass, String internalName) { + public void createRecordType(MethodVisitor mv, BRecordType recordType) { // Create the record type mv.visitTypeInsn(NEW, RECORD_TYPE_IMPL); mv.visitInsn(DUP); @@ -171,18 +159,6 @@ public void createRecordType(MethodVisitor mv, BRecordType recordType, String ty // initialize the record type mv.visitMethodInsn(INVOKESPECIAL, RECORD_TYPE_IMPL, JVM_INIT_METHOD, RECORD_TYPE_IMPL_INIT, false); - if (recordType.tsymbol.owner != null && recordType.tsymbol.owner.getKind() != SymbolKind.PACKAGE) { - return; - } - mv.visitInsn(DUP); - String packageName = JvmCodeGenUtil.getPackageName(recordType.tsymbol.pkgID); - String className = getTypeDescClassName(packageName, toNameString(recordType)); - mv.visitTypeInsn(NEW, className); - mv.visitInsn(DUP_X1); - mv.visitInsn(SWAP); - mv.visitInsn(ACONST_NULL); - mv.visitMethodInsn(INVOKESPECIAL, className, JVM_INIT_METHOD, TYPE_DESC_CONSTRUCTOR, false); - mv.visitFieldInsn(PUTSTATIC, typeOwnerClass, jvmTypeGen.getTypedescFieldName(internalName), GET_TYPEDESC); } private String getFullName(BRecordType recordType) { From 193eb7404283fb02780a94441f848fcdbf23ed11 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 3 Jan 2023 19:39:30 +0530 Subject: [PATCH 08/58] BIR test update --- .../resources/test-src/bir/bir-dump/mapInits | 225 +++++++++--------- 1 file changed, 114 insertions(+), 111 deletions(-) diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/mapInits b/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/mapInits index eb8f90d74fb2..5852e315454a 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/mapInits +++ b/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/mapInits @@ -2,255 +2,258 @@ mapInits function() -> (string|(), int|()) { %0(RETURN) (string|(), int|()); %1(LOCAL) map; %2(TEMP) typeDesc; - %4(LOCAL) Person; - %7(TEMP) string; + %3(TEMP) typeDesc; + %5(LOCAL) Person; %8(TEMP) string; %9(TEMP) string; - %10(TEMP) int; - %11(TEMP) string; + %10(TEMP) string; + %11(TEMP) int; %12(TEMP) string; - %13(TEMP) Employee; - %20(SYNTHETIC) string|(); - %21(SYNTHETIC) Employee|(); - %25(SYNTHETIC) Employee|(); - %27(SYNTHETIC) boolean; + %13(TEMP) string; + %14(TEMP) Employee; + %18(TEMP) typeDesc; + %21(SYNTHETIC) string|(); + %22(SYNTHETIC) Employee|(); + %26(SYNTHETIC) Employee|(); %28(SYNTHETIC) boolean; - %29(SYNTHETIC) any|error; - %30(TEMP) boolean; - %42(SYNTHETIC) boolean; + %29(SYNTHETIC) boolean; + %30(SYNTHETIC) any|error; + %31(TEMP) boolean; %43(SYNTHETIC) boolean; - %44(SYNTHETIC) any|error; - %60(SYNTHETIC) boolean; + %44(SYNTHETIC) boolean; + %45(SYNTHETIC) any|error; %61(SYNTHETIC) boolean; - %71(TEMP) (); - %73(SYNTHETIC) int|(); - %74(SYNTHETIC) Employee|(); - %78(SYNTHETIC) Employee|(); - %80(SYNTHETIC) boolean; + %62(SYNTHETIC) boolean; + %72(TEMP) (); + %74(SYNTHETIC) int|(); + %75(SYNTHETIC) Employee|(); + %79(SYNTHETIC) Employee|(); %81(SYNTHETIC) boolean; - %82(SYNTHETIC) any|error; - %95(SYNTHETIC) boolean; + %82(SYNTHETIC) boolean; + %83(SYNTHETIC) any|error; %96(SYNTHETIC) boolean; - %97(SYNTHETIC) any|error; - %109(TEMP) int; - %113(SYNTHETIC) boolean; + %97(SYNTHETIC) boolean; + %98(SYNTHETIC) any|error; + %110(TEMP) int; %114(SYNTHETIC) boolean; + %115(SYNTHETIC) boolean; bb0 { - %2 = newType map; - %1 = NewMap %2; - %2 = newType Person; - %7 = ConstLoad name; - %8 = ConstLoad Jack; - %9 = ConstLoad age; - %10 = ConstLoad 25; - %11 = ConstLoad address; - %12 = ConstLoad Usa; - %4 = NewMap %2; - %13 = %4; - %7 = ConstLoad jack; - %1[%7] = %13; - %2 = newType (string|(), int|()); - %10 = ConstLoad 2; + %2 = newType Employee; + %3 = newType map; + %1 = NewMap %3; + %3 = newType Person; + %8 = ConstLoad name; + %9 = ConstLoad Jack; + %10 = ConstLoad age; + %11 = ConstLoad 25; + %12 = ConstLoad address; + %13 = ConstLoad Usa; + %5 = NewMap %7; + %14 = %5; %8 = ConstLoad jack; - %21 = %1[%8]; - %25 = %21; - %30 = ConstLoad true; - %30? bb1 : bb2; + %1[%8] = %14; + %18 = newType (string|(), int|()); + %11 = ConstLoad 2; + %9 = ConstLoad jack; + %22 = %1[%9]; + %26 = %22; + %31 = ConstLoad true; + %31? bb1 : bb2; } bb1 { - %28 = ConstLoad true; - %29 = %25; + %29 = ConstLoad true; + %30 = %26; GOTO bb3; } bb2 { - %28 = ConstLoad false; + %29 = ConstLoad false; GOTO bb3; } bb3 { - %28? bb4 : bb5; + %29? bb4 : bb5; } bb4 { - %27 = %29 is (); + %28 = %30 is (); GOTO bb6; } bb5 { - %27 = ConstLoad false; + %28 = ConstLoad false; GOTO bb6; } bb6 { - %27? bb7 : bb8; + %28? bb7 : bb8; } bb7 { - %20 = %29; + %21 = %30; GOTO bb24; } bb8 { - %30 = ConstLoad true; - %30? bb9 : bb10; + %31 = ConstLoad true; + %31? bb9 : bb10; } bb9 { - %43 = ConstLoad true; - %44 = %25; + %44 = ConstLoad true; + %45 = %26; GOTO bb11; } bb10 { - %43 = ConstLoad false; + %44 = ConstLoad false; GOTO bb11; } bb11 { - %43? bb12 : bb13; + %44? bb12 : bb13; } bb12 { - %42 = %44 is Employee; + %43 = %45 is Employee; GOTO bb14; } bb13 { - %42 = ConstLoad false; + %43 = ConstLoad false; GOTO bb14; } bb14 { - %42? bb15 : bb16; + %43? bb15 : bb16; } bb15 { - %13 = %44; - %9 = ConstLoad name; - %11 = %13[%9]; - %20 = %11; + %14 = %45; + %10 = ConstLoad name; + %12 = %14[%10]; + %21 = %12; GOTO bb24; } bb16 { - %30 = ConstLoad true; - %30? bb17 : bb18; + %31 = ConstLoad true; + %31? bb17 : bb18; } bb17 { - %61 = ConstLoad true; + %62 = ConstLoad true; GOTO bb19; } bb18 { - %61 = %25 is any; + %62 = %26 is any; GOTO bb19; } bb19 { - %61? bb20 : bb21; + %62? bb20 : bb21; } bb20 { - %60 = ConstLoad true; + %61 = ConstLoad true; GOTO bb22; } bb21 { - %60 = ConstLoad false; + %61 = ConstLoad false; GOTO bb22; } bb22 { - %60? bb23 : bb24; + %61? bb23 : bb24; } bb23 { - %71 = ConstLoad 0; - %20 = %71; + %72 = ConstLoad 0; + %21 = %72; GOTO bb24; } bb24 { - %12 = ConstLoad jack; - %74 = %1[%12]; - %78 = %74; - %30 = ConstLoad true; - %30? bb25 : bb26; + %13 = ConstLoad jack; + %75 = %1[%13]; + %79 = %75; + %31 = ConstLoad true; + %31? bb25 : bb26; } bb25 { - %81 = ConstLoad true; - %82 = %78; + %82 = ConstLoad true; + %83 = %79; GOTO bb27; } bb26 { - %81 = ConstLoad false; + %82 = ConstLoad false; GOTO bb27; } bb27 { - %81? bb28 : bb29; + %82? bb28 : bb29; } bb28 { - %80 = %82 is (); + %81 = %83 is (); GOTO bb30; } bb29 { - %80 = ConstLoad false; + %81 = ConstLoad false; GOTO bb30; } bb30 { - %80? bb31 : bb32; + %81? bb31 : bb32; } bb31 { - %73 = %82; + %74 = %83; GOTO bb48; } bb32 { - %30 = ConstLoad true; - %30? bb33 : bb34; + %31 = ConstLoad true; + %31? bb33 : bb34; } bb33 { - %96 = ConstLoad true; - %97 = %78; + %97 = ConstLoad true; + %98 = %79; GOTO bb35; } bb34 { - %96 = ConstLoad false; + %97 = ConstLoad false; GOTO bb35; } bb35 { - %96? bb36 : bb37; + %97? bb36 : bb37; } bb36 { - %95 = %97 is Employee; + %96 = %98 is Employee; GOTO bb38; } bb37 { - %95 = ConstLoad false; + %96 = ConstLoad false; GOTO bb38; } bb38 { - %95? bb39 : bb40; + %96? bb39 : bb40; } bb39 { - %13 = %97; - %7 = ConstLoad age; - %109 = %13[%7]; - %73 = %109; + %14 = %98; + %8 = ConstLoad age; + %110 = %14[%8]; + %74 = %110; GOTO bb48; } bb40 { - %30 = ConstLoad true; - %30? bb41 : bb42; + %31 = ConstLoad true; + %31? bb41 : bb42; } bb41 { - %114 = ConstLoad true; + %115 = ConstLoad true; GOTO bb43; } bb42 { - %114 = %78 is any; + %115 = %79 is any; GOTO bb43; } bb43 { - %114? bb44 : bb45; + %115? bb44 : bb45; } bb44 { - %113 = ConstLoad true; + %114 = ConstLoad true; GOTO bb46; } bb45 { - %113 = ConstLoad false; + %114 = ConstLoad false; GOTO bb46; } bb46 { - %113? bb47 : bb48; + %114? bb47 : bb48; } bb47 { - %71 = ConstLoad 0; - %73 = %71; + %72 = ConstLoad 0; + %74 = %72; GOTO bb48; } bb48 { - %0 = newArray %2[%10]; + %0 = newArray %18[%11]; GOTO bb49; } bb49 { From 08af771be34469b4aeb2abb923b080186f097f10 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 3 Jan 2023 19:58:43 +0530 Subject: [PATCH 09/58] Add typedesc details to NewArray instruction --- .../org/wso2/ballerinalang/compiler/bir/BIRGen.java | 6 +++++- .../compiler/bir/codegen/JvmInstructionGen.java | 10 +++++++--- .../compiler/bir/model/BIRNonTerminator.java | 7 +++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index a433d85f3f2f..fafccd6f34f7 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -2422,6 +2422,9 @@ private void visitTypedesc(Location pos, BType type, List varDcls) { public static String toNameString(BType t) { BTypeSymbol typeSymbol = t.tsymbol; + if (typeSymbol == null) { + return t.name.getValue(); + } if ((typeSymbol.kind == SymbolKind.RECORD || typeSymbol.kind == SymbolKind.OBJECT) && ((BStructureTypeSymbol) typeSymbol).typeDefinitionSymbol != null) { return Utils.encodeNonFunctionIdentifier(((BStructureTypeSymbol) typeSymbol) @@ -2889,9 +2892,10 @@ private void generateListConstructorExpr(BLangListConstructorExpr listConstructo new BIRNonTerminator.NewArray(listConstructorExpr.pos, listConstructorExprType, toVarRef, typedescOp, sizeOp, initialValues)); } else { + BType eType = ((BArrayType) Types.getReferredType(listConstructorExprType)).eType; setScopeAndEmit( new BIRNonTerminator.NewArray(listConstructorExpr.pos, listConstructorExprType, toVarRef, sizeOp, - initialValues)); + initialValues, typeDescMap.getOrDefault(toNameString(eType), null))); } this.env.targetOperand = toVarRef; } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java index 7e09bee989c5..bb9dbed5191d 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java @@ -1520,7 +1520,7 @@ void generateArrayNewIns(BIRNonTerminator.NewArray inst, int localVarOffset) { if (elementType.tag == TypeTags.RECORD || (elementType.tag == TypeTags.INTERSECTION && ((BIntersectionType) elementType).effectiveType.tag == TypeTags.RECORD)) { - visitNewRecordArray(elementType); + visitNewRecordArray(elementType, inst); } else { this.mv.visitMethodInsn(INVOKESPECIAL, ARRAY_VALUE_IMPL, JVM_INIT_METHOD, INIT_ARRAY, false); @@ -1535,14 +1535,18 @@ void generateArrayNewIns(BIRNonTerminator.NewArray inst, int localVarOffset) { } } - private void visitNewRecordArray(BType type) { + private void visitNewRecordArray(BType type, BIRNonTerminator.NewArray inst) { BType elementType = JvmCodeGenUtil.getReferredType(type); elementType = elementType.tag == TypeTags.INTERSECTION ? ((BIntersectionType) elementType).effectiveType : elementType; String typeOwner = JvmCodeGenUtil.getPackageName(type.tsymbol.pkgID) + MODULE_INIT_CLASS_NAME; String typedescFieldName = jvmTypeGen.getTypedescFieldName(toNameString(elementType)); - this.mv.visitFieldInsn(GETSTATIC, typeOwner, typedescFieldName, "L" + TYPEDESC_VALUE + ";"); + if (inst.rhsOp == null) { + this.mv.visitFieldInsn(GETSTATIC, typeOwner, typedescFieldName, "L" + TYPEDESC_VALUE + ";"); + } else { + this.loadVar(inst.rhsOp.variableDcl); + } this.mv.visitMethodInsn(INVOKESPECIAL, ARRAY_VALUE_IMPL, JVM_INIT_METHOD, INIT_ARRAY_WITH_INITIAL_VALUES, false); } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNonTerminator.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNonTerminator.java index 5be88e6f3069..b8da2c10d9e2 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNonTerminator.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNonTerminator.java @@ -294,6 +294,7 @@ public static class NewArray extends BIRNonTerminator { public BIROperand sizeOp; public BType type; public List values; + public BIROperand rhsOp; public NewArray(Location location, BType type, BIROperand lhsOp, BIROperand sizeOp, List values) { @@ -304,6 +305,12 @@ public NewArray(Location location, BType type, BIROperand lhsOp, BIROperand size this.values = values; } + public NewArray(Location location, BType type, BIROperand lhsOp, BIROperand sizeOp, + List values, BIROperand rhsOp) { + this(location, type, lhsOp, sizeOp, values); + this.rhsOp = rhsOp; + } + public NewArray(Location location, BType type, BIROperand lhsOp, BIROperand typedescOp, BIROperand sizeOp, List values) { this(location, type, lhsOp, sizeOp, values); From e0ce0352a7af685066317c996416218524770d0d Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Wed, 4 Jan 2023 15:31:26 +0530 Subject: [PATCH 10/58] Use PackageID of type --- .../compiler/bir/codegen/JvmInstructionGen.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java index bb9dbed5191d..614748d539e7 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java @@ -1321,10 +1321,11 @@ private int getJVMIndexOfVarRef(BIRNode.BIRVariableDcl varDcl) { } void generateMapNewIns(BIRNonTerminator.NewStructure mapNewIns, int localVarOffset) { - if (isNonReferredRecord(mapNewIns.type)) { - PackageID packageID = mapNewIns.lhsOp.variableDcl.type.tsymbol.pkgID; + BType type = mapNewIns.type; + if (isNonReferredRecord(type)) { + PackageID packageID = type.tsymbol.pkgID; String typeOwner = JvmCodeGenUtil.getPackageName(packageID) + MODULE_INIT_CLASS_NAME; - String fieldName = jvmTypeGen.getTypedescFieldName(toNameString(mapNewIns.type)); + String fieldName = jvmTypeGen.getTypedescFieldName(toNameString(type)); mv.visitFieldInsn(GETSTATIC, typeOwner, fieldName, GET_TYPEDESC); } else { this.loadVar(mapNewIns.rhsOp.variableDcl); From ed9d56f60b01a2744651c7e805361dd574b8357d Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Mon, 9 Jan 2023 11:05:53 +0530 Subject: [PATCH 11/58] Generate a typedesc instruction once for record and tuple types --- .../ballerinalang/compiler/bir/BIRGen.java | 194 +++--------------- .../bir/codegen/JvmInstructionGen.java | 11 +- .../bir/codegen/split/JvmCreateTypeGen.java | 68 +++--- .../compiler/semantics/analyzer/Types.java | 9 + 4 files changed, 89 insertions(+), 193 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index fafccd6f34f7..0634bba9d895 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -33,7 +33,6 @@ import org.ballerinalang.model.tree.OperatorKind; import org.ballerinalang.model.tree.TopLevelNode; import org.ballerinalang.model.tree.expressions.RecordLiteralNode; -import org.ballerinalang.model.types.TypeKind; import org.wso2.ballerinalang.compiler.bir.model.BIRNode; import org.wso2.ballerinalang.compiler.bir.model.BIRNode.BIRAnnotation; import org.wso2.ballerinalang.compiler.bir.model.BIRNode.BIRAnnotationAttachment; @@ -104,7 +103,6 @@ import org.wso2.ballerinalang.compiler.tree.BLangResourceFunction; import org.wso2.ballerinalang.compiler.tree.BLangService; import org.wso2.ballerinalang.compiler.tree.BLangSimpleVariable; -import org.wso2.ballerinalang.compiler.tree.BLangTableKeyTypeConstraint; import org.wso2.ballerinalang.compiler.tree.BLangTypeDefinition; import org.wso2.ballerinalang.compiler.tree.BLangVariable; import org.wso2.ballerinalang.compiler.tree.BLangXMLNS; @@ -195,23 +193,8 @@ import org.wso2.ballerinalang.compiler.tree.statements.BLangWhile; import org.wso2.ballerinalang.compiler.tree.statements.BLangWorkerSend; import org.wso2.ballerinalang.compiler.tree.statements.BLangXMLNSStatement; -import org.wso2.ballerinalang.compiler.tree.types.BLangArrayType; -import org.wso2.ballerinalang.compiler.tree.types.BLangBuiltInRefTypeNode; -import org.wso2.ballerinalang.compiler.tree.types.BLangConstrainedType; -import org.wso2.ballerinalang.compiler.tree.types.BLangErrorType; -import org.wso2.ballerinalang.compiler.tree.types.BLangFiniteTypeNode; -import org.wso2.ballerinalang.compiler.tree.types.BLangFunctionTypeNode; -import org.wso2.ballerinalang.compiler.tree.types.BLangIntersectionTypeNode; -import org.wso2.ballerinalang.compiler.tree.types.BLangObjectTypeNode; -import org.wso2.ballerinalang.compiler.tree.types.BLangRecordTypeNode; -import org.wso2.ballerinalang.compiler.tree.types.BLangStreamType; import org.wso2.ballerinalang.compiler.tree.types.BLangStructureTypeNode; -import org.wso2.ballerinalang.compiler.tree.types.BLangTableTypeNode; -import org.wso2.ballerinalang.compiler.tree.types.BLangTupleTypeNode; import org.wso2.ballerinalang.compiler.tree.types.BLangType; -import org.wso2.ballerinalang.compiler.tree.types.BLangUnionTypeNode; -import org.wso2.ballerinalang.compiler.tree.types.BLangUserDefinedType; -import org.wso2.ballerinalang.compiler.tree.types.BLangValueType; import org.wso2.ballerinalang.compiler.util.BArrayState; import org.wso2.ballerinalang.compiler.util.ClosureVarSymbol; import org.wso2.ballerinalang.compiler.util.CompilerContext; @@ -268,7 +251,7 @@ public class BIRGen extends BLangNodeVisitor { // This map is used to create dependencies for imported module global variables private Map dummyGlobalVarMapForLocks = new HashMap<>(); - private Map typeDescMap = new HashMap<>(); + private Map typeDescMap = new HashMap<>(); // This is to cache the lockstmt to BIR Lock private Map lockStmtMap = new HashMap<>(); @@ -1123,10 +1106,6 @@ public void visit(BLangSimpleVariableDef astVarDefStmt) { this.currentScope = newScope; } - if (astVarDefStmt.var.typeNode != null) { - astVarDefStmt.var.typeNode.accept(this); - } - if (astVarDefStmt.var.expr == null) { return; } @@ -1160,106 +1139,6 @@ public void visit(BLangSimpleVariable varNode) { env.enclPkg.isListenerAvailable |= Symbols.isFlagOn(varNode.symbol.flags, Flags.LISTENER); } - @Override - public void visit(BLangUserDefinedType userDefinedType) { - if (Types.getReferredType(userDefinedType.getBType()).getKind() == TypeKind.RECORD) { - visitTypedesc(userDefinedType.pos, userDefinedType.getBType(), Collections.emptyList()); - } - } - - @Override - public void visit(BLangValueType valueType) { - } - - @Override - public void visit(BLangUnionTypeNode unionTypeNode) { - unionTypeNode.memberTypeNodes.forEach(typeNode -> typeNode.accept(this)); - } - - @Override - public void visit(BLangRecordTypeNode recordTypeNode) { - for (BLangSimpleVariable field : recordTypeNode.fields) { - if (field.typeNode != null) { - field.typeNode.accept(this); - } - } - if (recordTypeNode.restFieldType != null) { - recordTypeNode.restFieldType.accept(this); - } - } - - @Override - public void visit(BLangArrayType arrayType) { - arrayType.elemtype.accept(this); - } - - @Override - public void visit(BLangConstrainedType constrainedType) { - constrainedType.constraint.accept(this); - } - - @Override - public void visit(BLangErrorType errorType) { - if (errorType.detailType != null) { - errorType.detailType.accept(this); - } - } - - @Override - public void visit(BLangFunctionTypeNode functionTypeNode) { - } - - @Override - public void visit(BLangBuiltInRefTypeNode builtInRefTypeNode) { - } - - @Override - public void visit(BLangTableTypeNode tableTypeNode) { - tableTypeNode.constraint.accept(this); - if (tableTypeNode.tableKeyTypeConstraint != null) { - tableTypeNode.tableKeyTypeConstraint.accept(this); - } - } - - @Override - public void visit(BLangTupleTypeNode tupleTypeNode) { - tupleTypeNode.memberTypeNodes.forEach(member -> member.accept(this)); - if (tupleTypeNode.restParamType != null) { - tupleTypeNode.restParamType.accept(this); - } - } - - @Override - public void visit(BLangStreamType streamType) { - streamType.type.accept(this); - streamType.constraint.accept(this); - if (streamType.error != null) { - streamType.error.accept(this); - } - } - - @Override - public void visit(BLangTableKeyTypeConstraint keyTypeConstraint) { - keyTypeConstraint.keyType.accept(this); - } - - @Override - public void visit(BLangObjectTypeNode objectTypeNode) { - for (BLangSimpleVariable field : objectTypeNode.fields) { - if (field.typeNode != null) { - field.typeNode.accept(this); - } - } - } - - @Override - public void visit(BLangFiniteTypeNode finiteTypeNode) { - } - - @Override - public void visit(BLangIntersectionTypeNode intersectionTypeNode) { - } - @Override public void visit(BLangAssignment astAssignStmt) { astAssignStmt.expr.accept(this); @@ -1717,7 +1596,7 @@ public void visit(BLangLiteral astLiteralExpr) { @Override public void visit(BLangMapLiteral astMapLiteralExpr) { - visitTypedesc(astMapLiteralExpr.pos, astMapLiteralExpr.getBType(), Collections.emptyList()); + createNewTypeDescInst(astMapLiteralExpr.pos, astMapLiteralExpr.getBType(), Collections.emptyList()); BIRVariableDcl tempVarDcl = new BIRVariableDcl(astMapLiteralExpr.getBType(), this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind.TEMP); @@ -1746,12 +1625,6 @@ public void visit(BLangTypeConversionExpr astTypeConversionExpr) { this.env.targetOperand = toVarRef; } - private boolean isNonReferredRecord(BType type) { - type = Types.getReferredType(type); - return type.tsymbol != null && type.tag == TypeTags.RECORD && - type.tsymbol.owner.getKind() == SymbolKind.PACKAGE; - } - @Override public void visit(BLangStructLiteral astStructLiteralExpr) { BType type = astStructLiteralExpr.getBType(); @@ -1761,19 +1634,14 @@ public void visit(BLangStructLiteral astStructLiteralExpr) { BIROperand toVarRef = new BIROperand(tempVarDcl); BIRNonTerminator.NewStructure instruction; - if (isNonReferredRecord(type)) { + if (Types.isUserDefinedTypeDefinition(type)) { instruction = new BIRNonTerminator.NewStructure(astStructLiteralExpr.pos, toVarRef, toVarRef, generateMappingConstructorEntries(astStructLiteralExpr.fields), type); - } else if (typeDescMap.containsKey(toNameString(type))) { - instruction = new BIRNonTerminator.NewStructure(astStructLiteralExpr.pos, toVarRef, - typeDescMap.get(toNameString(type)), + } else if (typeDescMap.containsKey(type)) { + instruction = new BIRNonTerminator.NewStructure(astStructLiteralExpr.pos, toVarRef, typeDescMap.get(type), generateMappingConstructorEntries(astStructLiteralExpr.fields), type); } else { - if (type.getKind() == TypeKind.RECORD) { - visitTypedesc(astStructLiteralExpr.pos, type, mapToVarDcls(((BRecordType) type).enclMapSymbols)); - } else { - visitTypedesc(astStructLiteralExpr.pos, type, Collections.emptyList()); - } + createNewTypeDescInst(astStructLiteralExpr.pos, type, mapToVarDcls(type)); instruction = new BIRNonTerminator.NewStructure(astStructLiteralExpr.pos, toVarRef, this.env.targetOperand, generateMappingConstructorEntries(astStructLiteralExpr.fields), type); } @@ -1782,7 +1650,8 @@ public void visit(BLangStructLiteral astStructLiteralExpr) { this.env.targetOperand = toVarRef; } - private List mapToVarDcls(TreeMap enclMapSymbols) { + private List mapToVarDcls(BType type) { + TreeMap enclMapSymbols = ((BRecordType) Types.getReferredType(type)).enclMapSymbols; if (enclMapSymbols == null || enclMapSymbols.size() == 0) { return Collections.emptyList(); } @@ -1827,31 +1696,22 @@ public void visit(BLangSimpleVarRef.BLangFieldVarRef fieldVarRef) { @Override public void visit(BLangArrayLiteral astArrayLiteralExpr) { - BType bType = astArrayLiteralExpr.getBType(); - if (bType.tag == TypeTags.TUPLE) { - visitTypedesc(astArrayLiteralExpr.pos, bType, Collections.emptyList()); - } generateListConstructorExpr(astArrayLiteralExpr); } @Override public void visit(BLangTupleLiteral tupleLiteral) { - visitTypedesc(tupleLiteral.pos, tupleLiteral.getBType(), Collections.emptyList()); generateListConstructorExpr(tupleLiteral); } @Override - public void visit(BLangGroupExpr groupExpr) { - groupExpr.expression.accept(this); + public void visit(BLangJSONArrayLiteral jsonArrayLiteralExpr) { + generateListConstructorExpr(jsonArrayLiteralExpr); } @Override - public void visit(BLangJSONArrayLiteral jsonArrayLiteralExpr) { - BType bType = jsonArrayLiteralExpr.getBType(); - if (bType.tag == TypeTags.TUPLE) { - visitTypedesc(jsonArrayLiteralExpr.pos, bType, Collections.emptyList()); - } - generateListConstructorExpr(jsonArrayLiteralExpr); + public void visit(BLangGroupExpr groupExpr) { + groupExpr.expression.accept(this); } @Override @@ -2133,7 +1993,7 @@ public void visit(BLangWaitExpr waitExpr) { @Override public void visit(BLangWaitForAllExpr.BLangWaitLiteral waitLiteral) { - visitTypedesc(waitLiteral.pos, waitLiteral.getBType(), Collections.emptyList()); + createNewTypeDescInst(waitLiteral.pos, waitLiteral.getBType(), Collections.emptyList()); BIRBasicBlock thenBB = new BIRBasicBlock(this.env.nextBBId(names)); addToTrapStack(thenBB); BIRVariableDcl tempVarDcl = new BIRVariableDcl(waitLiteral.getBType(), @@ -2404,10 +2264,10 @@ public void visit(BLangTableConstructorExpr tableConstructorExpr) { public void visit(BLangSimpleVarRef.BLangTypeLoad typeLoad) { BType type = typeLoad.symbol.tag == SymTag.TYPE_DEF ? ((BTypeDefinitionSymbol) typeLoad.symbol).referenceType : typeLoad.symbol.type; - visitTypedesc(typeLoad.pos, type, Collections.emptyList()); + createNewTypeDescInst(typeLoad.pos, type, Collections.emptyList()); } - private void visitTypedesc(Location pos, BType type, List varDcls) { + private void createNewTypeDescInst(Location pos, BType type, List varDcls) { BIRVariableDcl tempVarDcl = new BIRVariableDcl(symTable.typeDesc, this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind .TEMP); @@ -2416,7 +2276,7 @@ private void visitTypedesc(Location pos, BType type, List varDcls) { setScopeAndEmit(new BIRNonTerminator.NewTypeDesc(pos, toVarRef, type, varDcls)); this.env.targetOperand = toVarRef; if (type.tsymbol != null && type.tsymbol.owner.getKind() != SymbolKind.PACKAGE) { - typeDescMap.put(toNameString(type), toVarRef); + typeDescMap.put(type, toVarRef); } } @@ -2855,7 +2715,6 @@ private void generateListConstructorExpr(BLangListConstructorExpr listConstructo BIROperand toVarRef = new BIROperand(tempVarDcl); long size = -1L; - BIROperand typedescOp = null; List exprs = listConstructorExpr.exprs; BType listConstructorExprType = listConstructorExpr.getBType(); BType referredType = Types.getReferredType(listConstructorExprType); @@ -2863,7 +2722,6 @@ private void generateListConstructorExpr(BLangListConstructorExpr listConstructo ((BArrayType) referredType).state != BArrayState.OPEN) { size = ((BArrayType) referredType).size; } else if (referredType.tag == TypeTags.TUPLE) { - typedescOp = this.env.targetOperand; size = exprs.size(); } @@ -2888,14 +2746,24 @@ private void generateListConstructorExpr(BLangListConstructorExpr listConstructo } if (referredType.tag == TypeTags.TUPLE) { - setScopeAndEmit( - new BIRNonTerminator.NewArray(listConstructorExpr.pos, listConstructorExprType, toVarRef, - typedescOp, sizeOp, initialValues)); + if (Types.isUserDefinedTypeDefinition(referredType)) { + setScopeAndEmit( + new BIRNonTerminator.NewArray(listConstructorExpr.pos, listConstructorExprType, toVarRef, + toVarRef, sizeOp, initialValues)); + } else if (typeDescMap.containsKey(referredType)) { + setScopeAndEmit( + new BIRNonTerminator.NewArray(listConstructorExpr.pos, listConstructorExprType, toVarRef, + typeDescMap.get(referredType), sizeOp, initialValues)); + } else { + createNewTypeDescInst(listConstructorExpr.pos, listConstructorExprType, Collections.emptyList()); + setScopeAndEmit( + new BIRNonTerminator.NewArray(listConstructorExpr.pos, listConstructorExprType, toVarRef, + this.env.targetOperand, sizeOp, initialValues)); + } } else { - BType eType = ((BArrayType) Types.getReferredType(listConstructorExprType)).eType; setScopeAndEmit( new BIRNonTerminator.NewArray(listConstructorExpr.pos, listConstructorExprType, toVarRef, sizeOp, - initialValues, typeDescMap.getOrDefault(toNameString(eType), null))); + initialValues)); } this.env.targetOperand = toVarRef; } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java index 614748d539e7..b5183979ad03 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java @@ -1322,7 +1322,7 @@ private int getJVMIndexOfVarRef(BIRNode.BIRVariableDcl varDcl) { void generateMapNewIns(BIRNonTerminator.NewStructure mapNewIns, int localVarOffset) { BType type = mapNewIns.type; - if (isNonReferredRecord(type)) { + if (Types.isUserDefinedTypeDefinition(type)) { PackageID packageID = type.tsymbol.pkgID; String typeOwner = JvmCodeGenUtil.getPackageName(packageID) + MODULE_INIT_CLASS_NAME; String fieldName = jvmTypeGen.getTypedescFieldName(toNameString(type)); @@ -1528,7 +1528,14 @@ void generateArrayNewIns(BIRNonTerminator.NewArray inst, int localVarOffset) { } this.storeToVar(inst.lhsOp.variableDcl); } else { - this.loadVar(inst.typedescOp.variableDcl); + if (Types.isUserDefinedTypeDefinition(instType)) { + PackageID packageID = instType.tsymbol.pkgID; + String typeOwner = JvmCodeGenUtil.getPackageName(packageID) + MODULE_INIT_CLASS_NAME; + String fieldName = jvmTypeGen.getTypedescFieldName(toNameString(instType)); + mv.visitFieldInsn(GETSTATIC, typeOwner, fieldName, GET_TYPEDESC); + } else { + this.loadVar(inst.typedescOp.variableDcl); + } this.mv.visitVarInsn(ALOAD, localVarOffset); loadListInitialValues(inst); this.mv.visitMethodInsn(INVOKEINTERFACE, TYPEDESC_VALUE, "instantiate", INSTANTIATE, true); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java index b80fbefdc275..ef16828a3963 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java @@ -123,6 +123,7 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.SET_IMMUTABLE_TYPE_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRING_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.TYPE; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.TYPEDESC_VALUE_IMPL; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.TYPE_ID_SET; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.VISIT_MAX_SAFE_MARGIN; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ADD_TYPE_ID; @@ -264,41 +265,52 @@ private void createTypedescInstances(ClassWriter cw, List typ MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, CREATE_TYPEDESC_INSTANCES_METHOD, "()V", null, null); mv.visitCode(); - for (BIRTypeDefinition optionalTypeDef : typeDefs) { - BType bType = JvmCodeGenUtil.getReferredType(optionalTypeDef.type); - if (bType.tag == TypeTags.RECORD) { - BRecordType recordType = (BRecordType) bType; - BSymbol owner = recordType.tsymbol.owner; - if (owner != null && owner.getKind() != SymbolKind.PACKAGE) { - continue; - } - String packageName = JvmCodeGenUtil.getPackageName(recordType.tsymbol.pkgID); - String className = getTypeDescClassName(packageName, toNameString(recordType)); - mv.visitTypeInsn(NEW, className); - mv.visitInsn(DUP); - BType referenceType = optionalTypeDef.referenceType; - if (referenceType == null) { - jvmTypeGen.loadType(mv, JvmCodeGenUtil.getReferredType(optionalTypeDef.type)); - } else { - BType referredType = ((BTypeReferenceType) referenceType).referredType; - if (referredType.tag == TypeTags.TYPEREFDESC) { - jvmTypeGen.loadType(mv, referenceType); - } else { - jvmTypeGen.loadType(mv, referredType); - } - } - mv.visitInsn(ACONST_NULL); - mv.visitMethodInsn(INVOKESPECIAL, className, JVM_INIT_METHOD, TYPE_DESC_CONSTRUCTOR, false); - mv.visitFieldInsn(PUTSTATIC, moduleInitClass, - jvmTypeGen.getTypedescFieldName(optionalTypeDef.internalName.value), GET_TYPEDESC); + for (BIRTypeDefinition typeDefinition : typeDefs) { + BType bType = JvmCodeGenUtil.getReferredType(typeDefinition.type); + BSymbol owner = bType.tsymbol.owner; + if (owner != null && owner.getKind() != SymbolKind.PACKAGE) { + continue; } + createTypedescInstance(mv, bType, typeDefinition, moduleInitClass); } - mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } + + private void createTypedescInstance(MethodVisitor mv, BType bType, BIRTypeDefinition typeDefinition, + String moduleInitClass) { + String className; + if (bType.tag == TypeTags.RECORD) { + PackageID pkgID = bType.tsymbol.pkgID; + String packageName = JvmCodeGenUtil.getPackageName(pkgID); + className = getTypeDescClassName(packageName, toNameString(bType)); + } else if (bType.tag == TypeTags.TUPLE) { + className = TYPEDESC_VALUE_IMPL; + } else { + return; + } + + mv.visitTypeInsn(NEW, className); + mv.visitInsn(DUP); + BType referenceType = typeDefinition.referenceType; + if (referenceType == null) { + jvmTypeGen.loadType(mv, JvmCodeGenUtil.getReferredType(bType)); + } else { + BType referredType = ((BTypeReferenceType) referenceType).referredType; + if (referredType.tag == TypeTags.TYPEREFDESC) { + jvmTypeGen.loadType(mv, referenceType); + } else { + jvmTypeGen.loadType(mv, referredType); + } + } + mv.visitInsn(ACONST_NULL); + mv.visitMethodInsn(INVOKESPECIAL, className, JVM_INIT_METHOD, TYPE_DESC_CONSTRUCTOR, false); + mv.visitFieldInsn(PUTSTATIC, moduleInitClass, + jvmTypeGen.getTypedescFieldName(typeDefinition.internalName.value), GET_TYPEDESC); + } + private int createTypesInstanceSplits(ClassWriter cw, List typeDefs, String typeOwnerClass) { if (typeDefs.isEmpty()) { diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/Types.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/Types.java index 54cde1d34382..8b28fd640db1 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/Types.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/Types.java @@ -24,6 +24,7 @@ import org.ballerinalang.model.TreeBuilder; import org.ballerinalang.model.elements.Flag; import org.ballerinalang.model.elements.PackageID; +import org.ballerinalang.model.symbols.SymbolKind; import org.ballerinalang.model.tree.NodeKind; import org.ballerinalang.model.tree.OperatorKind; import org.ballerinalang.model.types.SelectivelyImmutableReferenceType; @@ -5401,6 +5402,14 @@ private BType getIntersectionForErrorTypes(IntersectionContext intersectionConte return intersectionErrorType; } + // This function checks whether the specified type definition is a user-defined type or not. + public static boolean isUserDefinedTypeDefinition(BType type) { + type = Types.getReferredType(type); + BTypeSymbol typeSymbol = type.tsymbol; + return typeSymbol != null && (type.tag == TypeTags.RECORD || type.tag == TypeTags.TUPLE) && + typeSymbol.name != Names.EMPTY && typeSymbol.owner.getKind() == SymbolKind.PACKAGE; + } + private BType createRecordIntersection(IntersectionContext intersectionContext, BRecordType recordTypeOne, BRecordType recordTypeTwo, SymbolEnv env, LinkedHashSet visitedTypes) { From 955f2eba0c5ba9e9bc6521922f6cc9c07caf6bfb Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 10 Jan 2023 00:56:07 +0530 Subject: [PATCH 12/58] Implemente visitors for type node --- .../ballerinalang/compiler/bir/BIRGen.java | 166 ++++++++++++++++-- 1 file changed, 147 insertions(+), 19 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index 0634bba9d895..3d25247aaf71 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -18,7 +18,6 @@ package org.wso2.ballerinalang.compiler.bir; -import io.ballerina.identifier.Utils; import io.ballerina.tools.diagnostics.Location; import io.ballerina.tools.text.LinePosition; import io.ballerina.tools.text.LineRange; @@ -33,6 +32,7 @@ import org.ballerinalang.model.tree.OperatorKind; import org.ballerinalang.model.tree.TopLevelNode; import org.ballerinalang.model.tree.expressions.RecordLiteralNode; +import org.ballerinalang.model.types.TypeKind; import org.wso2.ballerinalang.compiler.bir.model.BIRNode; import org.wso2.ballerinalang.compiler.bir.model.BIRNode.BIRAnnotation; import org.wso2.ballerinalang.compiler.bir.model.BIRNode.BIRAnnotationAttachment; @@ -72,7 +72,6 @@ import org.wso2.ballerinalang.compiler.semantics.model.symbols.BObjectTypeSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BResourceFunction; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BServiceSymbol; -import org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructureTypeSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BTypeDefinitionSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BTypeSymbol; @@ -103,6 +102,7 @@ import org.wso2.ballerinalang.compiler.tree.BLangResourceFunction; import org.wso2.ballerinalang.compiler.tree.BLangService; import org.wso2.ballerinalang.compiler.tree.BLangSimpleVariable; +import org.wso2.ballerinalang.compiler.tree.BLangTableKeyTypeConstraint; import org.wso2.ballerinalang.compiler.tree.BLangTypeDefinition; import org.wso2.ballerinalang.compiler.tree.BLangVariable; import org.wso2.ballerinalang.compiler.tree.BLangXMLNS; @@ -193,8 +193,23 @@ import org.wso2.ballerinalang.compiler.tree.statements.BLangWhile; import org.wso2.ballerinalang.compiler.tree.statements.BLangWorkerSend; import org.wso2.ballerinalang.compiler.tree.statements.BLangXMLNSStatement; +import org.wso2.ballerinalang.compiler.tree.types.BLangArrayType; +import org.wso2.ballerinalang.compiler.tree.types.BLangBuiltInRefTypeNode; +import org.wso2.ballerinalang.compiler.tree.types.BLangConstrainedType; +import org.wso2.ballerinalang.compiler.tree.types.BLangErrorType; +import org.wso2.ballerinalang.compiler.tree.types.BLangFiniteTypeNode; +import org.wso2.ballerinalang.compiler.tree.types.BLangFunctionTypeNode; +import org.wso2.ballerinalang.compiler.tree.types.BLangIntersectionTypeNode; +import org.wso2.ballerinalang.compiler.tree.types.BLangObjectTypeNode; +import org.wso2.ballerinalang.compiler.tree.types.BLangRecordTypeNode; +import org.wso2.ballerinalang.compiler.tree.types.BLangStreamType; import org.wso2.ballerinalang.compiler.tree.types.BLangStructureTypeNode; +import org.wso2.ballerinalang.compiler.tree.types.BLangTableTypeNode; +import org.wso2.ballerinalang.compiler.tree.types.BLangTupleTypeNode; import org.wso2.ballerinalang.compiler.tree.types.BLangType; +import org.wso2.ballerinalang.compiler.tree.types.BLangUnionTypeNode; +import org.wso2.ballerinalang.compiler.tree.types.BLangUserDefinedType; +import org.wso2.ballerinalang.compiler.tree.types.BLangValueType; import org.wso2.ballerinalang.compiler.util.BArrayState; import org.wso2.ballerinalang.compiler.util.ClosureVarSymbol; import org.wso2.ballerinalang.compiler.util.CompilerContext; @@ -710,6 +725,7 @@ public void visit(BLangFunction astFunc) { this.env.enclBB = entryBB; this.typeDescMap = new HashMap<>(); addToTrapStack(entryBB); + analyzeParametersAndReturnType(astFunc); astFunc.body.accept(this); birFunc.basicBlocks.add(this.env.returnBB); @@ -742,6 +758,20 @@ private BIRVariableDcl getSelf(BSymbol receiver) { return self; } + private void analyzeParametersAndReturnType(BLangFunction astFunc) { + if (astFunc.returnTypeNode != null) { + astFunc.returnTypeNode.accept(this); + } + for (BLangSimpleVariable parameter : astFunc.requiredParams) { + if (parameter.typeNode != null) { + parameter.typeNode.accept(this); + } + } + if (astFunc.restParam != null && astFunc.restParam.typeNode != null) { + astFunc.restParam.typeNode.accept(this); + } + } + @Override public void visit(BLangBlockFunctionBody astBody) { BIRBasicBlock endLoopEndBB = this.env.enclLoopEndBB; @@ -1106,12 +1136,17 @@ public void visit(BLangSimpleVariableDef astVarDefStmt) { this.currentScope = newScope; } - if (astVarDefStmt.var.expr == null) { + BLangSimpleVariable simpleVariable = astVarDefStmt.var; + if (simpleVariable.typeNode != null) { + simpleVariable.typeNode.accept(this); + } + + if (simpleVariable.expr == null) { return; } // Visit the rhs expression. - astVarDefStmt.var.expr.accept(this); + simpleVariable.expr.accept(this); // Create a variable reference and BIROperand varRef = new BIROperand(birVarDcl); @@ -1139,6 +1174,111 @@ public void visit(BLangSimpleVariable varNode) { env.enclPkg.isListenerAvailable |= Symbols.isFlagOn(varNode.symbol.flags, Flags.LISTENER); } + @Override + public void visit(BLangUserDefinedType userDefinedType) { + if (Types.getReferredType(userDefinedType.getBType()).getKind() == TypeKind.RECORD) { + createNewTypeDescInst(userDefinedType.pos, userDefinedType.getBType(), Collections.emptyList()); + } + } + + @Override + public void visit(BLangTupleTypeNode tupleTypeNode) { + createNewTypeDescInst(tupleTypeNode.pos, tupleTypeNode.getBType(), Collections.emptyList()); + tupleTypeNode.memberTypeNodes.forEach(member -> member.accept(this)); + if (tupleTypeNode.restParamType != null) { + tupleTypeNode.restParamType.accept(this); + } + } + + @Override + public void visit(BLangValueType valueType) { + } + + @Override + public void visit(BLangUnionTypeNode unionTypeNode) { + unionTypeNode.memberTypeNodes.forEach(typeNode -> typeNode.accept(this)); + } + + @Override + public void visit(BLangRecordTypeNode recordTypeNode) { + createNewTypeDescInst(recordTypeNode.pos, recordTypeNode.getBType(), Collections.emptyList()); + for (BLangSimpleVariable field : recordTypeNode.fields) { + if (field.typeNode != null) { + field.typeNode.accept(this); + } + } + if (recordTypeNode.restFieldType != null) { + recordTypeNode.restFieldType.accept(this); + } + } + + @Override + public void visit(BLangArrayType arrayType) { + arrayType.elemtype.accept(this); + } + + @Override + public void visit(BLangConstrainedType constrainedType) { + constrainedType.constraint.accept(this); + } + + @Override + public void visit(BLangErrorType errorType) { + if (errorType.detailType != null) { + errorType.detailType.accept(this); + } + } + + @Override + public void visit(BLangFunctionTypeNode functionTypeNode) { + } + + @Override + public void visit(BLangBuiltInRefTypeNode builtInRefTypeNode) { + } + + @Override + public void visit(BLangTableTypeNode tableTypeNode) { + tableTypeNode.constraint.accept(this); + if (tableTypeNode.tableKeyTypeConstraint != null) { + tableTypeNode.tableKeyTypeConstraint.accept(this); + } + } + + @Override + public void visit(BLangStreamType streamType) { + streamType.type.accept(this); + streamType.constraint.accept(this); + if (streamType.error != null) { + streamType.error.accept(this); + } + } + + @Override + public void visit(BLangTableKeyTypeConstraint keyTypeConstraint) { + keyTypeConstraint.keyType.accept(this); + } + + @Override + public void visit(BLangObjectTypeNode objectTypeNode) { + } + + @Override + public void visit(BLangFiniteTypeNode finiteTypeNode) { + } + + @Override + public void visit(BLangIntersectionTypeNode intersectionTypeNode) { + BType type = intersectionTypeNode.getBType(); + if (type.tag != TypeTags.INTERSECTION) { + return; + } + BType effectiveType = ((BIntersectionType) intersectionTypeNode.getBType()).effectiveType; + if (effectiveType.tag == TypeTags.RECORD || effectiveType.tag == TypeTags.TUPLE) { + createNewTypeDescInst(intersectionTypeNode.pos, effectiveType, Collections.emptyList()); + } + } + @Override public void visit(BLangAssignment astAssignStmt) { astAssignStmt.expr.accept(this); @@ -2280,19 +2420,6 @@ private void createNewTypeDescInst(Location pos, BType type, List va } } - public static String toNameString(BType t) { - BTypeSymbol typeSymbol = t.tsymbol; - if (typeSymbol == null) { - return t.name.getValue(); - } - if ((typeSymbol.kind == SymbolKind.RECORD || typeSymbol.kind == SymbolKind.OBJECT) && - ((BStructureTypeSymbol) typeSymbol).typeDefinitionSymbol != null) { - return Utils.encodeNonFunctionIdentifier(((BStructureTypeSymbol) typeSymbol) - .typeDefinitionSymbol.name.value); - } - return Utils.encodeNonFunctionIdentifier(typeSymbol.name.value); - } - @Override public void visit(BLangBreak breakStmt) { BIRLockDetailsHolder toUnlock = this.env.unlockVars.peek(); @@ -2761,9 +2888,10 @@ private void generateListConstructorExpr(BLangListConstructorExpr listConstructo this.env.targetOperand, sizeOp, initialValues)); } } else { + BType eType = ((BArrayType) Types.getReferredType(listConstructorExprType)).eType; setScopeAndEmit( - new BIRNonTerminator.NewArray(listConstructorExpr.pos, listConstructorExprType, toVarRef, sizeOp, - initialValues)); + new BIRNonTerminator.NewArray(listConstructorExpr.pos, listConstructorExprType, toVarRef, + typeDescMap.getOrDefault(eType, null), sizeOp, initialValues)); } this.env.targetOperand = toVarRef; } From 89b498192943f59fbc396a2dcc0161754add86fa Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 10 Jan 2023 00:58:00 +0530 Subject: [PATCH 13/58] Add BTypeReferenceType constructor for creating a read-only type reference to a referred type --- .../runtime/internal/types/BTypeReferenceType.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java index f43cd540dc0e..2ba7d36de3f4 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java @@ -47,6 +47,13 @@ public BTypeReferenceType(String typeName, Module pkg, int typeFlags, boolean re this.readOnly = readOnly; } + public BTypeReferenceType(Type referredType) { + super(referredType.getName(), referredType.getPkg(), Object.class); + this.typeFlags = (int) referredType.getFlags(); + this.referredType = referredType; + this.readOnly = true; + } + public void setReferredType(Type referredType) { this.referredType = referredType; } From e5875bae6f3e48246b43187f9a3490009e6d1303 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 10 Jan 2023 01:12:15 +0530 Subject: [PATCH 14/58] Generate type definition for tuple intersection with readonly --- .../io/ballerina/runtime/api/utils/TypeUtils.java | 7 +++++++ .../runtime/internal/values/TypedescValueImpl.java | 5 +++++ .../compiler/bir/codegen/JvmInstructionGen.java | 9 ++++----- .../compiler/bir/codegen/JvmTypeGen.java | 3 ++- .../compiler/bir/codegen/split/JvmCreateTypeGen.java | 12 ++++++------ .../compiler/bir/model/BIRNonTerminator.java | 7 ------- 6 files changed, 24 insertions(+), 19 deletions(-) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/TypeUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/TypeUtils.java index 59360d9ab29a..1b7aee1ee491 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/TypeUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/TypeUtils.java @@ -24,6 +24,7 @@ import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.types.BArrayType; import io.ballerina.runtime.internal.types.BFiniteType; +import io.ballerina.runtime.internal.types.BIntersectionType; import io.ballerina.runtime.internal.types.BType; import static io.ballerina.runtime.api.PredefinedTypes.TYPE_ANY; @@ -159,4 +160,10 @@ public static Type getReferredType(Type type) { return constraint; } + public static Type getEffectiveType(Type type) { + if (type.getTag() == TypeTags.INTERSECTION_TAG) { + return ((BIntersectionType) type).getEffectiveType(); + } + return type; + } } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java index 89a70fc2e7db..2bf72a50e488 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java @@ -25,11 +25,13 @@ import io.ballerina.runtime.api.values.BMapInitialValueEntry; import io.ballerina.runtime.api.values.BTypedesc; import io.ballerina.runtime.internal.scheduling.Strand; +import io.ballerina.runtime.internal.types.BTypeReferenceType; import io.ballerina.runtime.internal.types.BTypedescType; import io.ballerina.runtime.internal.util.exceptions.BallerinaException; import java.util.Map; +import static io.ballerina.runtime.api.utils.TypeUtils.getEffectiveType; import static io.ballerina.runtime.api.utils.TypeUtils.getReferredType; /** @@ -91,6 +93,9 @@ public Object instantiate(Strand s, BInitialValueEntry[] initialValues) { return new MapValueImpl(this.describingType, (BMapInitialValueEntry[]) initialValues); } else if (referredType.getTag() == TypeTags.TUPLE_TAG) { return new TupleValueImpl(this.describingType, (BListInitialValueEntry[]) initialValues); + } else if (getEffectiveType(referredType).getTag() == TypeTags.TUPLE_TAG) { + return new TupleValueImpl(new BTypeReferenceType(getEffectiveType(referredType)), + (BListInitialValueEntry[]) initialValues); } // This method will be overridden for user-defined types, therefor this line shouldn't be reached. throw new BallerinaException("Given type can't be instantiated at runtime : " + this.describingType); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java index b5183979ad03..87fe64b44dc3 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java @@ -1547,13 +1547,12 @@ private void visitNewRecordArray(BType type, BIRNonTerminator.NewArray inst) { BType elementType = JvmCodeGenUtil.getReferredType(type); elementType = elementType.tag == TypeTags.INTERSECTION ? ((BIntersectionType) elementType).effectiveType : elementType; - String typeOwner = JvmCodeGenUtil.getPackageName(type.tsymbol.pkgID) + MODULE_INIT_CLASS_NAME; - String typedescFieldName = - jvmTypeGen.getTypedescFieldName(toNameString(elementType)); - if (inst.rhsOp == null) { + if (inst.typedescOp == null) { + String typeOwner = JvmCodeGenUtil.getPackageName(type.tsymbol.pkgID) + MODULE_INIT_CLASS_NAME; + String typedescFieldName = jvmTypeGen.getTypedescFieldName(toNameString(elementType)); this.mv.visitFieldInsn(GETSTATIC, typeOwner, typedescFieldName, "L" + TYPEDESC_VALUE + ";"); } else { - this.loadVar(inst.rhsOp.variableDcl); + this.loadVar(inst.typedescOp.variableDcl); } this.mv.visitMethodInsn(INVOKESPECIAL, ARRAY_VALUE_IMPL, JVM_INIT_METHOD, INIT_ARRAY_WITH_INITIAL_VALUES, false); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmTypeGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmTypeGen.java index 59733f387f79..63315580a9e4 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmTypeGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmTypeGen.java @@ -32,6 +32,7 @@ import org.wso2.ballerinalang.compiler.semantics.analyzer.IsAnydataUniqueVisitor; import org.wso2.ballerinalang.compiler.semantics.analyzer.IsPureTypeUniqueVisitor; import org.wso2.ballerinalang.compiler.semantics.analyzer.TypeHashVisitor; +import org.wso2.ballerinalang.compiler.semantics.analyzer.Types; import org.wso2.ballerinalang.compiler.semantics.model.SymbolTable; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableTypeSymbol; @@ -227,7 +228,7 @@ void generateUserDefinedTypeFields(ClassWriter cw, List typeD for (BIRTypeDefinition typeDef : typeDefs) { BType bType = JvmCodeGenUtil.getReferredType(typeDef.type); if (bType.tag == TypeTags.RECORD || bType.tag == TypeTags.ERROR || bType.tag == TypeTags.OBJECT - || bType.tag == TypeTags.UNION || bType.tag == TypeTags.TUPLE) { + || bType.tag == TypeTags.UNION || Types.getEffectiveType(bType).tag == TypeTags.TUPLE) { String name = typeDef.internalName.value; generateTypeField(cw, name); generateTypedescField(cw, name); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java index ef16828a3963..28538ee25451 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java @@ -278,7 +278,6 @@ private void createTypedescInstances(ClassWriter cw, List typ mv.visitEnd(); } - private void createTypedescInstance(MethodVisitor mv, BType bType, BIRTypeDefinition typeDefinition, String moduleInitClass) { String className; @@ -286,7 +285,8 @@ private void createTypedescInstance(MethodVisitor mv, BType bType, BIRTypeDefini PackageID pkgID = bType.tsymbol.pkgID; String packageName = JvmCodeGenUtil.getPackageName(pkgID); className = getTypeDescClassName(packageName, toNameString(bType)); - } else if (bType.tag == TypeTags.TUPLE) { + } else if (Types.getEffectiveType(bType).tag == TypeTags.TUPLE) { + bType = Types.getEffectiveType(bType); className = TYPEDESC_VALUE_IMPL; } else { return; @@ -299,7 +299,7 @@ private void createTypedescInstance(MethodVisitor mv, BType bType, BIRTypeDefini jvmTypeGen.loadType(mv, JvmCodeGenUtil.getReferredType(bType)); } else { BType referredType = ((BTypeReferenceType) referenceType).referredType; - if (referredType.tag == TypeTags.TYPEREFDESC) { + if (referredType.tag == TypeTags.TYPEREFDESC || bType.tag == TypeTags.TUPLE) { jvmTypeGen.loadType(mv, referenceType); } else { jvmTypeGen.loadType(mv, referredType); @@ -325,7 +325,7 @@ private int createTypesInstanceSplits(ClassWriter cw, List ty String name = optionalTypeDef.internalName.value; BType bType = JvmCodeGenUtil.getReferredType(optionalTypeDef.type); if (bType.tag != TypeTags.RECORD && bType.tag != TypeTags.OBJECT && bType.tag != TypeTags.ERROR && - bType.tag != TypeTags.UNION && bType.tag != TypeTags.TUPLE) { + bType.tag != TypeTags.UNION && Types.getEffectiveType(bType).tag != TypeTags.TUPLE) { // do not generate anything for other types (e.g.: finite type, etc.) continue; } else { @@ -335,7 +335,7 @@ private int createTypesInstanceSplits(ClassWriter cw, List ty mv.visitCode(); } } - switch (bType.tag) { + switch (Types.getEffectiveType(bType).tag) { case TypeTags.RECORD: jvmRecordTypeGen.createRecordType(mv, (BRecordType) bType); break; @@ -346,7 +346,7 @@ private int createTypesInstanceSplits(ClassWriter cw, List ty jvmErrorTypeGen.createErrorType(mv, (BErrorType) bType, bType.tsymbol.name.value); break; case TypeTags.TUPLE: - jvmTupleTypeGen.createTupleType(mv, (BTupleType) bType); + jvmTupleTypeGen.createTupleType(mv, (BTupleType) Types.getEffectiveType(bType)); break; default: jvmUnionTypeGen.createUnionType(mv, (BUnionType) bType); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNonTerminator.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNonTerminator.java index b8da2c10d9e2..5be88e6f3069 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNonTerminator.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNonTerminator.java @@ -294,7 +294,6 @@ public static class NewArray extends BIRNonTerminator { public BIROperand sizeOp; public BType type; public List values; - public BIROperand rhsOp; public NewArray(Location location, BType type, BIROperand lhsOp, BIROperand sizeOp, List values) { @@ -305,12 +304,6 @@ public NewArray(Location location, BType type, BIROperand lhsOp, BIROperand size this.values = values; } - public NewArray(Location location, BType type, BIROperand lhsOp, BIROperand sizeOp, - List values, BIROperand rhsOp) { - this(location, type, lhsOp, sizeOp, values); - this.rhsOp = rhsOp; - } - public NewArray(Location location, BType type, BIROperand lhsOp, BIROperand typedescOp, BIROperand sizeOp, List values) { this(location, type, lhsOp, sizeOp, values); From 2097769d214737a10176096ba4617e8dfa35d7b2 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 10 Jan 2023 01:13:16 +0530 Subject: [PATCH 15/58] Update BIR test --- .../test-src/bir/bir-dump/failLockWithinLock | 132 +++++++++--------- .../resources/test-src/bir/bir-dump/mapInits | 72 +++++----- 2 files changed, 104 insertions(+), 100 deletions(-) diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/failLockWithinLock b/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/failLockWithinLock index b1ddbf4699f7..748fd9a295be 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/failLockWithinLock +++ b/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/failLockWithinLock @@ -1,119 +1,123 @@ failLockWithinLock function() -> (int, string) { %0(RETURN) (int, string); - %1(SYNTHETIC) error|(); - %4(SYNTHETIC) error|(); - %7(SYNTHETIC) error|(); - %10(TEMP) boolean; - %12(TEMP) error; - %14(LOCAL) error; - %16(TEMP) string; - %18(TEMP) (); - %19(TEMP) typeDesc; - %20(TEMP) map; - %21(TEMP) string; + %1(TEMP) typeDesc; + %2(SYNTHETIC) error|(); + %5(SYNTHETIC) error|(); + %8(SYNTHETIC) error|(); + %11(TEMP) boolean; + %13(TEMP) error; + %15(LOCAL) error; + %17(TEMP) string; + %19(TEMP) (); + %20(TEMP) typeDesc; + %21(TEMP) map; %22(TEMP) string; - %23(TEMP) map; - %24(LOCAL) error; + %23(TEMP) string; + %24(TEMP) map; + %25(LOCAL) error; %41(TEMP) int; bb0 { - lock -> bb1; + %1 = newType (int, string); + GOTO bb1; } bb1 { - lockWithinLockInt = ConstLoad 50; - lockWithinLockString = ConstLoad sample value; lock -> bb2; } bb2 { - lockWithinLockString = ConstLoad second sample value; - lockWithinLockInt = ConstLoad 99; + lockWithinLockInt = ConstLoad 50; + lockWithinLockString = ConstLoad sample value; lock -> bb3; } bb3 { - lockWithinLockInt = ConstLoad 90; - %7 = ConstLoad 0; - GOTO bb4; + lockWithinLockString = ConstLoad second sample value; + lockWithinLockInt = ConstLoad 99; + lock -> bb4; } bb4 { - unlock -> bb5; + lockWithinLockInt = ConstLoad 90; + %8 = ConstLoad 0; + GOTO bb5; } bb5 { - %10 = %7 is error; - %10? bb6 : bb7; + unlock -> bb6; } bb6 { - %12 = %7; - panic %12; + %11 = %8 is error; + %11? bb7 : bb8; } bb7 { - %16 = ConstLoad custom error; - %18 = ConstLoad 0; - %12 = %18; - %19 = newType map; - %21 = ConstLoad message; - %22 = ConstLoad error value; - %20 = NewMap %19; - %23 = cloneReadOnly(%20) -> bb8; + %13 = %8; + panic %13; } bb8 { - %14 = error error(%16, %12, %23); - GOTO bb9; + %17 = ConstLoad custom error; + %19 = ConstLoad 0; + %13 = %19; + %20 = newType map; + %22 = ConstLoad message; + %23 = ConstLoad error value; + %21 = NewMap %20; + %24 = cloneReadOnly(%21) -> bb9; } bb9 { - unlock -> bb10; + %15 = error error(%17, %13, %24); + GOTO bb10; } bb10 { - %24 = %14; - lockWithinLockInt = ConstLoad 100; - lockWithinLockString = ConstLoad Error caught; - %18 = ConstLoad 0; - GOTO bb15; + unlock -> bb11; } bb11 { - %4 = ConstLoad 0; - GOTO bb15; + %25 = %15; + lockWithinLockInt = ConstLoad 100; + lockWithinLockString = ConstLoad Error caught; + %19 = ConstLoad 0; + GOTO bb16; } bb12 { - unlock -> bb13; + %5 = ConstLoad 0; + GOTO bb16; } bb13 { - %10 = %4 is error; - %10? bb14 : bb15; + unlock -> bb14; } bb14 { - %12 = %4; - panic %12; + %11 = %5 is error; + %11? bb15 : bb16; } bb15 { - %1 = ConstLoad 0; - GOTO bb16; + %13 = %5; + panic %13; } bb16 { - unlock -> bb17; + %2 = ConstLoad 0; + GOTO bb17; } bb17 { - %10 = %1 is error; - %10? bb18 : bb19; + unlock -> bb18; } bb18 { - %12 = %1; - panic %12; + %11 = %2 is error; + %11? bb19 : bb20; } bb19 { - %19 = newType (int, string); - %41 = ConstLoad 2; - %0 = newArray %19[%41]; - GOTO bb20; + %13 = %2; + panic %13; } bb20 { + %41 = ConstLoad 2; + %0 = newArray %1[%41]; + GOTO bb21; + } + bb21 { return; } ------------------------------------------------------------- | trapBB | endBB | targetBB | errorOp | ------------------------------------------------------------- - | bb1 | bb15 | bb16 | %1 | - | bb2 | bb11 | bb12 | %4 | - | bb3 | bb3 | bb4 | %7 | + | bb2 | bb16 | bb17 | %2 | + | bb3 | bb12 | bb13 | %5 | + | bb4 | bb4 | bb5 | %8 | ------------------------------------------------------------- -} +} \ No newline at end of file diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/mapInits b/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/mapInits index 5852e315454a..e34ab7ea803c 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/mapInits +++ b/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/mapInits @@ -1,17 +1,17 @@ mapInits function() -> (string|(), int|()) { %0(RETURN) (string|(), int|()); - %1(LOCAL) map; - %2(TEMP) typeDesc; + %1(TEMP) typeDesc; + %2(LOCAL) map; %3(TEMP) typeDesc; - %5(LOCAL) Person; - %8(TEMP) string; + %4(TEMP) typeDesc; + %6(LOCAL) Person; %9(TEMP) string; %10(TEMP) string; - %11(TEMP) int; - %12(TEMP) string; + %11(TEMP) string; + %12(TEMP) int; %13(TEMP) string; - %14(TEMP) Employee; - %18(TEMP) typeDesc; + %14(TEMP) string; + %15(TEMP) Employee; %21(SYNTHETIC) string|(); %22(SYNTHETIC) Employee|(); %26(SYNTHETIC) Employee|(); @@ -39,24 +39,24 @@ mapInits function() -> (string|(), int|()) { %115(SYNTHETIC) boolean; bb0 { - %2 = newType Employee; - %3 = newType map; - %1 = NewMap %3; - %3 = newType Person; - %8 = ConstLoad name; - %9 = ConstLoad Jack; - %10 = ConstLoad age; - %11 = ConstLoad 25; - %12 = ConstLoad address; - %13 = ConstLoad Usa; - %5 = NewMap %7; - %14 = %5; - %8 = ConstLoad jack; - %1[%8] = %14; - %18 = newType (string|(), int|()); - %11 = ConstLoad 2; + %1 = newType (string|(), int|()); + %3 = newType Employee; + %4 = newType map; + %2 = NewMap %4; + %4 = newType Person; + %9 = ConstLoad name; + %10 = ConstLoad Jack; + %11 = ConstLoad age; + %12 = ConstLoad 25; + %13 = ConstLoad address; + %14 = ConstLoad Usa; + %6 = NewMap %8; + %15 = %6; %9 = ConstLoad jack; - %22 = %1[%9]; + %2[%9] = %15; + %12 = ConstLoad 2; + %10 = ConstLoad jack; + %22 = %2[%10]; %26 = %22; %31 = ConstLoad true; %31? bb1 : bb2; @@ -116,10 +116,10 @@ mapInits function() -> (string|(), int|()) { %43? bb15 : bb16; } bb15 { - %14 = %45; - %10 = ConstLoad name; - %12 = %14[%10]; - %21 = %12; + %15 = %45; + %11 = ConstLoad name; + %13 = %15[%11]; + %21 = %13; GOTO bb24; } bb16 { @@ -154,8 +154,8 @@ mapInits function() -> (string|(), int|()) { GOTO bb24; } bb24 { - %13 = ConstLoad jack; - %75 = %1[%13]; + %14 = ConstLoad jack; + %75 = %2[%14]; %79 = %75; %31 = ConstLoad true; %31? bb25 : bb26; @@ -215,9 +215,9 @@ mapInits function() -> (string|(), int|()) { %96? bb39 : bb40; } bb39 { - %14 = %98; - %8 = ConstLoad age; - %110 = %14[%8]; + %15 = %98; + %9 = ConstLoad age; + %110 = %15[%9]; %74 = %110; GOTO bb48; } @@ -253,7 +253,7 @@ mapInits function() -> (string|(), int|()) { GOTO bb48; } bb48 { - %0 = newArray %18[%11]; + %0 = newArray %1[%12]; GOTO bb49; } bb49 { @@ -261,4 +261,4 @@ mapInits function() -> (string|(), int|()) { } -} +} \ No newline at end of file From 4f85ee549b751790c43dae70b28f8f159bedd7fb Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 10 Jan 2023 01:13:49 +0530 Subject: [PATCH 16/58] Update error meesage --- .../test-src/typedefs/tuple-type-definitions-cyclic.bal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/typedefs/tuple-type-definitions-cyclic.bal b/tests/jballerina-unit-test/src/test/resources/test-src/typedefs/tuple-type-definitions-cyclic.bal index 17756532dbb7..dfdd6424f4aa 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/typedefs/tuple-type-definitions-cyclic.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/typedefs/tuple-type-definitions-cyclic.bal @@ -277,7 +277,7 @@ function testCastingToImmutableCyclicTuple() { assert(b is error, true); error err = b; assert(err.message(), "{ballerina}TypeCastError"); - assert( checkpanic err.detail()["message"], "incompatible types: '[int,MyCyclicTuple[]]' " + + assert( checkpanic err.detail()["message"], "incompatible types: 'MyCyclicTuple' " + "cannot be cast to '[int,([int,MyCyclicTuple[]][] & readonly)] & readonly'"); MyCyclicTuple c = <[int, MyCyclicTuple[]] & readonly> [1, []]; MyCyclicTuple & readonly d = c; From 722f9e116a722c9f7d332dea5b1112436f056f1c Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 10 Jan 2023 10:14:07 +0530 Subject: [PATCH 17/58] Use referred type of type reference --- .../main/java/io/ballerina/runtime/internal/TypeChecker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java index 2bb06c4ab211..d70a1d9713d6 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java @@ -2190,7 +2190,7 @@ private static boolean checkIsNeverTypeOrStructureTypeWithARequiredNeverMember(T private static boolean checkIsLikeType(List errors, Object sourceValue, Type targetType, List unresolvedValues, boolean allowNumericConversion, String varName) { - Type sourceType = getType(sourceValue); + Type sourceType = getReferredType(getType(sourceValue)); if (checkIsType(sourceType, targetType, new ArrayList<>())) { return true; } From 83e3fa82ce302becace852351451c70e5b1a2f26 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 10 Jan 2023 10:14:41 +0530 Subject: [PATCH 18/58] Update test --- .../langlib-test/src/test/resources/test-src/valuelib_test.bal | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/langlib/langlib-test/src/test/resources/test-src/valuelib_test.bal b/langlib/langlib-test/src/test/resources/test-src/valuelib_test.bal index 8746f7a72daa..edc7869e7936 100644 --- a/langlib/langlib-test/src/test/resources/test-src/valuelib_test.bal +++ b/langlib/langlib-test/src/test/resources/test-src/valuelib_test.bal @@ -584,8 +584,7 @@ function testCloneWithTypeTupleToJSON() { assert(jsonValue is error, true); err = jsonValue; assert(err.message(), "{ballerina/lang.value}ConversionError"); - assert( checkpanic err.detail()["message"], "'[int,(string|xml<(lang.xml:Element|lang.xml:Comment|" + - "lang.xml:ProcessingInstruction|lang.xml:Text)>),A...]' value cannot be converted to 'json'"); + assert( checkpanic err.detail()["message"], "'A' value cannot be converted to 'json'"); } function testCloneWithTypeJsonRec1() { From d7dc5551565c29a80cf6cca838a982a4895d9e43 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 10 Jan 2023 11:08:19 +0530 Subject: [PATCH 19/58] Update code-coverage test --- .../org/ballerinalang/testerina/test/TestReportTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/testerina-integration-test/src/test/java/org/ballerinalang/testerina/test/TestReportTest.java b/tests/testerina-integration-test/src/test/java/org/ballerinalang/testerina/test/TestReportTest.java index ab61a1f5bd16..d2c4f4fc6c3f 100644 --- a/tests/testerina-integration-test/src/test/java/org/ballerinalang/testerina/test/TestReportTest.java +++ b/tests/testerina-integration-test/src/test/java/org/ballerinalang/testerina/test/TestReportTest.java @@ -207,8 +207,8 @@ private void validateCoverage() { float mathPercentage = (float) (Math.round(mathPercentageVal * 100.0) / 100.0); //foo module - int[] fooMainCovered = new int[]{19, 22, 23, 24, 29, 30, 36, 37, 42, 43, 50, 55, 56, 57, 60, 61, 64, 65, 69, - 70, 71, 74, 75}, fooMainMissed = new int[]{26}; + int[] fooMainCovered = new int[]{19, 22, 23, 24, 29, 30, 36, 37, 42, 43, 50, 55, 56, 57, 59, 60, 61, 64, 65, + 68, 69, 70, 71, 74, 75}, fooMainMissed = new int[]{26}; float fooMainPercentageVal = (float) (fooMainCovered.length) / (fooMainCovered.length + fooMainMissed.length) * 100; float fooMainPercentage = @@ -323,7 +323,7 @@ private void validateModuleWiseCoverage() { //foo module int[] fooMainCovered = new int[]{}, fooMainMissed = new int[]{19, 22, 23, 24, 26, 29, 30, 36, 37, - 42, 43, 50, 55, 56, 57, 60, 61, 64, 65, 69, 70, 71, 74, 75}; + 42, 43, 50, 55, 56, 57, 59, 60, 61, 64, 65, 68, 69, 70, 71, 74, 75}; float fooMainPercentageVal = (float) (fooMainCovered.length) / (fooMainCovered.length + fooMainMissed.length) * 100; float fooMainPercentage = (float) (Math.round(fooMainPercentageVal * 100.0) / 100.0); From 2ea5364e480f2d53d0506d129e35969add0de8bc Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 10 Jan 2023 11:29:25 +0530 Subject: [PATCH 20/58] Fix review suggestion --- .../compiler/bir/codegen/JvmInstructionGen.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java index 87fe64b44dc3..8aefd41449b5 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java @@ -21,7 +21,6 @@ import io.ballerina.identifier.Utils; import org.ballerinalang.compiler.BLangCompilerException; import org.ballerinalang.model.elements.PackageID; -import org.ballerinalang.model.symbols.SymbolKind; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.wso2.ballerinalang.compiler.bir.codegen.internal.AsyncDataCollector; @@ -2104,7 +2103,7 @@ void generateNegateIns(BIRNonTerminator.UnaryOP unaryOp) { void generateNewTypedescIns(BIRNonTerminator.NewTypeDesc newTypeDesc) { List closureVars = newTypeDesc.closureVars; - if (isNonReferredRecord(newTypeDesc.type)) { + if (Types.isUserDefinedTypeDefinition(newTypeDesc.type)) { BType type = newTypeDesc.type; PackageID packageID = type.tsymbol.pkgID; String typeOwner = JvmCodeGenUtil.getPackageName(packageID) + MODULE_INIT_CLASS_NAME; @@ -2116,12 +2115,6 @@ void generateNewTypedescIns(BIRNonTerminator.NewTypeDesc newTypeDesc) { this.storeToVar(newTypeDesc.lhsOp.variableDcl); } - private boolean isNonReferredRecord(BType type) { - type = Types.getReferredType(type); - return type.tsymbol != null && type.tag == TypeTags.RECORD && - type.tsymbol.owner.getKind() == SymbolKind.PACKAGE; - } - private void generateNewTypedescCreate(BType btype, List closureVars) { BType type = JvmCodeGenUtil.getReferredType(btype); String className = TYPEDESC_VALUE_IMPL; From c444f9fd8523c3dd5b7feb58943dc193d23ff9d4 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 10 Jan 2023 14:02:03 +0530 Subject: [PATCH 21/58] Fix review suggestions --- .../runtime/api/utils/TypeUtils.java | 8 ----- .../internal/types/BTypeReferenceType.java | 6 ++-- .../runtime/internal/util/RuntimeUtils.java | 8 +++++ .../internal/values/TypedescValueImpl.java | 9 ++--- .../ballerinalang/compiler/bir/BIRGen.java | 35 +++++++++++++++---- .../resources/test-src/bir/bir-dump/mapInits | 2 +- 6 files changed, 45 insertions(+), 23 deletions(-) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/TypeUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/TypeUtils.java index 1b7aee1ee491..180fe6c77fa4 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/TypeUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/TypeUtils.java @@ -24,7 +24,6 @@ import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.types.BArrayType; import io.ballerina.runtime.internal.types.BFiniteType; -import io.ballerina.runtime.internal.types.BIntersectionType; import io.ballerina.runtime.internal.types.BType; import static io.ballerina.runtime.api.PredefinedTypes.TYPE_ANY; @@ -159,11 +158,4 @@ public static Type getReferredType(Type type) { } return constraint; } - - public static Type getEffectiveType(Type type) { - if (type.getTag() == TypeTags.INTERSECTION_TAG) { - return ((BIntersectionType) type).getEffectiveType(); - } - return type; - } } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java index 2ba7d36de3f4..231645a021f5 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java @@ -48,10 +48,8 @@ public BTypeReferenceType(String typeName, Module pkg, int typeFlags, boolean re } public BTypeReferenceType(Type referredType) { - super(referredType.getName(), referredType.getPkg(), Object.class); - this.typeFlags = (int) referredType.getFlags(); - this.referredType = referredType; - this.readOnly = true; + this(referredType.getName(), referredType.getPkg(), (int) referredType.getFlags(), true); + setReferredType(referredType); } public void setReferredType(Type referredType) { diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/RuntimeUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/RuntimeUtils.java index c914ad6242aa..c2bb50dd77c9 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/RuntimeUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/RuntimeUtils.java @@ -29,6 +29,7 @@ import io.ballerina.runtime.internal.TypeConverter; import io.ballerina.runtime.internal.diagnostics.RuntimeDiagnosticLog; import io.ballerina.runtime.internal.types.BArrayType; +import io.ballerina.runtime.internal.types.BIntersectionType; import io.ballerina.runtime.internal.values.ArrayValue; import io.ballerina.runtime.internal.values.ArrayValueImpl; import io.ballerina.runtime.internal.values.ErrorValue; @@ -247,4 +248,11 @@ private static boolean isInvalidBallerinaValue(Object value) { private RuntimeUtils() { } + + public static Type getEffectiveType(Type type) { + if (type.getTag() == TypeTags.INTERSECTION_TAG) { + return ((BIntersectionType) type).getEffectiveType(); + } + return type; + } } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java index 2bf72a50e488..cd2045d8e10a 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java @@ -31,8 +31,8 @@ import java.util.Map; -import static io.ballerina.runtime.api.utils.TypeUtils.getEffectiveType; import static io.ballerina.runtime.api.utils.TypeUtils.getReferredType; +import static io.ballerina.runtime.internal.util.RuntimeUtils.getEffectiveType; /** *

@@ -93,9 +93,10 @@ public Object instantiate(Strand s, BInitialValueEntry[] initialValues) { return new MapValueImpl(this.describingType, (BMapInitialValueEntry[]) initialValues); } else if (referredType.getTag() == TypeTags.TUPLE_TAG) { return new TupleValueImpl(this.describingType, (BListInitialValueEntry[]) initialValues); - } else if (getEffectiveType(referredType).getTag() == TypeTags.TUPLE_TAG) { - return new TupleValueImpl(new BTypeReferenceType(getEffectiveType(referredType)), - (BListInitialValueEntry[]) initialValues); + } + Type effectiveType = getEffectiveType(referredType); + if (effectiveType.getTag() == TypeTags.TUPLE_TAG) { + return new TupleValueImpl(new BTypeReferenceType(effectiveType), (BListInitialValueEntry[]) initialValues); } // This method will be overridden for user-defined types, therefor this line shouldn't be reached. throw new BallerinaException("Given type can't be instantiated at runtime : " + this.describingType); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index 3d25247aaf71..c45b4ba772e2 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -759,16 +759,22 @@ private BIRVariableDcl getSelf(BSymbol receiver) { } private void analyzeParametersAndReturnType(BLangFunction astFunc) { - if (astFunc.returnTypeNode != null) { - astFunc.returnTypeNode.accept(this); + BLangType typeNode = astFunc.returnTypeNode; + if (typeNode != null) { + typeNode.accept(this); } for (BLangSimpleVariable parameter : astFunc.requiredParams) { - if (parameter.typeNode != null) { - parameter.typeNode.accept(this); + typeNode = parameter.typeNode; + if (typeNode != null) { + typeNode.accept(this); } } - if (astFunc.restParam != null && astFunc.restParam.typeNode != null) { - astFunc.restParam.typeNode.accept(this); + BLangSimpleVariable restParam = astFunc.restParam; + if (restParam != null) { + typeNode = restParam.typeNode; + if (typeNode != null) { + typeNode.accept(this); + } } } @@ -1231,6 +1237,23 @@ public void visit(BLangErrorType errorType) { @Override public void visit(BLangFunctionTypeNode functionTypeNode) { + BLangType typeNode = functionTypeNode.returnTypeNode; + if (typeNode != null) { + typeNode.accept(this); + } + for (BLangSimpleVariable parameter : functionTypeNode.params) { + typeNode = parameter.typeNode; + if (typeNode != null) { + typeNode.accept(this); + } + } + BLangVariable restParam = functionTypeNode.restParam; + if (restParam != null) { + typeNode = restParam.typeNode; + if (typeNode != null) { + typeNode.accept(this); + } + } } @Override diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/mapInits b/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/mapInits index e34ab7ea803c..d0396d815ab1 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/mapInits +++ b/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/mapInits @@ -261,4 +261,4 @@ mapInits function() -> (string|(), int|()) { } -} \ No newline at end of file +} From 0c6d138848c83c2da9c03f1aeac4c2c180230cd5 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 10 Jan 2023 17:07:06 +0530 Subject: [PATCH 22/58] Fix review suggestions --- .../internal/types/BTypeReferenceType.java | 4 ++-- .../internal/values/TypedescValueImpl.java | 3 ++- .../ballerinalang/compiler/bir/BIRGen.java | 22 +++++++++---------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java index 231645a021f5..698780123445 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java @@ -47,8 +47,8 @@ public BTypeReferenceType(String typeName, Module pkg, int typeFlags, boolean re this.readOnly = readOnly; } - public BTypeReferenceType(Type referredType) { - this(referredType.getName(), referredType.getPkg(), (int) referredType.getFlags(), true); + public BTypeReferenceType(Type referredType, boolean readOnly) { + this(referredType.getName(), referredType.getPkg(), (int) referredType.getFlags(), readOnly); setReferredType(referredType); } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java index cd2045d8e10a..139a7cd50e0e 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java @@ -96,7 +96,8 @@ public Object instantiate(Strand s, BInitialValueEntry[] initialValues) { } Type effectiveType = getEffectiveType(referredType); if (effectiveType.getTag() == TypeTags.TUPLE_TAG) { - return new TupleValueImpl(new BTypeReferenceType(effectiveType), (BListInitialValueEntry[]) initialValues); + return new TupleValueImpl(new BTypeReferenceType(effectiveType, true), + (BListInitialValueEntry[]) initialValues); } // This method will be overridden for user-defined types, therefor this line shouldn't be reached. throw new BallerinaException("Given type can't be instantiated at runtime : " + this.describingType); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index c45b4ba772e2..a524aa649a62 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -1183,13 +1183,13 @@ public void visit(BLangSimpleVariable varNode) { @Override public void visit(BLangUserDefinedType userDefinedType) { if (Types.getReferredType(userDefinedType.getBType()).getKind() == TypeKind.RECORD) { - createNewTypeDescInst(userDefinedType.pos, userDefinedType.getBType(), Collections.emptyList()); + createNewTypeDescInst(userDefinedType.getBType(), Collections.emptyList()); } } @Override public void visit(BLangTupleTypeNode tupleTypeNode) { - createNewTypeDescInst(tupleTypeNode.pos, tupleTypeNode.getBType(), Collections.emptyList()); + createNewTypeDescInst(tupleTypeNode.getBType(), Collections.emptyList()); tupleTypeNode.memberTypeNodes.forEach(member -> member.accept(this)); if (tupleTypeNode.restParamType != null) { tupleTypeNode.restParamType.accept(this); @@ -1207,7 +1207,7 @@ public void visit(BLangUnionTypeNode unionTypeNode) { @Override public void visit(BLangRecordTypeNode recordTypeNode) { - createNewTypeDescInst(recordTypeNode.pos, recordTypeNode.getBType(), Collections.emptyList()); + createNewTypeDescInst(recordTypeNode.getBType(), Collections.emptyList()); for (BLangSimpleVariable field : recordTypeNode.fields) { if (field.typeNode != null) { field.typeNode.accept(this); @@ -1298,7 +1298,7 @@ public void visit(BLangIntersectionTypeNode intersectionTypeNode) { } BType effectiveType = ((BIntersectionType) intersectionTypeNode.getBType()).effectiveType; if (effectiveType.tag == TypeTags.RECORD || effectiveType.tag == TypeTags.TUPLE) { - createNewTypeDescInst(intersectionTypeNode.pos, effectiveType, Collections.emptyList()); + createNewTypeDescInst(effectiveType, Collections.emptyList()); } } @@ -1759,7 +1759,7 @@ public void visit(BLangLiteral astLiteralExpr) { @Override public void visit(BLangMapLiteral astMapLiteralExpr) { - createNewTypeDescInst(astMapLiteralExpr.pos, astMapLiteralExpr.getBType(), Collections.emptyList()); + createNewTypeDescInst(astMapLiteralExpr.getBType(), Collections.emptyList()); BIRVariableDcl tempVarDcl = new BIRVariableDcl(astMapLiteralExpr.getBType(), this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind.TEMP); @@ -1804,7 +1804,7 @@ public void visit(BLangStructLiteral astStructLiteralExpr) { instruction = new BIRNonTerminator.NewStructure(astStructLiteralExpr.pos, toVarRef, typeDescMap.get(type), generateMappingConstructorEntries(astStructLiteralExpr.fields), type); } else { - createNewTypeDescInst(astStructLiteralExpr.pos, type, mapToVarDcls(type)); + createNewTypeDescInst(type, mapToVarDcls(type)); instruction = new BIRNonTerminator.NewStructure(astStructLiteralExpr.pos, toVarRef, this.env.targetOperand, generateMappingConstructorEntries(astStructLiteralExpr.fields), type); } @@ -2156,7 +2156,7 @@ public void visit(BLangWaitExpr waitExpr) { @Override public void visit(BLangWaitForAllExpr.BLangWaitLiteral waitLiteral) { - createNewTypeDescInst(waitLiteral.pos, waitLiteral.getBType(), Collections.emptyList()); + createNewTypeDescInst(waitLiteral.getBType(), Collections.emptyList()); BIRBasicBlock thenBB = new BIRBasicBlock(this.env.nextBBId(names)); addToTrapStack(thenBB); BIRVariableDcl tempVarDcl = new BIRVariableDcl(waitLiteral.getBType(), @@ -2427,16 +2427,16 @@ public void visit(BLangTableConstructorExpr tableConstructorExpr) { public void visit(BLangSimpleVarRef.BLangTypeLoad typeLoad) { BType type = typeLoad.symbol.tag == SymTag.TYPE_DEF ? ((BTypeDefinitionSymbol) typeLoad.symbol).referenceType : typeLoad.symbol.type; - createNewTypeDescInst(typeLoad.pos, type, Collections.emptyList()); + createNewTypeDescInst(type, Collections.emptyList()); } - private void createNewTypeDescInst(Location pos, BType type, List varDcls) { + private void createNewTypeDescInst(BType type, List varDcls) { BIRVariableDcl tempVarDcl = new BIRVariableDcl(symTable.typeDesc, this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind .TEMP); this.env.enclFunc.localVars.add(tempVarDcl); BIROperand toVarRef = new BIROperand(tempVarDcl); - setScopeAndEmit(new BIRNonTerminator.NewTypeDesc(pos, toVarRef, type, varDcls)); + setScopeAndEmit(new BIRNonTerminator.NewTypeDesc(null, toVarRef, type, varDcls)); this.env.targetOperand = toVarRef; if (type.tsymbol != null && type.tsymbol.owner.getKind() != SymbolKind.PACKAGE) { typeDescMap.put(type, toVarRef); @@ -2905,7 +2905,7 @@ private void generateListConstructorExpr(BLangListConstructorExpr listConstructo new BIRNonTerminator.NewArray(listConstructorExpr.pos, listConstructorExprType, toVarRef, typeDescMap.get(referredType), sizeOp, initialValues)); } else { - createNewTypeDescInst(listConstructorExpr.pos, listConstructorExprType, Collections.emptyList()); + createNewTypeDescInst(listConstructorExprType, Collections.emptyList()); setScopeAndEmit( new BIRNonTerminator.NewArray(listConstructorExpr.pos, listConstructorExprType, toVarRef, this.env.targetOperand, sizeOp, initialValues)); From 849fe3cbde95becbfd1e1be27cdcef71f3759ed9 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 10 Jan 2023 19:01:46 +0530 Subject: [PATCH 23/58] Update code-coverage test --- .../org/ballerinalang/testerina/test/TestReportTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/testerina-integration-test/src/test/java/org/ballerinalang/testerina/test/TestReportTest.java b/tests/testerina-integration-test/src/test/java/org/ballerinalang/testerina/test/TestReportTest.java index d2c4f4fc6c3f..ab61a1f5bd16 100644 --- a/tests/testerina-integration-test/src/test/java/org/ballerinalang/testerina/test/TestReportTest.java +++ b/tests/testerina-integration-test/src/test/java/org/ballerinalang/testerina/test/TestReportTest.java @@ -207,8 +207,8 @@ private void validateCoverage() { float mathPercentage = (float) (Math.round(mathPercentageVal * 100.0) / 100.0); //foo module - int[] fooMainCovered = new int[]{19, 22, 23, 24, 29, 30, 36, 37, 42, 43, 50, 55, 56, 57, 59, 60, 61, 64, 65, - 68, 69, 70, 71, 74, 75}, fooMainMissed = new int[]{26}; + int[] fooMainCovered = new int[]{19, 22, 23, 24, 29, 30, 36, 37, 42, 43, 50, 55, 56, 57, 60, 61, 64, 65, 69, + 70, 71, 74, 75}, fooMainMissed = new int[]{26}; float fooMainPercentageVal = (float) (fooMainCovered.length) / (fooMainCovered.length + fooMainMissed.length) * 100; float fooMainPercentage = @@ -323,7 +323,7 @@ private void validateModuleWiseCoverage() { //foo module int[] fooMainCovered = new int[]{}, fooMainMissed = new int[]{19, 22, 23, 24, 26, 29, 30, 36, 37, - 42, 43, 50, 55, 56, 57, 59, 60, 61, 64, 65, 68, 69, 70, 71, 74, 75}; + 42, 43, 50, 55, 56, 57, 60, 61, 64, 65, 69, 70, 71, 74, 75}; float fooMainPercentageVal = (float) (fooMainCovered.length) / (fooMainCovered.length + fooMainMissed.length) * 100; float fooMainPercentage = (float) (Math.round(fooMainPercentageVal * 100.0) / 100.0); From a2d16cb1549ad8b72bb885d0ae5de9e0d3d9f884 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 10 Jan 2023 22:41:28 +0530 Subject: [PATCH 24/58] Update variable visibility tests --- .../debugger/test/adapter/variables/VariableVisibilityTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/variables/VariableVisibilityTest.java b/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/variables/VariableVisibilityTest.java index 74ef3c28987a..aa7cfb5fd706 100644 --- a/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/variables/VariableVisibilityTest.java +++ b/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/variables/VariableVisibilityTest.java @@ -86,7 +86,7 @@ public void newVariableVisibilityTest() throws BallerinaTestException { debugTestRunner.resumeProgram(debugHitInfo.getRight(), DebugTestRunner.DebugResumeKind.STEP_OVER); debugHitInfo = debugTestRunner.waitForDebugHit(15000); localVariables = debugTestRunner.fetchVariables(debugHitInfo.getRight(), DebugTestRunner.VariableScope.LOCAL); - Assert.assertEquals(localVariables.size(), 41); + Assert.assertEquals(localVariables.size(), 42); Assert.assertTrue(localVariables.containsKey("byteVar")); // debug point variable should be visible when multiple function returned values are present. From 3de6606ed752a107b0663cfc3bb76f2f7a28e414 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Wed, 11 Jan 2023 00:06:07 +0530 Subject: [PATCH 25/58] Visit member types of tupletypenode --- .../org/wso2/ballerinalang/compiler/bir/BIRGen.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index a524aa649a62..a9c95affe732 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -1190,9 +1190,16 @@ public void visit(BLangUserDefinedType userDefinedType) { @Override public void visit(BLangTupleTypeNode tupleTypeNode) { createNewTypeDescInst(tupleTypeNode.getBType(), Collections.emptyList()); - tupleTypeNode.memberTypeNodes.forEach(member -> member.accept(this)); - if (tupleTypeNode.restParamType != null) { - tupleTypeNode.restParamType.accept(this); + BLangType typeNode; + for (BLangSimpleVariable member : tupleTypeNode.memberTypeNodes) { + typeNode = member.typeNode; + if (member.typeNode != null) { + typeNode.accept(this); + } + } + typeNode = tupleTypeNode.restParamType; + if (typeNode != null) { + typeNode.accept(this); } } From d39e35330a1ca70ea58b3c15bf3b4e9cd2ab55be Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Wed, 11 Jan 2023 00:11:42 +0530 Subject: [PATCH 26/58] Refactor tuple member visit logic --- .../org/wso2/ballerinalang/compiler/bir/BIRGen.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index a9c95affe732..1e2f3abd29c5 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -1190,14 +1190,10 @@ public void visit(BLangUserDefinedType userDefinedType) { @Override public void visit(BLangTupleTypeNode tupleTypeNode) { createNewTypeDescInst(tupleTypeNode.getBType(), Collections.emptyList()); - BLangType typeNode; - for (BLangSimpleVariable member : tupleTypeNode.memberTypeNodes) { - typeNode = member.typeNode; - if (member.typeNode != null) { - typeNode.accept(this); - } + for (BLangType member : tupleTypeNode.memberTypeNodes) { + member.accept(this); } - typeNode = tupleTypeNode.restParamType; + BLangType typeNode = tupleTypeNode.restParamType; if (typeNode != null) { typeNode.accept(this); } From 247b1ebcfa0fcc724776ce0be3e80aa057f0e4a1 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Wed, 11 Jan 2023 13:27:51 +0530 Subject: [PATCH 27/58] Refactor logic in `mapToVarDcls` function --- .../ballerinalang/compiler/bir/BIRGen.java | 27 +++++++++++-------- .../compiler/desugar/ClosureDesugar.java | 16 +++++------ 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index 1e2f3abd29c5..e822570a3808 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -1183,13 +1183,13 @@ public void visit(BLangSimpleVariable varNode) { @Override public void visit(BLangUserDefinedType userDefinedType) { if (Types.getReferredType(userDefinedType.getBType()).getKind() == TypeKind.RECORD) { - createNewTypeDescInst(userDefinedType.getBType(), Collections.emptyList()); + createNewTypeDescInst(userDefinedType.getBType()); } } @Override public void visit(BLangTupleTypeNode tupleTypeNode) { - createNewTypeDescInst(tupleTypeNode.getBType(), Collections.emptyList()); + createNewTypeDescInst(tupleTypeNode.getBType()); for (BLangType member : tupleTypeNode.memberTypeNodes) { member.accept(this); } @@ -1210,7 +1210,7 @@ public void visit(BLangUnionTypeNode unionTypeNode) { @Override public void visit(BLangRecordTypeNode recordTypeNode) { - createNewTypeDescInst(recordTypeNode.getBType(), Collections.emptyList()); + createNewTypeDescInst(recordTypeNode.getBType()); for (BLangSimpleVariable field : recordTypeNode.fields) { if (field.typeNode != null) { field.typeNode.accept(this); @@ -1301,7 +1301,7 @@ public void visit(BLangIntersectionTypeNode intersectionTypeNode) { } BType effectiveType = ((BIntersectionType) intersectionTypeNode.getBType()).effectiveType; if (effectiveType.tag == TypeTags.RECORD || effectiveType.tag == TypeTags.TUPLE) { - createNewTypeDescInst(effectiveType, Collections.emptyList()); + createNewTypeDescInst(effectiveType); } } @@ -1762,7 +1762,7 @@ public void visit(BLangLiteral astLiteralExpr) { @Override public void visit(BLangMapLiteral astMapLiteralExpr) { - createNewTypeDescInst(astMapLiteralExpr.getBType(), Collections.emptyList()); + createNewTypeDescInst(astMapLiteralExpr.getBType()); BIRVariableDcl tempVarDcl = new BIRVariableDcl(astMapLiteralExpr.getBType(), this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind.TEMP); @@ -1807,7 +1807,7 @@ public void visit(BLangStructLiteral astStructLiteralExpr) { instruction = new BIRNonTerminator.NewStructure(astStructLiteralExpr.pos, toVarRef, typeDescMap.get(type), generateMappingConstructorEntries(astStructLiteralExpr.fields), type); } else { - createNewTypeDescInst(type, mapToVarDcls(type)); + createNewTypeDescInst(type); instruction = new BIRNonTerminator.NewStructure(astStructLiteralExpr.pos, toVarRef, this.env.targetOperand, generateMappingConstructorEntries(astStructLiteralExpr.fields), type); } @@ -1817,7 +1817,11 @@ public void visit(BLangStructLiteral astStructLiteralExpr) { } private List mapToVarDcls(BType type) { - TreeMap enclMapSymbols = ((BRecordType) Types.getReferredType(type)).enclMapSymbols; + BType referredType = Types.getReferredType(type); + if (referredType.tag != TypeTags.RECORD) { + return Collections.emptyList(); + } + TreeMap enclMapSymbols = ((BRecordType) referredType).enclMapSymbols; if (enclMapSymbols == null || enclMapSymbols.size() == 0) { return Collections.emptyList(); } @@ -2159,7 +2163,7 @@ public void visit(BLangWaitExpr waitExpr) { @Override public void visit(BLangWaitForAllExpr.BLangWaitLiteral waitLiteral) { - createNewTypeDescInst(waitLiteral.getBType(), Collections.emptyList()); + createNewTypeDescInst(waitLiteral.getBType()); BIRBasicBlock thenBB = new BIRBasicBlock(this.env.nextBBId(names)); addToTrapStack(thenBB); BIRVariableDcl tempVarDcl = new BIRVariableDcl(waitLiteral.getBType(), @@ -2430,10 +2434,11 @@ public void visit(BLangTableConstructorExpr tableConstructorExpr) { public void visit(BLangSimpleVarRef.BLangTypeLoad typeLoad) { BType type = typeLoad.symbol.tag == SymTag.TYPE_DEF ? ((BTypeDefinitionSymbol) typeLoad.symbol).referenceType : typeLoad.symbol.type; - createNewTypeDescInst(type, Collections.emptyList()); + createNewTypeDescInst(type); } - private void createNewTypeDescInst(BType type, List varDcls) { + private void createNewTypeDescInst(BType type) { + List varDcls = mapToVarDcls(type); BIRVariableDcl tempVarDcl = new BIRVariableDcl(symTable.typeDesc, this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind .TEMP); @@ -2908,7 +2913,7 @@ private void generateListConstructorExpr(BLangListConstructorExpr listConstructo new BIRNonTerminator.NewArray(listConstructorExpr.pos, listConstructorExprType, toVarRef, typeDescMap.get(referredType), sizeOp, initialValues)); } else { - createNewTypeDescInst(listConstructorExprType, Collections.emptyList()); + createNewTypeDescInst(listConstructorExprType); setScopeAndEmit( new BIRNonTerminator.NewArray(listConstructorExpr.pos, listConstructorExprType, toVarRef, this.env.targetOperand, sizeOp, initialValues)); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java index c9949182ad20..1f9310409cb5 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java @@ -24,7 +24,6 @@ import org.ballerinalang.model.tree.NodeKind; import org.ballerinalang.model.tree.TopLevelNode; import org.ballerinalang.model.tree.expressions.RecordLiteralNode; -import org.ballerinalang.model.types.TypeKind; import org.wso2.ballerinalang.compiler.semantics.analyzer.SymbolResolver; import org.wso2.ballerinalang.compiler.semantics.analyzer.Types; import org.wso2.ballerinalang.compiler.semantics.model.Scope; @@ -965,6 +964,13 @@ public void visit(BLangArrayType arrayType) { @Override public void visit(BLangUserDefinedType userDefinedType) { + BType type = userDefinedType.getBType(); + if (type != null && type.tag == TypeTags.RECORD) { + SymbolEnv symbolEnv = env.createClone(); + BLangFunction enclInvokable = (BLangFunction) symbolEnv.enclInvokable; + ((BRecordType) userDefinedType.getBType()).enclMapSymbols = + collectClosureMapSymbols(symbolEnv, enclInvokable, false); + } result = userDefinedType; } @@ -1424,7 +1430,7 @@ private TreeMap collectClosureMapSymbols(SymbolEnv symbolEn boolean isWorker) { // Recursively iterate back to the encl invokable and get all map symbols visited. TreeMap enclMapSymbols = new TreeMap<>(); - while (symbolEnv != null && symbolEnv.enclInvokable == enclInvokable) { + while (symbolEnv != null && symbolEnv.node != null && symbolEnv.enclInvokable == enclInvokable) { BVarSymbol mapSym = getMapSymbol(symbolEnv.node); // Skip non-block bodies @@ -1963,12 +1969,6 @@ public void visit(BLangRecordLiteral.BLangMapLiteral mapLiteral) { @Override public void visit(BLangRecordLiteral.BLangStructLiteral structLiteral) { - SymbolEnv symbolEnv = env.createClone(); - BLangFunction enclInvokable = (BLangFunction) symbolEnv.enclInvokable; - if (structLiteral.getBType().getKind() == TypeKind.RECORD) { - ((BRecordType) structLiteral.getBType()).enclMapSymbols = - collectClosureMapSymbols(symbolEnv, enclInvokable, false); - } for (RecordLiteralNode.RecordField field : structLiteral.fields) { if (field.isKeyValueField()) { BLangRecordLiteral.BLangRecordKeyValueField keyValueField = From bde8535ccde8df02d7aab0ab324d32e2eaf83201 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 10 Jan 2023 23:26:32 +0530 Subject: [PATCH 28/58] Import BIntersectionType --- .../main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index 3b4396bc52f8..acfc2b861deb 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -79,6 +79,7 @@ import org.wso2.ballerinalang.compiler.semantics.model.symbols.SymTag; import org.wso2.ballerinalang.compiler.semantics.model.symbols.Symbols; import org.wso2.ballerinalang.compiler.semantics.model.types.BArrayType; +import org.wso2.ballerinalang.compiler.semantics.model.types.BIntersectionType; import org.wso2.ballerinalang.compiler.semantics.model.types.BInvokableType; import org.wso2.ballerinalang.compiler.semantics.model.types.BRecordType; import org.wso2.ballerinalang.compiler.semantics.model.types.BTableType; From 95560b26add73a6c22572d66eaa99fbe3d29f330 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Wed, 11 Jan 2023 00:06:07 +0530 Subject: [PATCH 29/58] Visit member types of tupletypenode --- .../org/wso2/ballerinalang/compiler/bir/BIRGen.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index acfc2b861deb..ba654abab163 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -1164,10 +1164,14 @@ public void visit(BLangUserDefinedType userDefinedType) { @Override public void visit(BLangTupleTypeNode tupleTypeNode) { createNewTypeDescInst(tupleTypeNode.getBType()); - for (BLangType member : tupleTypeNode.memberTypeNodes) { - member.accept(this); + BLangType typeNode; + for (BLangSimpleVariable member : tupleTypeNode.memberTypeNodes) { + typeNode = member.typeNode; + if (member.typeNode != null) { + typeNode.accept(this); + } } - BLangType typeNode = tupleTypeNode.restParamType; + typeNode = tupleTypeNode.restParamType; if (typeNode != null) { typeNode.accept(this); } From c0ef0a550116ffe5b0a0eaf59a6177e39afbbaaf Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Wed, 11 Jan 2023 19:02:41 +0530 Subject: [PATCH 30/58] Refactor error detail type handling logic --- .../compiler/desugar/ClosureDesugar.java | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java index 19257d0bc99c..6d5b19a337e6 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java @@ -36,6 +36,7 @@ import org.wso2.ballerinalang.compiler.semantics.model.symbols.BRecordTypeSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BVarSymbol; +import org.wso2.ballerinalang.compiler.semantics.model.types.BErrorType; import org.wso2.ballerinalang.compiler.semantics.model.types.BField; import org.wso2.ballerinalang.compiler.semantics.model.types.BInvokableType; import org.wso2.ballerinalang.compiler.semantics.model.types.BMapType; @@ -965,11 +966,17 @@ public void visit(BLangArrayType arrayType) { @Override public void visit(BLangUserDefinedType userDefinedType) { BType type = userDefinedType.getBType(); - if (type != null && type.tag == TypeTags.RECORD) { - SymbolEnv symbolEnv = env.createClone(); - BLangFunction enclInvokable = (BLangFunction) symbolEnv.enclInvokable; - ((BRecordType) userDefinedType.getBType()).enclMapSymbols = - collectClosureMapSymbols(symbolEnv, enclInvokable, false); + if (type == null) { + result = userDefinedType; + return; + } + if (type.tag == TypeTags.RECORD) { + ((BRecordType) type).enclMapSymbols = collectClosureMapSymbols(env, false); + } else if (type.tag == TypeTags.ERROR) { + BType detailType = ((BErrorType) type).detailType; + if (detailType.tag == TypeTags.RECORD) { + ((BRecordType) detailType).enclMapSymbols = collectClosureMapSymbols(env, false); + } } result = userDefinedType; } @@ -1421,14 +1428,15 @@ public void visit(BLangLambdaFunction bLangLambdaFunction) { // Save param closure map of the encl invokable. bLangLambdaFunction.paramMapSymbolsOfEnclInvokable = enclInvokable.paramClosureMap; boolean isWorker = bLangLambdaFunction.function.flagSet.contains(Flag.WORKER); - bLangLambdaFunction.enclMapSymbols = collectClosureMapSymbols(symbolEnv, enclInvokable, isWorker); + bLangLambdaFunction.enclMapSymbols = collectClosureMapSymbols(env, isWorker); } result = bLangLambdaFunction; } - private TreeMap collectClosureMapSymbols(SymbolEnv symbolEnv, BLangInvokableNode enclInvokable, - boolean isWorker) { + private TreeMap collectClosureMapSymbols(SymbolEnv env, boolean isWorker) { // Recursively iterate back to the encl invokable and get all map symbols visited. + SymbolEnv symbolEnv = env.createClone(); + BLangFunction enclInvokable = (BLangFunction) symbolEnv.enclInvokable; TreeMap enclMapSymbols = new TreeMap<>(); while (symbolEnv != null && symbolEnv.node != null && symbolEnv.enclInvokable == enclInvokable) { BVarSymbol mapSym = getMapSymbol(symbolEnv.node); From b21e351e828b9dedb15e1977337d35651387307d Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Mon, 16 Jan 2023 19:38:08 +0530 Subject: [PATCH 31/58] Generate new Typedesc Id --- .../java/org/wso2/ballerinalang/compiler/bir/BIRGenEnv.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGenEnv.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGenEnv.java index 2f3cfa39a88c..685671a785c9 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGenEnv.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGenEnv.java @@ -53,6 +53,7 @@ class BIRGenEnv { Map symbolVarMap = new HashMap<>(); private int currentBBId = -1; private int currentLocalVarId = -1; + private int currentTypedescId = -1; private int currentLambdaVarId = -1; BIRBasicBlock enclBB; @@ -94,6 +95,11 @@ Name nextLocalVarId(Names names) { return names.merge(Names.BIR_LOCAL_VAR_PREFIX, names.fromString(Integer.toString(currentLocalVarId))); } + Name nextTypedescId(Names names) { + currentTypedescId++; + return names.merge(Names.TYPEDESC, Names.fromString(Integer.toString(currentTypedescId))); + } + Name nextLambdaVarId(Names names) { currentLambdaVarId++; return names.merge(Names.BIR_LOCAL_VAR_PREFIX, names.fromString(Integer.toString(currentLambdaVarId))); From 7cae7b406c79dfa1d0a76d39f994e5e642e8e20e Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Mon, 16 Jan 2023 19:41:39 +0530 Subject: [PATCH 32/58] Add constructor to BIRGlobalVariableDcl class --- .../ballerinalang/compiler/bir/model/BIRNode.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNode.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNode.java index 8c9156de2b1c..adb2cbc1cf6e 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNode.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/model/BIRNode.java @@ -59,6 +59,7 @@ public static class BIRPackage extends BIRNode { public final List importModules; public final List typeDefs; public final List globalVars; + public final List typedescs; public final Set importedGlobalVarsDummyVarDcls; public final List functions; public final List annotations; @@ -83,6 +84,7 @@ public BIRPackage(Location pos, Name org, Name pkgName, Name name, Name version, this.annotations = new ArrayList<>(); this.constants = new ArrayList<>(); this.serviceDecls = new ArrayList<>(); + this.typedescs = new ArrayList<>(); } @Override @@ -231,6 +233,15 @@ public BIRGlobalVariableDcl(Location pos, long flags, BType type, PackageID pkgI this.annotAttachments = new ArrayList<>(); } + public BIRGlobalVariableDcl(BType type, Name name, VarScope scope, VarKind kind, long flags, PackageID pkgId, + SymbolOrigin origin) { + super(type, name, scope, kind); + this.flags = flags; + this.pkgId = pkgId; + this.origin = origin; + this.annotAttachments = new ArrayList<>(); + } + @Override public void accept(BIRVisitor visitor) { visitor.visit(this); From 8d23d1aef8889de7eef7ffe3ce8352fa0710f8a4 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Mon, 16 Jan 2023 19:53:01 +0530 Subject: [PATCH 33/58] Remove desugaring of local anonymous record type node to BLangUserDefinedType --- .../wso2/ballerinalang/compiler/desugar/Desugar.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java index 696aedc294d1..e5184a28143a 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java @@ -1243,22 +1243,16 @@ public void visit(BLangRecordTypeNode recordTypeNode) { // referenced types are invoked on the current record type. if (recordTypeNode.isAnonymous && recordTypeNode.isLocal) { - BLangUserDefinedType userDefinedType = desugarLocalAnonRecordTypeNode(recordTypeNode); TypeDefBuilderHelper.createTypeDefinitionForTSymbol(recordTypeNode.getBType(), recordTypeNode.getBType().tsymbol, recordTypeNode, env); recordTypeNode.desugared = true; - result = userDefinedType; + result = recordTypeNode; return; } result = recordTypeNode; } - private BLangUserDefinedType desugarLocalAnonRecordTypeNode(BLangRecordTypeNode recordTypeNode) { - return ASTBuilderUtil.createUserDefineTypeNode(recordTypeNode.symbol.name.value, recordTypeNode.getBType(), - recordTypeNode.pos); - } - @Override public void visit(BLangArrayType arrayType) { arrayType.elemtype = rewrite(arrayType.elemtype, env); @@ -1329,11 +1323,10 @@ public void visit(BLangErrorType errorType) { // Error without type param is either a user-defined-type or a default error, they don't need a type-def. // We need to create type-defs for local anonymous types with type param. if (errorType.isLocal && errorType.isAnonymous && hasTypeParam) { - BLangUserDefinedType userDefinedType = desugarLocalAnonRecordTypeNode(errorType); TypeDefBuilderHelper.createTypeDefinitionForTSymbol(errorType.getBType(), errorType.getBType().tsymbol, errorType, env); errorType.desugared = true; - result = userDefinedType; + result = errorType; return; } result = errorType; From bba94d63a807c21c524ae5113187ece5b504c0a9 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Mon, 16 Jan 2023 19:55:39 +0530 Subject: [PATCH 34/58] Add function to check for user-defined type --- .../compiler/semantics/analyzer/Types.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/Types.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/Types.java index fb70742c880a..0296cc4e086b 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/Types.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/Types.java @@ -148,6 +148,7 @@ import static org.wso2.ballerinalang.compiler.util.TypeTags.NEVER; import static org.wso2.ballerinalang.compiler.util.TypeTags.OBJECT; import static org.wso2.ballerinalang.compiler.util.TypeTags.RECORD; +import static org.wso2.ballerinalang.compiler.util.TypeTags.TUPLE; import static org.wso2.ballerinalang.compiler.util.TypeTags.UNION; import static org.wso2.ballerinalang.compiler.util.TypeTags.isSimpleBasicType; @@ -5416,12 +5417,17 @@ private BType getIntersectionForErrorTypes(IntersectionContext intersectionConte return intersectionErrorType; } - // This function checks whether the specified type definition is a user-defined type or not. public static boolean isUserDefinedTypeDefinition(BType type) { type = Types.getReferredType(type); BTypeSymbol typeSymbol = type.tsymbol; - return typeSymbol != null && (type.tag == TypeTags.RECORD || type.tag == TypeTags.TUPLE) && - typeSymbol.name != Names.EMPTY && typeSymbol.owner.getKind() == SymbolKind.PACKAGE; + switch (type.tag) { + case RECORD: + return typeSymbol != null && typeSymbol.owner.getKind() == SymbolKind.PACKAGE; + case TUPLE: + return typeSymbol != null && typeSymbol.name != Names.EMPTY; + default: + return false; + } } private BType createRecordIntersection(IntersectionContext intersectionContext, From d3074692e72e4ed75b409471cbba36b5f7c30f2b Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Mon, 16 Jan 2023 20:08:58 +0530 Subject: [PATCH 35/58] Add support to create type descriptor instances for global variables --- .../runtime/internal/values/MapValueImpl.java | 5 +- .../bir/codegen/split/JvmCreateTypeGen.java | 66 +++++++++++++++---- .../bir/codegen/split/JvmMethodsSplitter.java | 3 +- 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/MapValueImpl.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/MapValueImpl.java index 9c2b8d02e85d..7394fb56c28d 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/MapValueImpl.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/MapValueImpl.java @@ -67,6 +67,7 @@ import static io.ballerina.runtime.internal.JsonInternalUtils.mergeJson; import static io.ballerina.runtime.internal.ValueUtils.createSingletonTypedesc; import static io.ballerina.runtime.internal.ValueUtils.getTypedescValue; +import static io.ballerina.runtime.internal.util.RuntimeUtils.getEffectiveType; import static io.ballerina.runtime.internal.util.exceptions.BallerinaErrorReasons.INVALID_UPDATE_ERROR_IDENTIFIER; import static io.ballerina.runtime.internal.util.exceptions.BallerinaErrorReasons.MAP_KEY_NOT_FOUND_ERROR; import static io.ballerina.runtime.internal.util.exceptions.BallerinaErrorReasons.getModulePrefixedReason; @@ -307,8 +308,8 @@ public void populateInitialValue(K key, V value) { putValue(key, value); } else { BString fieldName = (BString) key; - if (MapUtils.handleInherentTypeViolatingRecordUpdate(this, fieldName, value, (BRecordType) referredType, - true)) { + if (MapUtils.handleInherentTypeViolatingRecordUpdate(this, fieldName, value, + (BRecordType) getEffectiveType(referredType), true)) { putValue(key, value); } } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java index 28538ee25451..41a8a36e1b76 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java @@ -39,6 +39,7 @@ import org.wso2.ballerinalang.compiler.bir.codegen.split.types.JvmUnionTypeGen; import org.wso2.ballerinalang.compiler.bir.model.BIRNode; import org.wso2.ballerinalang.compiler.bir.model.BIRNode.BIRTypeDefinition; +import org.wso2.ballerinalang.compiler.bir.model.BIRNonTerminator; import org.wso2.ballerinalang.compiler.parser.BLangAnonymousModelHelper; import org.wso2.ballerinalang.compiler.semantics.analyzer.TypeHashVisitor; import org.wso2.ballerinalang.compiler.semantics.analyzer.Types; @@ -77,7 +78,9 @@ import static org.objectweb.asm.Opcodes.ACC_SUPER; import static org.objectweb.asm.Opcodes.ACONST_NULL; import static org.objectweb.asm.Opcodes.ALOAD; +import static org.objectweb.asm.Opcodes.ANEWARRAY; import static org.objectweb.asm.Opcodes.ARETURN; +import static org.objectweb.asm.Opcodes.BIPUSH; import static org.objectweb.asm.Opcodes.DUP; import static org.objectweb.asm.Opcodes.GETSTATIC; import static org.objectweb.asm.Opcodes.GOTO; @@ -115,6 +118,7 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.GET_ANON_TYPE_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.JVM_INIT_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MAP; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MAP_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MAX_FIELDS_PER_SPLIT_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MAX_TYPES_PER_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MODULE_ANON_TYPES_CLASS_NAME; @@ -135,8 +139,10 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.SET_IMMUTABLE_TYPE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.SET_LINKED_HASH_MAP; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.TYPE_DESC_CONSTRUCTOR; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmTypeGen.getTypeDesc; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmTypeGen.getTypeFieldName; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmValueGen.getTypeDescClassName; +import static org.wso2.ballerinalang.compiler.semantics.analyzer.Types.getEffectiveType; /** * BIR types to JVM byte code generation class. @@ -159,11 +165,13 @@ public class JvmCreateTypeGen { private final String typesClass; private final String anonTypesClass; private final ClassWriter typesCw; + private final JvmPackageGen jvmPackageGen; public JvmCreateTypeGen(JvmTypeGen jvmTypeGen, JvmConstantsGen jvmConstantsGen, PackageID packageID, - TypeHashVisitor typeHashVisitor) { + TypeHashVisitor typeHashVisitor, JvmPackageGen jvmPackageGen) { this.jvmTypeGen = jvmTypeGen; this.jvmConstantsGen = jvmConstantsGen; + this.jvmPackageGen = jvmPackageGen; this.typesClass = getModuleLevelClassName(packageID, MODULE_TYPES_CLASS_NAME); this.anonTypesClass = getModuleLevelClassName(packageID, MODULE_ANON_TYPES_CLASS_NAME); this.jvmRecordTypeGen = new JvmRecordTypeGen(this, jvmTypeGen, jvmConstantsGen, packageID); @@ -182,7 +190,7 @@ public JvmCreateTypeGen(JvmTypeGen jvmTypeGen, JvmConstantsGen jvmConstantsGen, public void generateTypeClass(JvmPackageGen jvmPackageGen, BIRNode.BIRPackage module, Map jarEntries, String moduleInitClass, SymbolTable symbolTable) { - generateCreateTypesMethod(typesCw, module.typeDefs, moduleInitClass, symbolTable); + generateCreateTypesMethod(typesCw, module.typeDefs, moduleInitClass, symbolTable, module.typedescs); typesCw.visitEnd(); jvmRecordTypeGen.visitEnd(jvmPackageGen, module, jarEntries); jvmObjectTypeGen.visitEnd(jvmPackageGen, module, jarEntries); @@ -219,11 +227,11 @@ void createTypeConstants(ClassWriter cw) { mv.visitEnd(); } - void generateCreateTypesMethod(ClassWriter cw, List typeDefs, - String moduleInitClass, SymbolTable symbolTable) { + void generateCreateTypesMethod(ClassWriter cw, List typeDefs, String moduleInitClass, + SymbolTable symbolTable, List typesecs) { createTypeConstants(cw); createTypesInstance(cw, typeDefs, moduleInitClass); - createTypedescInstances(cw, typeDefs, moduleInitClass); + createTypedescInstances(cw, typeDefs, moduleInitClass, typesecs); Map populateTypeFuncNames = populateTypes(cw, typeDefs, moduleInitClass, symbolTable); MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, CREATE_TYPES_METHOD, "()V", null, null); @@ -261,23 +269,53 @@ private void createTypesInstance(ClassWriter cw, List typeDef mv.visitEnd(); } - private void createTypedescInstances(ClassWriter cw, List typeDefs, String moduleInitClass) { + private void createTypedescInstances(ClassWriter cw, List typeDefs, String moduleInitClass, + List typesecs) { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, CREATE_TYPEDESC_INSTANCES_METHOD, "()V", null, null); mv.visitCode(); for (BIRTypeDefinition typeDefinition : typeDefs) { BType bType = JvmCodeGenUtil.getReferredType(typeDefinition.type); BSymbol owner = bType.tsymbol.owner; - if (owner != null && owner.getKind() != SymbolKind.PACKAGE) { + if (bType.tag == TypeTags.RECORD && (owner != null && owner.getKind() != SymbolKind.PACKAGE)) { continue; - } - createTypedescInstance(mv, bType, typeDefinition, moduleInitClass); + } + createTypedescInstance(mv, bType, typeDefinition, moduleInitClass); + } + + for (BIRNonTerminator.NewTypeDesc typedesc : typesecs) { + createTypedescInstances(mv, typedesc); } mv.visitInsn(RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } + private void createTypedescInstances(MethodVisitor mv, BIRNonTerminator.NewTypeDesc typeDesc) { + BType type = JvmCodeGenUtil.getReferredType(typeDesc.type); + String className = TYPEDESC_VALUE_IMPL; + if (type.tag == TypeTags.RECORD) { + className = getTypeDescClassName(JvmCodeGenUtil.getPackageName(type.tsymbol.pkgID), toNameString(type)); + } + mv.visitTypeInsn(NEW, className); + mv.visitInsn(DUP); + jvmTypeGen.loadType(mv, typeDesc.type); + mv.visitIntInsn(BIPUSH, typeDesc.closureVars.size()); + mv.visitTypeInsn(ANEWARRAY, MAP_VALUE); + mv.visitMethodInsn(INVOKESPECIAL, className, JVM_INIT_METHOD, TYPE_DESC_CONSTRUCTOR, false); + generateGlobalVarStore(mv, typeDesc.lhsOp.variableDcl); + } + + public void generateGlobalVarStore(MethodVisitor mv, BIRNode.BIRVariableDcl varDcl) { + BType bType = JvmCodeGenUtil.getReferredType(varDcl.type); + String varName = varDcl.name.value; + PackageID moduleId = ((BIRNode.BIRGlobalVariableDcl) varDcl).pkgId; + String pkgName = JvmCodeGenUtil.getPackageName(moduleId); + String className = jvmPackageGen.lookupGlobalVarClassName(pkgName, varName); + String typeSig = getTypeDesc(bType); + mv.visitFieldInsn(PUTSTATIC, className, varName, typeSig); + } + private void createTypedescInstance(MethodVisitor mv, BType bType, BIRTypeDefinition typeDefinition, String moduleInitClass) { String className; @@ -285,8 +323,8 @@ private void createTypedescInstance(MethodVisitor mv, BType bType, BIRTypeDefini PackageID pkgID = bType.tsymbol.pkgID; String packageName = JvmCodeGenUtil.getPackageName(pkgID); className = getTypeDescClassName(packageName, toNameString(bType)); - } else if (Types.getEffectiveType(bType).tag == TypeTags.TUPLE) { - bType = Types.getEffectiveType(bType); + } else if (getEffectiveType(bType).tag == TypeTags.TUPLE) { + bType = getEffectiveType(bType); className = TYPEDESC_VALUE_IMPL; } else { return; @@ -325,7 +363,7 @@ private int createTypesInstanceSplits(ClassWriter cw, List ty String name = optionalTypeDef.internalName.value; BType bType = JvmCodeGenUtil.getReferredType(optionalTypeDef.type); if (bType.tag != TypeTags.RECORD && bType.tag != TypeTags.OBJECT && bType.tag != TypeTags.ERROR && - bType.tag != TypeTags.UNION && Types.getEffectiveType(bType).tag != TypeTags.TUPLE) { + bType.tag != TypeTags.UNION && getEffectiveType(bType).tag != TypeTags.TUPLE) { // do not generate anything for other types (e.g.: finite type, etc.) continue; } else { @@ -335,7 +373,7 @@ private int createTypesInstanceSplits(ClassWriter cw, List ty mv.visitCode(); } } - switch (Types.getEffectiveType(bType).tag) { + switch (getEffectiveType(bType).tag) { case TypeTags.RECORD: jvmRecordTypeGen.createRecordType(mv, (BRecordType) bType); break; @@ -346,7 +384,7 @@ private int createTypesInstanceSplits(ClassWriter cw, List ty jvmErrorTypeGen.createErrorType(mv, (BErrorType) bType, bType.tsymbol.name.value); break; case TypeTags.TUPLE: - jvmTupleTypeGen.createTupleType(mv, (BTupleType) Types.getEffectiveType(bType)); + jvmTupleTypeGen.createTupleType(mv, (BTupleType) getEffectiveType(bType)); break; default: jvmUnionTypeGen.createUnionType(mv, (BUnionType) bType); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmMethodsSplitter.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmMethodsSplitter.java index 8f85ad603ff6..d3b48ff8b837 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmMethodsSplitter.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmMethodsSplitter.java @@ -48,7 +48,8 @@ public JvmMethodsSplitter(JvmPackageGen jvmPackageGen, JvmConstantsGen jvmConsta this.moduleInitClass = moduleInitClass; JvmTypeGen jvmTypeGen = new JvmTypeGen(jvmConstantsGen, module.packageID, typeHashVisitor, jvmPackageGen.symbolTable); - this.jvmCreateTypeGen = new JvmCreateTypeGen(jvmTypeGen, jvmConstantsGen, module.packageID, typeHashVisitor); + this.jvmCreateTypeGen = new JvmCreateTypeGen(jvmTypeGen, jvmConstantsGen, module.packageID, typeHashVisitor, + jvmPackageGen); this.jvmAnnotationsGen = new JvmAnnotationsGen(module, jvmPackageGen, jvmTypeGen, jvmConstantsGen); this.jvmValueCreatorGen = new JvmValueCreatorGen(module.packageID); jvmConstantsGen.setJvmCreateTypeGen(jvmCreateTypeGen); From b9c75522d45da08464396495d8027702b40c45e4 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Mon, 16 Jan 2023 20:30:23 +0530 Subject: [PATCH 36/58] Modify typenode visitors to generate type descriptor instructions during type visits --- .../ballerinalang/compiler/bir/BIRGen.java | 180 +++++++++++------- 1 file changed, 110 insertions(+), 70 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index ba654abab163..50821a49f511 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -25,14 +25,12 @@ import org.ballerinalang.model.elements.Flag; import org.ballerinalang.model.elements.PackageID; import org.ballerinalang.model.symbols.AnnotationAttachmentSymbol; -import org.ballerinalang.model.symbols.SymbolKind; import org.ballerinalang.model.symbols.SymbolOrigin; import org.ballerinalang.model.tree.BlockNode; import org.ballerinalang.model.tree.NodeKind; import org.ballerinalang.model.tree.OperatorKind; import org.ballerinalang.model.tree.TopLevelNode; import org.ballerinalang.model.tree.expressions.RecordLiteralNode; -import org.ballerinalang.model.types.TypeKind; import org.wso2.ballerinalang.compiler.bir.model.BIRNode; import org.wso2.ballerinalang.compiler.bir.model.BIRNode.BIRAnnotation; import org.wso2.ballerinalang.compiler.bir.model.BIRNode.BIRAnnotationAttachment; @@ -266,7 +264,8 @@ public class BIRGen extends BLangNodeVisitor { // This map is used to create dependencies for imported module global variables private Map dummyGlobalVarMapForLocks = new HashMap<>(); - private Map typeDescMap = new HashMap<>(); + private Map localTypedescMap = new HashMap<>(); + private Map globalTypedescMap = new HashMap<>(); // This is to cache the lockstmt to BIR Lock private Map lockStmtMap = new HashMap<>(); @@ -376,6 +375,10 @@ private void generateClassDefinitions(List topLevelNodes) { @Override public void visit(BLangTypeDefinition astTypeDefinition) { + BLangType bLangType = astTypeDefinition.typeNode; + if (bLangType != null) { + bLangType.accept(this); + } BType type = getDefinedType(astTypeDefinition); BSymbol symbol = astTypeDefinition.symbol; Name displayName = symbol.name; @@ -482,6 +485,12 @@ private BType getDefinedType(BLangTypeDefinition astTypeDefinition) { @Override public void visit(BLangClassDefinition classDefinition) { + for (BLangSimpleVariable bLangSimpleVariable : classDefinition.fields) { + BLangType typeNode = bLangSimpleVariable.typeNode; + if (typeNode != null) { + typeNode.accept(this); + } + } BIRTypeDefinition typeDef = new BIRTypeDefinition(classDefinition.pos, classDefinition.symbol.name, classDefinition.symbol.originalName, @@ -592,6 +601,7 @@ public void visit(BLangFunction astFunc) { this.env.unlockVars.push(new BIRLockDetailsHolder()); Name funcName; + analyzeParametersAndReturnType(astFunc); if (isTypeAttachedFunction) { funcName = names.fromString(astFunc.symbol.name.value); } else { @@ -697,9 +707,8 @@ public void visit(BLangFunction astFunc) { this.env.enclBasicBlocks = birFunc.basicBlocks; birFunc.basicBlocks.add(entryBB); this.env.enclBB = entryBB; - this.typeDescMap = new HashMap<>(); + this.localTypedescMap = new HashMap<>(); addToTrapStack(entryBB); - analyzeParametersAndReturnType(astFunc); astFunc.body.accept(this); birFunc.basicBlocks.add(this.env.returnBB); @@ -1117,8 +1126,9 @@ public void visit(BLangSimpleVariableDef astVarDefStmt) { } BLangSimpleVariable simpleVariable = astVarDefStmt.var; - if (simpleVariable.typeNode != null) { - simpleVariable.typeNode.accept(this); + BLangType typeNode = simpleVariable.typeNode; + if (typeNode != null) { + typeNode.accept(this); } if (simpleVariable.expr == null) { @@ -1136,6 +1146,10 @@ public void visit(BLangSimpleVariableDef astVarDefStmt) { @Override public void visit(BLangSimpleVariable varNode) { + BLangType typeNode = varNode.typeNode; + if (typeNode != null) { + typeNode.accept(this); + } String name = ANNOTATION_DATA.equals(varNode.symbol.name.value) ? ANNOTATION_DATA : varNode.name.value; String originalName = ANNOTATION_DATA.equals(varNode.symbol.getOriginalName().value) ? ANNOTATION_DATA : varNode.name.originalValue; @@ -1156,14 +1170,12 @@ public void visit(BLangSimpleVariable varNode) { @Override public void visit(BLangUserDefinedType userDefinedType) { - if (Types.getReferredType(userDefinedType.getBType()).getKind() == TypeKind.RECORD) { - createNewTypeDescInst(userDefinedType.getBType()); - } } @Override public void visit(BLangTupleTypeNode tupleTypeNode) { - createNewTypeDescInst(tupleTypeNode.getBType()); + BType type = tupleTypeNode.getBType(); + createNewTypedescInst(type, tupleTypeNode.pos); BLangType typeNode; for (BLangSimpleVariable member : tupleTypeNode.memberTypeNodes) { typeNode = member.typeNode; @@ -1188,14 +1200,18 @@ public void visit(BLangUnionTypeNode unionTypeNode) { @Override public void visit(BLangRecordTypeNode recordTypeNode) { - createNewTypeDescInst(recordTypeNode.getBType()); + BType type = recordTypeNode.getBType(); + createNewTypedescInst(type, recordTypeNode.pos); + BLangType typeNode; for (BLangSimpleVariable field : recordTypeNode.fields) { - if (field.typeNode != null) { - field.typeNode.accept(this); + typeNode = field.typeNode; + if (typeNode != null) { + typeNode.accept(this); } } - if (recordTypeNode.restFieldType != null) { - recordTypeNode.restFieldType.accept(this); + typeNode = recordTypeNode.restFieldType; + if (typeNode != null) { + typeNode.accept(this); } } @@ -1265,6 +1281,12 @@ public void visit(BLangTableKeyTypeConstraint keyTypeConstraint) { @Override public void visit(BLangObjectTypeNode objectTypeNode) { + for (BLangSimpleVariable field : objectTypeNode.fields) { + BLangType typeNode = field.typeNode; + if (typeNode != null) { + typeNode.accept(this); + } + } } @Override @@ -1279,7 +1301,7 @@ public void visit(BLangIntersectionTypeNode intersectionTypeNode) { } BType effectiveType = ((BIntersectionType) intersectionTypeNode.getBType()).effectiveType; if (effectiveType.tag == TypeTags.RECORD || effectiveType.tag == TypeTags.TUPLE) { - createNewTypeDescInst(effectiveType); + createNewTypedescInst(effectiveType, intersectionTypeNode.pos); } } @@ -1740,16 +1762,16 @@ public void visit(BLangLiteral astLiteralExpr) { @Override public void visit(BLangMapLiteral astMapLiteralExpr) { - createNewTypeDescInst(astMapLiteralExpr.getBType()); + BType type = astMapLiteralExpr.getBType(); + createNewTypedescInst(type, astMapLiteralExpr.pos); BIRVariableDcl tempVarDcl = - new BIRVariableDcl(astMapLiteralExpr.getBType(), this.env.nextLocalVarId(names), + new BIRVariableDcl(type, this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind.TEMP); this.env.enclFunc.localVars.add(tempVarDcl); BIROperand toVarRef = new BIROperand(tempVarDcl); setScopeAndEmit(new BIRNonTerminator.NewStructure(astMapLiteralExpr.pos, toVarRef, this.env.targetOperand, - generateMappingConstructorEntries(astMapLiteralExpr.fields), - astMapLiteralExpr.getBType())); + generateMappingConstructorEntries(astMapLiteralExpr.fields), type)); this.env.targetOperand = toVarRef; } @@ -1776,22 +1798,23 @@ public void visit(BLangStructLiteral astStructLiteralExpr) { VarKind.TEMP); this.env.enclFunc.localVars.add(tempVarDcl); BIROperand toVarRef = new BIROperand(tempVarDcl); + List fields = + generateMappingConstructorEntries(astStructLiteralExpr.fields); + setScopeAndEmit(createNewStructureInst(fields, toVarRef, type, astStructLiteralExpr.pos)); - BIRNonTerminator.NewStructure instruction; - if (Types.isUserDefinedTypeDefinition(type)) { - instruction = new BIRNonTerminator.NewStructure(astStructLiteralExpr.pos, toVarRef, toVarRef, - generateMappingConstructorEntries(astStructLiteralExpr.fields), type); - } else if (typeDescMap.containsKey(type)) { - instruction = new BIRNonTerminator.NewStructure(astStructLiteralExpr.pos, toVarRef, typeDescMap.get(type), - generateMappingConstructorEntries(astStructLiteralExpr.fields), type); + this.env.targetOperand = toVarRef; + } + + private BIRNonTerminator.NewStructure createNewStructureInst(List fields, + BIROperand toVarRef, BType type, Location pos) { + if (localTypedescMap.containsKey(type)) { + return new BIRNonTerminator.NewStructure(pos, toVarRef, localTypedescMap.get(type), fields, type); + } else if (Types.isUserDefinedTypeDefinition(type)) { + return new BIRNonTerminator.NewStructure(pos, toVarRef, toVarRef, fields, type); } else { - createNewTypeDescInst(type); - instruction = new BIRNonTerminator.NewStructure(astStructLiteralExpr.pos, toVarRef, this.env.targetOperand, - generateMappingConstructorEntries(astStructLiteralExpr.fields), type); + createNewTypedescInst(type, pos); + return new BIRNonTerminator.NewStructure(pos, toVarRef, this.env.targetOperand, fields, type); } - setScopeAndEmit(instruction); - - this.env.targetOperand = toVarRef; } private List mapToVarDcls(BType type) { @@ -2141,15 +2164,13 @@ public void visit(BLangWaitExpr waitExpr) { @Override public void visit(BLangWaitForAllExpr.BLangWaitLiteral waitLiteral) { - createNewTypeDescInst(waitLiteral.getBType()); BIRBasicBlock thenBB = new BIRBasicBlock(this.env.nextBBId(names)); addToTrapStack(thenBB); BIRVariableDcl tempVarDcl = new BIRVariableDcl(waitLiteral.getBType(), this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind.TEMP); this.env.enclFunc.localVars.add(tempVarDcl); BIROperand toVarRef = new BIROperand(tempVarDcl); - setScopeAndEmit(new BIRNonTerminator.NewStructure(waitLiteral.pos, toVarRef, this.env.targetOperand, - waitLiteral.getBType())); + setScopeAndEmit(createNewStructureInst(new ArrayList<>(), toVarRef, waitLiteral.getBType(), waitLiteral.pos)); this.env.targetOperand = toVarRef; List keys = new ArrayList<>(); @@ -2356,9 +2377,8 @@ public void visit(BLangXMLAccessExpr xmlAccessExpr) { @Override public void visit(BLangTypedescExpr accessExpr) { - BIRVariableDcl tempVarDcl = - new BIRVariableDcl(accessExpr.getBType(), this.env.nextLocalVarId(names), VarScope.FUNCTION, - VarKind.TEMP); + BIRVariableDcl tempVarDcl = new BIRVariableDcl(accessExpr.getBType(), this.env.nextLocalVarId(names), + VarScope.FUNCTION, VarKind.TEMP); this.env.enclFunc.localVars.add(tempVarDcl); BIROperand toVarRef = new BIROperand(tempVarDcl); setScopeAndEmit(new BIRNonTerminator.NewTypeDesc(accessExpr.pos, toVarRef, accessExpr.resolvedType, @@ -2412,20 +2432,35 @@ public void visit(BLangTableConstructorExpr tableConstructorExpr) { public void visit(BLangSimpleVarRef.BLangTypeLoad typeLoad) { BType type = typeLoad.symbol.tag == SymTag.TYPE_DEF ? ((BTypeDefinitionSymbol) typeLoad.symbol).referenceType : typeLoad.symbol.type; - createNewTypeDescInst(type); + createNewTypedescInst(type, typeLoad.pos); } - private void createNewTypeDescInst(BType type) { + private void createNewTypedescInst(BType type, Location position) { List varDcls = mapToVarDcls(type); - BIRVariableDcl tempVarDcl = - new BIRVariableDcl(symTable.typeDesc, this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind - .TEMP); - this.env.enclFunc.localVars.add(tempVarDcl); - BIROperand toVarRef = new BIROperand(tempVarDcl); - setScopeAndEmit(new BIRNonTerminator.NewTypeDesc(null, toVarRef, type, varDcls)); - this.env.targetOperand = toVarRef; - if (type.tsymbol != null && type.tsymbol.owner.getKind() != SymbolKind.PACKAGE) { - typeDescMap.put(type, toVarRef); + BTypeSymbol typeSymbol = type.tsymbol; + BIRVariableDcl tempVarDcl; + BIROperand toVarRef; + BIRNonTerminator.NewTypeDesc newTypeDesc; + if (this.env.enclBB == null) { + if (type.tag == TypeTags.RECORD || typeSymbol.name != Names.EMPTY) { + return; + } + tempVarDcl = new BIRGlobalVariableDcl(symTable.typeDesc, this.env.nextTypedescId(names), VarScope.GLOBAL, + VarKind.GLOBAL, 0, typeSymbol.pkgID, SymbolOrigin.VIRTUAL); + this.env.enclPkg.globalVars.add((BIRGlobalVariableDcl) tempVarDcl); + toVarRef = new BIROperand(tempVarDcl); + globalTypedescMap.put(type, toVarRef); + newTypeDesc = new BIRNonTerminator.NewTypeDesc(position, toVarRef, type, varDcls); + this.env.enclPkg.typedescs.add(newTypeDesc); + } else { + tempVarDcl = new BIRVariableDcl(symTable.typeDesc, this.env.nextLocalVarId(names), VarScope.FUNCTION, + VarKind.TEMP); + this.env.enclFunc.localVars.add(tempVarDcl); + toVarRef = new BIROperand(tempVarDcl); + newTypeDesc = new BIRNonTerminator.NewTypeDesc(position, toVarRef, type, varDcls); + this.env.targetOperand = toVarRef; + setScopeAndEmit(newTypeDesc); + localTypedescMap.put(type, toVarRef); } } @@ -2852,8 +2887,8 @@ private void generateListConstructorExpr(BLangListConstructorExpr listConstructo long size = -1L; List exprs = listConstructorExpr.exprs; - BType listConstructorExprType = listConstructorExpr.getBType(); - BType referredType = Types.getReferredType(listConstructorExprType); + BType type = listConstructorExpr.getBType(); + BType referredType = Types.getReferredType(type); if (referredType.tag == TypeTags.ARRAY && ((BArrayType) referredType).state != BArrayState.OPEN) { size = ((BArrayType) referredType).size; @@ -2862,7 +2897,8 @@ private void generateListConstructorExpr(BLangListConstructorExpr listConstructo } BLangLiteral literal = new BLangLiteral(); - literal.pos = listConstructorExpr.pos; + Location pos = listConstructorExpr.pos; + literal.pos = pos; literal.value = size; literal.setBType(symTable.intType); literal.accept(this); @@ -2880,29 +2916,33 @@ private void generateListConstructorExpr(BLangListConstructorExpr listConstructo initialValues.add(new BIRNode.BIRListConstructorExprEntry(this.env.targetOperand)); } } + setScopeAndEmit(createNewArrayInst(initialValues, type, sizeOp, toVarRef, referredType, pos)); + this.env.targetOperand = toVarRef; + } + private BIRNonTerminator.NewArray createNewArrayInst(List initialValues, + BType listConstructorExprType, BIROperand sizeOp, + BIROperand toVarRef, BType referredType, Location pos) { if (referredType.tag == TypeTags.TUPLE) { - if (Types.isUserDefinedTypeDefinition(referredType)) { - setScopeAndEmit( - new BIRNonTerminator.NewArray(listConstructorExpr.pos, listConstructorExprType, toVarRef, - toVarRef, sizeOp, initialValues)); - } else if (typeDescMap.containsKey(referredType)) { - setScopeAndEmit( - new BIRNonTerminator.NewArray(listConstructorExpr.pos, listConstructorExprType, toVarRef, - typeDescMap.get(referredType), sizeOp, initialValues)); + if (localTypedescMap.containsKey(referredType)) { + return new BIRNonTerminator.NewArray(pos, listConstructorExprType, toVarRef, + localTypedescMap.get(referredType), sizeOp, initialValues); + } else if (globalTypedescMap.containsKey(referredType)) { + return new BIRNonTerminator.NewArray(pos, listConstructorExprType, toVarRef, + globalTypedescMap.get(referredType), sizeOp, initialValues); + } else if (Types.isUserDefinedTypeDefinition(referredType)) { + return new BIRNonTerminator.NewArray(pos, listConstructorExprType, toVarRef, toVarRef, sizeOp, + initialValues); } else { - createNewTypeDescInst(listConstructorExprType); - setScopeAndEmit( - new BIRNonTerminator.NewArray(listConstructorExpr.pos, listConstructorExprType, toVarRef, - this.env.targetOperand, sizeOp, initialValues)); + createNewTypedescInst(listConstructorExprType, pos); + return new BIRNonTerminator.NewArray(pos, listConstructorExprType, toVarRef, this.env.targetOperand, + sizeOp, initialValues); } } else { BType eType = ((BArrayType) Types.getReferredType(listConstructorExprType)).eType; - setScopeAndEmit( - new BIRNonTerminator.NewArray(listConstructorExpr.pos, listConstructorExprType, toVarRef, - typeDescMap.getOrDefault(eType, null), sizeOp, initialValues)); + return new BIRNonTerminator.NewArray(pos, listConstructorExprType, toVarRef, + localTypedescMap.getOrDefault(eType, null), sizeOp, initialValues); } - this.env.targetOperand = toVarRef; } private void generateArrayAccess(BLangIndexBasedAccess astArrayAccessExpr) { From 32e4e513e3a41b5fbd286f5a5ef41caa7ccc401d Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Mon, 16 Jan 2023 20:42:11 +0530 Subject: [PATCH 37/58] BIR test update --- .../test-src/bir/bir-dump/failLockWithinLock | 131 +++++----- .../resources/test-src/bir/bir-dump/mapInits | 243 +++++++++--------- 2 files changed, 182 insertions(+), 192 deletions(-) diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/failLockWithinLock b/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/failLockWithinLock index 748fd9a295be..c25fa3e435d6 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/failLockWithinLock +++ b/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/failLockWithinLock @@ -1,123 +1,118 @@ failLockWithinLock function() -> (int, string) { %0(RETURN) (int, string); - %1(TEMP) typeDesc; - %2(SYNTHETIC) error|(); - %5(SYNTHETIC) error|(); - %8(SYNTHETIC) error|(); - %11(TEMP) boolean; - %13(TEMP) error; - %15(LOCAL) error; - %17(TEMP) string; - %19(TEMP) (); - %20(TEMP) typeDesc; - %21(TEMP) map; + %1(SYNTHETIC) error|(); + %4(SYNTHETIC) error|(); + %7(SYNTHETIC) error|(); + %10(TEMP) boolean; + %12(TEMP) error; + %14(LOCAL) error; + %16(TEMP) string; + %18(TEMP) (); + %19(TEMP) typeDesc; + %20(TEMP) map; + %21(TEMP) string; %22(TEMP) string; - %23(TEMP) string; - %24(TEMP) map; - %25(LOCAL) error; - %41(TEMP) int; + %23(TEMP) map; + %24(LOCAL) error; + %40(TEMP) int; bb0 { - %1 = newType (int, string); - GOTO bb1; + lock -> bb1; } bb1 { + lockWithinLockInt = ConstLoad 50; + lockWithinLockString = ConstLoad sample value; lock -> bb2; } bb2 { - lockWithinLockInt = ConstLoad 50; - lockWithinLockString = ConstLoad sample value; + lockWithinLockString = ConstLoad second sample value; + lockWithinLockInt = ConstLoad 99; lock -> bb3; } bb3 { - lockWithinLockString = ConstLoad second sample value; - lockWithinLockInt = ConstLoad 99; - lock -> bb4; + lockWithinLockInt = ConstLoad 90; + %7 = ConstLoad 0; + GOTO bb4; } bb4 { - lockWithinLockInt = ConstLoad 90; - %8 = ConstLoad 0; - GOTO bb5; + unlock -> bb5; } bb5 { - unlock -> bb6; + %10 = %7 is error; + %10? bb6 : bb7; } bb6 { - %11 = %8 is error; - %11? bb7 : bb8; + %12 = %7; + panic %12; } bb7 { - %13 = %8; - panic %13; + %16 = ConstLoad custom error; + %18 = ConstLoad 0; + %12 = %18; + %19 = newType map; + %21 = ConstLoad message; + %22 = ConstLoad error value; + %20 = NewMap %19; + %23 = cloneReadOnly(%20) -> bb8; } bb8 { - %17 = ConstLoad custom error; - %19 = ConstLoad 0; - %13 = %19; - %20 = newType map; - %22 = ConstLoad message; - %23 = ConstLoad error value; - %21 = NewMap %20; - %24 = cloneReadOnly(%21) -> bb9; + %14 = error error(%16, %12, %23); + GOTO bb9; } bb9 { - %15 = error error(%17, %13, %24); - GOTO bb10; + unlock -> bb10; } bb10 { - unlock -> bb11; - } - bb11 { - %25 = %15; + %24 = %14; lockWithinLockInt = ConstLoad 100; lockWithinLockString = ConstLoad Error caught; - %19 = ConstLoad 0; - GOTO bb16; + %18 = ConstLoad 0; + GOTO bb15; + } + bb11 { + %4 = ConstLoad 0; + GOTO bb15; } bb12 { - %5 = ConstLoad 0; - GOTO bb16; + unlock -> bb13; } bb13 { - unlock -> bb14; + %10 = %4 is error; + %10? bb14 : bb15; } bb14 { - %11 = %5 is error; - %11? bb15 : bb16; + %12 = %4; + panic %12; } bb15 { - %13 = %5; - panic %13; + %1 = ConstLoad 0; + GOTO bb16; } bb16 { - %2 = ConstLoad 0; - GOTO bb17; + unlock -> bb17; } bb17 { - unlock -> bb18; + %10 = %1 is error; + %10? bb18 : bb19; } bb18 { - %11 = %2 is error; - %11? bb19 : bb20; + %12 = %1; + panic %12; } bb19 { - %13 = %2; - panic %13; + %40 = ConstLoad 2; + %0 = newArray typedesc1[%40]; + GOTO bb20; } bb20 { - %41 = ConstLoad 2; - %0 = newArray %1[%41]; - GOTO bb21; - } - bb21 { return; } ------------------------------------------------------------- | trapBB | endBB | targetBB | errorOp | ------------------------------------------------------------- - | bb2 | bb16 | bb17 | %2 | - | bb3 | bb12 | bb13 | %5 | - | bb4 | bb4 | bb5 | %8 | + | bb1 | bb15 | bb16 | %1 | + | bb2 | bb11 | bb12 | %4 | + | bb3 | bb3 | bb4 | %7 | ------------------------------------------------------------- } \ No newline at end of file diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/mapInits b/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/mapInits index d0396d815ab1..3cb0dc051a9d 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/mapInits +++ b/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/mapInits @@ -1,259 +1,254 @@ mapInits function() -> (string|(), int|()) { %0(RETURN) (string|(), int|()); - %1(TEMP) typeDesc; - %2(LOCAL) map; - %3(TEMP) typeDesc; - %4(TEMP) typeDesc; - %6(LOCAL) Person; - %9(TEMP) string; + %1(LOCAL) map; + %2(TEMP) typeDesc; + %4(LOCAL) Person; + %6(TEMP) string; + %7(TEMP) string; + %8(TEMP) string; + %9(TEMP) int; %10(TEMP) string; %11(TEMP) string; - %12(TEMP) int; - %13(TEMP) string; - %14(TEMP) string; - %15(TEMP) Employee; - %21(SYNTHETIC) string|(); - %22(SYNTHETIC) Employee|(); - %26(SYNTHETIC) Employee|(); - %28(SYNTHETIC) boolean; - %29(SYNTHETIC) boolean; - %30(SYNTHETIC) any|error; - %31(TEMP) boolean; - %43(SYNTHETIC) boolean; - %44(SYNTHETIC) boolean; - %45(SYNTHETIC) any|error; - %61(SYNTHETIC) boolean; - %62(SYNTHETIC) boolean; - %72(TEMP) (); - %74(SYNTHETIC) int|(); - %75(SYNTHETIC) Employee|(); - %79(SYNTHETIC) Employee|(); - %81(SYNTHETIC) boolean; - %82(SYNTHETIC) boolean; - %83(SYNTHETIC) any|error; - %96(SYNTHETIC) boolean; - %97(SYNTHETIC) boolean; - %98(SYNTHETIC) any|error; - %110(TEMP) int; - %114(SYNTHETIC) boolean; - %115(SYNTHETIC) boolean; + %12(TEMP) Employee; + %18(SYNTHETIC) string|(); + %19(SYNTHETIC) Employee|(); + %23(SYNTHETIC) Employee|(); + %25(SYNTHETIC) boolean; + %26(SYNTHETIC) boolean; + %27(SYNTHETIC) any|error; + %28(TEMP) boolean; + %40(SYNTHETIC) boolean; + %41(SYNTHETIC) boolean; + %42(SYNTHETIC) any|error; + %58(SYNTHETIC) boolean; + %59(SYNTHETIC) boolean; + %69(TEMP) (); + %71(SYNTHETIC) int|(); + %72(SYNTHETIC) Employee|(); + %76(SYNTHETIC) Employee|(); + %78(SYNTHETIC) boolean; + %79(SYNTHETIC) boolean; + %80(SYNTHETIC) any|error; + %93(SYNTHETIC) boolean; + %94(SYNTHETIC) boolean; + %95(SYNTHETIC) any|error; + %107(TEMP) int; + %111(SYNTHETIC) boolean; + %112(SYNTHETIC) boolean; bb0 { - %1 = newType (string|(), int|()); - %3 = newType Employee; - %4 = newType map; - %2 = NewMap %4; - %4 = newType Person; - %9 = ConstLoad name; - %10 = ConstLoad Jack; - %11 = ConstLoad age; - %12 = ConstLoad 25; - %13 = ConstLoad address; - %14 = ConstLoad Usa; - %6 = NewMap %8; - %15 = %6; - %9 = ConstLoad jack; - %2[%9] = %15; - %12 = ConstLoad 2; - %10 = ConstLoad jack; - %22 = %2[%10]; - %26 = %22; - %31 = ConstLoad true; - %31? bb1 : bb2; + %2 = newType map; + %1 = NewMap %2; + %6 = ConstLoad name; + %7 = ConstLoad Jack; + %8 = ConstLoad age; + %9 = ConstLoad 25; + %10 = ConstLoad address; + %11 = ConstLoad Usa; + %4 = NewMap %5; + %12 = %4; + %6 = ConstLoad jack; + %1[%6] = %12; + %9 = ConstLoad 2; + %7 = ConstLoad jack; + %19 = %1[%7]; + %23 = %19; + %28 = ConstLoad true; + %28? bb1 : bb2; } bb1 { - %29 = ConstLoad true; - %30 = %26; + %26 = ConstLoad true; + %27 = %23; GOTO bb3; } bb2 { - %29 = ConstLoad false; + %26 = ConstLoad false; GOTO bb3; } bb3 { - %29? bb4 : bb5; + %26? bb4 : bb5; } bb4 { - %28 = %30 is (); + %25 = %27 is (); GOTO bb6; } bb5 { - %28 = ConstLoad false; + %25 = ConstLoad false; GOTO bb6; } bb6 { - %28? bb7 : bb8; + %25? bb7 : bb8; } bb7 { - %21 = %30; + %18 = %27; GOTO bb24; } bb8 { - %31 = ConstLoad true; - %31? bb9 : bb10; + %28 = ConstLoad true; + %28? bb9 : bb10; } bb9 { - %44 = ConstLoad true; - %45 = %26; + %41 = ConstLoad true; + %42 = %23; GOTO bb11; } bb10 { - %44 = ConstLoad false; + %41 = ConstLoad false; GOTO bb11; } bb11 { - %44? bb12 : bb13; + %41? bb12 : bb13; } bb12 { - %43 = %45 is Employee; + %40 = %42 is Employee; GOTO bb14; } bb13 { - %43 = ConstLoad false; + %40 = ConstLoad false; GOTO bb14; } bb14 { - %43? bb15 : bb16; + %40? bb15 : bb16; } bb15 { - %15 = %45; - %11 = ConstLoad name; - %13 = %15[%11]; - %21 = %13; + %12 = %42; + %8 = ConstLoad name; + %10 = %12[%8]; + %18 = %10; GOTO bb24; } bb16 { - %31 = ConstLoad true; - %31? bb17 : bb18; + %28 = ConstLoad true; + %28? bb17 : bb18; } bb17 { - %62 = ConstLoad true; + %59 = ConstLoad true; GOTO bb19; } bb18 { - %62 = %26 is any; + %59 = %23 is any; GOTO bb19; } bb19 { - %62? bb20 : bb21; + %59? bb20 : bb21; } bb20 { - %61 = ConstLoad true; + %58 = ConstLoad true; GOTO bb22; } bb21 { - %61 = ConstLoad false; + %58 = ConstLoad false; GOTO bb22; } bb22 { - %61? bb23 : bb24; + %58? bb23 : bb24; } bb23 { - %72 = ConstLoad 0; - %21 = %72; + %69 = ConstLoad 0; + %18 = %69; GOTO bb24; } bb24 { - %14 = ConstLoad jack; - %75 = %2[%14]; - %79 = %75; - %31 = ConstLoad true; - %31? bb25 : bb26; + %11 = ConstLoad jack; + %72 = %1[%11]; + %76 = %72; + %28 = ConstLoad true; + %28? bb25 : bb26; } bb25 { - %82 = ConstLoad true; - %83 = %79; + %79 = ConstLoad true; + %80 = %76; GOTO bb27; } bb26 { - %82 = ConstLoad false; + %79 = ConstLoad false; GOTO bb27; } bb27 { - %82? bb28 : bb29; + %79? bb28 : bb29; } bb28 { - %81 = %83 is (); + %78 = %80 is (); GOTO bb30; } bb29 { - %81 = ConstLoad false; + %78 = ConstLoad false; GOTO bb30; } bb30 { - %81? bb31 : bb32; + %78? bb31 : bb32; } bb31 { - %74 = %83; + %71 = %80; GOTO bb48; } bb32 { - %31 = ConstLoad true; - %31? bb33 : bb34; + %28 = ConstLoad true; + %28? bb33 : bb34; } bb33 { - %97 = ConstLoad true; - %98 = %79; + %94 = ConstLoad true; + %95 = %76; GOTO bb35; } bb34 { - %97 = ConstLoad false; + %94 = ConstLoad false; GOTO bb35; } bb35 { - %97? bb36 : bb37; + %94? bb36 : bb37; } bb36 { - %96 = %98 is Employee; + %93 = %95 is Employee; GOTO bb38; } bb37 { - %96 = ConstLoad false; + %93 = ConstLoad false; GOTO bb38; } bb38 { - %96? bb39 : bb40; + %93? bb39 : bb40; } bb39 { - %15 = %98; - %9 = ConstLoad age; - %110 = %15[%9]; - %74 = %110; + %12 = %95; + %6 = ConstLoad age; + %107 = %12[%6]; + %71 = %107; GOTO bb48; } bb40 { - %31 = ConstLoad true; - %31? bb41 : bb42; + %28 = ConstLoad true; + %28? bb41 : bb42; } bb41 { - %115 = ConstLoad true; + %112 = ConstLoad true; GOTO bb43; } bb42 { - %115 = %79 is any; + %112 = %76 is any; GOTO bb43; } bb43 { - %115? bb44 : bb45; + %112? bb44 : bb45; } bb44 { - %114 = ConstLoad true; + %111 = ConstLoad true; GOTO bb46; } bb45 { - %114 = ConstLoad false; + %111 = ConstLoad false; GOTO bb46; } bb46 { - %114? bb47 : bb48; + %111? bb47 : bb48; } bb47 { - %72 = ConstLoad 0; - %74 = %72; + %69 = ConstLoad 0; + %71 = %69; GOTO bb48; } bb48 { - %0 = newArray %1[%12]; + %0 = newArray typedesc0[%9]; GOTO bb49; } bb49 { From 0b954eeccda6e6f7a813c79b9edab058f4c3d159 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Mon, 16 Jan 2023 23:42:26 +0530 Subject: [PATCH 38/58] Add enclMapSymbols set in record type node visitor --- .../compiler/desugar/ClosureDesugar.java | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java index 6d5b19a337e6..74cf840e0630 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java @@ -36,7 +36,6 @@ import org.wso2.ballerinalang.compiler.semantics.model.symbols.BRecordTypeSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BVarSymbol; -import org.wso2.ballerinalang.compiler.semantics.model.types.BErrorType; import org.wso2.ballerinalang.compiler.semantics.model.types.BField; import org.wso2.ballerinalang.compiler.semantics.model.types.BInvokableType; import org.wso2.ballerinalang.compiler.semantics.model.types.BMapType; @@ -936,6 +935,7 @@ public void visit(BLangObjectTypeNode objectTypeNode) { @Override public void visit(BLangRecordTypeNode recordTypeNode) { + ((BRecordType) recordTypeNode.getBType()).enclMapSymbols = collectClosureMapSymbols(env, false); for (BLangSimpleVariable field : recordTypeNode.fields) { field.typeNode = rewrite(field.typeNode, env); } @@ -965,19 +965,6 @@ public void visit(BLangArrayType arrayType) { @Override public void visit(BLangUserDefinedType userDefinedType) { - BType type = userDefinedType.getBType(); - if (type == null) { - result = userDefinedType; - return; - } - if (type.tag == TypeTags.RECORD) { - ((BRecordType) type).enclMapSymbols = collectClosureMapSymbols(env, false); - } else if (type.tag == TypeTags.ERROR) { - BType detailType = ((BErrorType) type).detailType; - if (detailType.tag == TypeTags.RECORD) { - ((BRecordType) detailType).enclMapSymbols = collectClosureMapSymbols(env, false); - } - } result = userDefinedType; } From 87d3701fc79309a4f9f86e4bef8507143d0328a3 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 17 Jan 2023 00:12:53 +0530 Subject: [PATCH 39/58] Refactor logic --- .../org/wso2/ballerinalang/compiler/bir/BIRGen.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index 50821a49f511..c2e8488038d1 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -1260,8 +1260,9 @@ public void visit(BLangBuiltInRefTypeNode builtInRefTypeNode) { @Override public void visit(BLangTableTypeNode tableTypeNode) { tableTypeNode.constraint.accept(this); - if (tableTypeNode.tableKeyTypeConstraint != null) { - tableTypeNode.tableKeyTypeConstraint.accept(this); + BLangTableKeyTypeConstraint tableKeyTypeConstraint = tableTypeNode.tableKeyTypeConstraint; + if (tableKeyTypeConstraint != null) { + tableKeyTypeConstraint.accept(this); } } @@ -1269,8 +1270,9 @@ public void visit(BLangTableTypeNode tableTypeNode) { public void visit(BLangStreamType streamType) { streamType.type.accept(this); streamType.constraint.accept(this); - if (streamType.error != null) { - streamType.error.accept(this); + BLangType error = streamType.error; + if (error != null) { + error.accept(this); } } From 860a236ee5007c3fae3729e7ab44341d2cf79673 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 17 Jan 2023 00:57:59 +0530 Subject: [PATCH 40/58] Update variable visibility tests --- .../debugger/test/adapter/variables/VariableVisibilityTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/variables/VariableVisibilityTest.java b/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/variables/VariableVisibilityTest.java index aa7cfb5fd706..74ef3c28987a 100644 --- a/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/variables/VariableVisibilityTest.java +++ b/tests/jballerina-debugger-integration-test/src/test/java/org/ballerinalang/debugger/test/adapter/variables/VariableVisibilityTest.java @@ -86,7 +86,7 @@ public void newVariableVisibilityTest() throws BallerinaTestException { debugTestRunner.resumeProgram(debugHitInfo.getRight(), DebugTestRunner.DebugResumeKind.STEP_OVER); debugHitInfo = debugTestRunner.waitForDebugHit(15000); localVariables = debugTestRunner.fetchVariables(debugHitInfo.getRight(), DebugTestRunner.VariableScope.LOCAL); - Assert.assertEquals(localVariables.size(), 42); + Assert.assertEquals(localVariables.size(), 41); Assert.assertTrue(localVariables.containsKey("byteVar")); // debug point variable should be visible when multiple function returned values are present. From 1cf271a81a87d5454f6856905b57203501979988 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 17 Jan 2023 11:18:31 +0530 Subject: [PATCH 41/58] Fix review suggestions --- .../ballerinalang/compiler/bir/BIRGen.java | 59 +++++++------------ .../test-src/bir/bir-dump/failLockWithinLock | 2 +- 2 files changed, 21 insertions(+), 40 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index c2e8488038d1..820ee2103e53 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -77,7 +77,6 @@ import org.wso2.ballerinalang.compiler.semantics.model.symbols.SymTag; import org.wso2.ballerinalang.compiler.semantics.model.symbols.Symbols; import org.wso2.ballerinalang.compiler.semantics.model.types.BArrayType; -import org.wso2.ballerinalang.compiler.semantics.model.types.BIntersectionType; import org.wso2.ballerinalang.compiler.semantics.model.types.BInvokableType; import org.wso2.ballerinalang.compiler.semantics.model.types.BRecordType; import org.wso2.ballerinalang.compiler.semantics.model.types.BTableType; @@ -601,7 +600,10 @@ public void visit(BLangFunction astFunc) { this.env.unlockVars.push(new BIRLockDetailsHolder()); Name funcName; - analyzeParametersAndReturnType(astFunc); + List requiredParams = astFunc.requiredParams; + BLangSimpleVariable restParam = astFunc.restParam; + BLangType returnTypeNode = astFunc.returnTypeNode; + analyzeParametersAndReturnType(requiredParams, restParam, returnTypeNode); if (isTypeAttachedFunction) { funcName = names.fromString(astFunc.symbol.name.value); } else { @@ -639,12 +641,11 @@ public void visit(BLangFunction astFunc) { // Populate annotation attachments on return type BTypeSymbol tsymbol = astFunc.symbol.type.tsymbol; - if (astFunc.returnTypeNode != null && tsymbol != null) { + if (returnTypeNode != null && tsymbol != null) { birFunc.returnTypeAnnots.addAll(getBIRAnnotAttachments(((BInvokableTypeSymbol) tsymbol).returnTypeAnnots)); } - birFunc.argsCount = astFunc.requiredParams.size() - + (astFunc.restParam != null ? 1 : 0) + astFunc.paramClosureMap.size(); + birFunc.argsCount = requiredParams.size() + (restParam != null ? 1 : 0) + astFunc.paramClosureMap.size(); if (astFunc.flagSet.contains(Flag.ATTACHED) && typeDefs.containsKey(astFunc.receiver.getBType().tsymbol)) { typeDefs.get(astFunc.receiver.getBType().tsymbol).attachedFuncs.add(birFunc); } else { @@ -664,9 +665,9 @@ public void visit(BLangFunction astFunc) { astFunc.paramClosureMap.forEach((k, v) -> addRequiredParam(birFunc, v, astFunc.pos)); // Create variable declaration for function params - astFunc.requiredParams.forEach(requiredParam -> addParam(birFunc, requiredParam)); - if (astFunc.restParam != null) { - addRestParam(birFunc, astFunc.restParam.symbol, astFunc.restParam.pos); + requiredParams.forEach(requiredParam -> addParam(birFunc, requiredParam)); + if (restParam != null) { + addRestParam(birFunc, restParam.symbol, restParam.pos); } if (astFunc.flagSet.contains(Flag.RESOURCE)) { @@ -741,24 +742,24 @@ private BIRVariableDcl getSelf(BSymbol receiver) { return self; } - private void analyzeParametersAndReturnType(BLangFunction astFunc) { - BLangType typeNode = astFunc.returnTypeNode; - if (typeNode != null) { - typeNode.accept(this); - } - for (BLangSimpleVariable parameter : astFunc.requiredParams) { + private void analyzeParametersAndReturnType(List requiredParams, BLangVariable restParam, + BLangType returnTypeNode) { + BLangType typeNode; + for (BLangSimpleVariable parameter : requiredParams) { typeNode = parameter.typeNode; if (typeNode != null) { typeNode.accept(this); } } - BLangSimpleVariable restParam = astFunc.restParam; if (restParam != null) { typeNode = restParam.typeNode; if (typeNode != null) { typeNode.accept(this); } } + if (returnTypeNode != null) { + returnTypeNode.accept(this); + } } @Override @@ -1234,23 +1235,8 @@ public void visit(BLangErrorType errorType) { @Override public void visit(BLangFunctionTypeNode functionTypeNode) { - BLangType typeNode = functionTypeNode.returnTypeNode; - if (typeNode != null) { - typeNode.accept(this); - } - for (BLangSimpleVariable parameter : functionTypeNode.params) { - typeNode = parameter.typeNode; - if (typeNode != null) { - typeNode.accept(this); - } - } - BLangVariable restParam = functionTypeNode.restParam; - if (restParam != null) { - typeNode = restParam.typeNode; - if (typeNode != null) { - typeNode.accept(this); - } - } + analyzeParametersAndReturnType(functionTypeNode.params, functionTypeNode.restParam, + functionTypeNode.returnTypeNode); } @Override @@ -1297,13 +1283,8 @@ public void visit(BLangFiniteTypeNode finiteTypeNode) { @Override public void visit(BLangIntersectionTypeNode intersectionTypeNode) { - BType type = intersectionTypeNode.getBType(); - if (type.tag != TypeTags.INTERSECTION) { - return; - } - BType effectiveType = ((BIntersectionType) intersectionTypeNode.getBType()).effectiveType; - if (effectiveType.tag == TypeTags.RECORD || effectiveType.tag == TypeTags.TUPLE) { - createNewTypedescInst(effectiveType, intersectionTypeNode.pos); + for (BLangType typeNode : intersectionTypeNode.constituentTypeNodes) { + typeNode.accept(this); } } diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/failLockWithinLock b/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/failLockWithinLock index c25fa3e435d6..120b7e29f53c 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/failLockWithinLock +++ b/tests/jballerina-unit-test/src/test/resources/test-src/bir/bir-dump/failLockWithinLock @@ -115,4 +115,4 @@ failLockWithinLock function() -> (int, string) { | bb2 | bb11 | bb12 | %4 | | bb3 | bb3 | bb4 | %7 | ------------------------------------------------------------- -} \ No newline at end of file +} From 1db824ff7fd8e4838386941c399e3bfe6eb22f3e Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 21 Mar 2023 13:43:21 +0530 Subject: [PATCH 42/58] Resolve conflicts --- .../main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java | 2 +- .../compiler/bir/codegen/split/JvmCreateTypeGen.java | 2 +- .../compiler/bir/codegen/split/types/JvmRecordTypeGen.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index 000b6b70786e..d780ec7013fe 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -1154,7 +1154,7 @@ public void visit(BLangTupleTypeNode tupleTypeNode) { BType type = tupleTypeNode.getBType(); createNewTypedescInst(type, tupleTypeNode.pos); BLangType typeNode; - for (BLangSimpleVariable member : tupleTypeNode.memberTypeNodes) { + for (BLangSimpleVariable member : tupleTypeNode.members) { typeNode = member.typeNode; if (member.typeNode != null) { typeNode.accept(this); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java index 3d26d82449e9..e40af097b96c 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java @@ -383,7 +383,7 @@ private int createTypesInstanceSplits(ClassWriter cw, List ty } switch (getEffectiveType(bType).tag) { case TypeTags.RECORD: - jvmRecordTypeGen.createRecordType(mv, (BRecordType) bType); + jvmRecordTypeGen.createRecordType(mv, (BRecordType) bType, name); break; case TypeTags.OBJECT: jvmObjectTypeGen.createObjectType(mv, (BObjectType) bType); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/types/JvmRecordTypeGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/types/JvmRecordTypeGen.java index bb5b7f3f43c9..e6c387e2cdb0 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/types/JvmRecordTypeGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/types/JvmRecordTypeGen.java @@ -137,7 +137,7 @@ private void addRecordRestField(MethodVisitor mv, BType restFieldType) { * @param mv method visitor * @param recordType record type */ - public void createRecordType(MethodVisitor mv, BRecordType recordType) { + public void createRecordType(MethodVisitor mv, BRecordType recordType, String internalName) { // Create the record type mv.visitTypeInsn(NEW, RECORD_TYPE_IMPL); mv.visitInsn(DUP); From c2dd87bd5ad2e0e58be5454ba1fe11b1e6a02658 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 16 May 2023 13:00:28 +0530 Subject: [PATCH 43/58] Include global variables into top level nodes --- .../wso2/ballerinalang/compiler/desugar/ServiceDesugar.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ServiceDesugar.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ServiceDesugar.java index 1629b6b098b9..3587471143ed 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ServiceDesugar.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ServiceDesugar.java @@ -157,7 +157,7 @@ void rewriteServiceVariable(BLangService service, SymbolEnv env, BLangBlockStmt ASTBuilderUtil.defineVariable(service.serviceVariable, env.enclPkg.symbol, names); env.enclPkg.globalVars.add(service.serviceVariable); - + env.enclPkg.topLevelNodes.add(service.serviceVariable); int count = 0; for (BLangExpression attachExpr : service.attachedExprs) { // if y is anonymous -> y = y(expr) @@ -173,6 +173,7 @@ void rewriteServiceVariable(BLangService service, SymbolEnv env, BLangBlockStmt ASTBuilderUtil.defineVariable(listenerVar, env.enclPkg.symbol, names); listenerVar.symbol.flags |= Flags.LISTENER; env.enclPkg.globalVars.add(listenerVar); + env.enclPkg.topLevelNodes.add(listenerVar); listenerVarRef = ASTBuilderUtil.createVariableRef(pos, listenerVar.symbol); } @@ -187,6 +188,7 @@ void rewriteServiceVariable(BLangService service, SymbolEnv env, BLangBlockStmt null); ASTBuilderUtil.defineVariable(listenerWithoutErrors, env.enclPkg.symbol, names); env.enclPkg.globalVars.add(listenerWithoutErrors); + env.enclPkg.topLevelNodes.add(listenerWithoutErrors); BLangSimpleVarRef checkedRef = ASTBuilderUtil.createVariableRef(pos, listenerWithoutErrors.symbol); listenerVarRef = checkedRef; } From b9ac3b68f17159b229db711ace1d71e6a43c7d9b Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 16 May 2023 14:29:03 +0530 Subject: [PATCH 44/58] Rearrange top level nodes for improve order --- .../semantics/analyzer/DataflowAnalyzer.java | 26 ++++++-- .../cyclefind/GlobalVariableRefAnalyzer.java | 61 +++++++++++++------ 2 files changed, 65 insertions(+), 22 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/DataflowAnalyzer.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/DataflowAnalyzer.java index 35446de14f2c..6de493dace9f 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/DataflowAnalyzer.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/DataflowAnalyzer.java @@ -511,9 +511,11 @@ public void visit(BLangTypeDefinition typeDefinition) { if (typeDefinition.symbol.kind == SymbolKind.TYPE_DEF) { symbol = symbol.type.tsymbol; } - typeDefEnv = SymbolEnv.createTypeEnv(typeDefinition.typeNode, symbol.scope, env); this.currDependentSymbolDeque.push(symbol); - analyzeNode(typeDefinition.typeNode, typeDefEnv); + analyzeNode(typeDefinition.typeNode, env); + for (BLangAnnotationAttachment annAttachment : typeDefinition.annAttachments) { + analyzeNode(annAttachment, env); + } this.currDependentSymbolDeque.pop(); } @@ -640,7 +642,6 @@ public void visit(BLangSimpleVariableDef varDefNode) { @Override public void visit(BLangSimpleVariable variable) { BVarSymbol symbol = variable.symbol; - analyzeNode(variable.typeNode, env); if (symbol == null) { if (variable.expr != null) { analyzeNode(variable.expr, env); @@ -649,8 +650,11 @@ public void visit(BLangSimpleVariable variable) { } this.currDependentSymbolDeque.push(symbol); - if (variable.typeNode != null && variable.typeNode.getBType() != null) { - BType type = variable.typeNode.getBType(); + BLangType typeNode = variable.typeNode; + if (typeNode != null) { + analyzeNode(typeNode, env); + } else { + BType type = variable.symbol.getType(); recordGlobalVariableReferenceRelationship(Types.getReferredType(type).tsymbol); } boolean withInModuleVarLetExpr = symbol.owner.tag == SymTag.LET && isGlobalVarSymbol(env.enclVarSym); @@ -1938,6 +1942,7 @@ public void visit(BLangAnnotation annotationNode) { @Override public void visit(BLangAnnotationAttachment annAttachmentNode) { + analyzeNode(annAttachmentNode.expr, env); } @Override @@ -1989,6 +1994,17 @@ public void visit(BLangConstant constant) { boolean validVariable = constant.symbol != null; if (validVariable) { this.currDependentSymbolDeque.push(constant.symbol); + BLangType typeNode = constant.typeNode; + if (typeNode != null) { + analyzeNode(typeNode, env); + } else { + BType type = constant.symbol.getType(); + recordGlobalVariableReferenceRelationship(Types.getReferredType(type).tsymbol); + } + } + if (constant.associatedTypeDefinition != null) { + BLangType bLangType = constant.associatedTypeDefinition.typeNode; + analyzeNode(bLangType, env); } try { analyzeNode(constant.expr, env); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/cyclefind/GlobalVariableRefAnalyzer.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/cyclefind/GlobalVariableRefAnalyzer.java index 44910048288e..453a2eedad09 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/cyclefind/GlobalVariableRefAnalyzer.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/cyclefind/GlobalVariableRefAnalyzer.java @@ -31,6 +31,7 @@ import org.wso2.ballerinalang.compiler.tree.BLangFunction; import org.wso2.ballerinalang.compiler.tree.BLangIdentifier; import org.wso2.ballerinalang.compiler.tree.BLangPackage; +import org.wso2.ballerinalang.compiler.tree.BLangService; import org.wso2.ballerinalang.compiler.tree.BLangSimpleVariable; import org.wso2.ballerinalang.compiler.tree.BLangTypeDefinition; import org.wso2.ballerinalang.compiler.tree.BLangVariable; @@ -275,7 +276,7 @@ public void analyzeAndReOrder(BLangPackage pkgNode, Map> g sortConstants(sorted); projectSortToGlobalVarsList(sorted); - projectSortToTopLevelNodesList(); + projectSortToTopLevelNodesList(sorted); } private List analyzeDependenciesStartingFrom(BSymbol symbol) { @@ -348,26 +349,52 @@ private void addDependenciesDependencies(LinkedList dependencies, Set topLevelPositions = new ArrayList<>(); - for (BLangVariable globalVar : pkgNode.globalVars) { - topLevelPositions.add(pkgNode.topLevelNodes.indexOf(globalVar)); + private void projectSortToTopLevelNodesList(Set sorted) { + List orderedTopLevelNodes = new ArrayList<>(); + + for (BSymbol symbol : sorted) { + TopLevelNode matchedNode = findMatchingTopLevelNode(symbol); + if (matchedNode != null) { + orderedTopLevelNodes.add(matchedNode); + } } - topLevelPositions.sort(Comparator.comparingInt(i -> i)); - for (int i = 0; i < topLevelPositions.size(); i++) { - Integer targetIndex = topLevelPositions.get(i); - pkgNode.topLevelNodes.set(targetIndex, pkgNode.globalVars.get(i)); + + reorderTopLevelNodes(orderedTopLevelNodes); + } + + private TopLevelNode findMatchingTopLevelNode(BSymbol symbol) { + for (TopLevelNode topLevelNode : pkgNode.topLevelNodes) { + if (isMatchingNode(topLevelNode, symbol)) { + return topLevelNode; + } } + return null; + } - topLevelPositions = new ArrayList<>(); - for (BLangConstant constant : pkgNode.constants) { - topLevelPositions.add(pkgNode.topLevelNodes.indexOf(constant)); + private boolean isMatchingNode(TopLevelNode topLevelNode, BSymbol symbol) { + switch (topLevelNode.getKind()) { + case VARIABLE: + return ((BLangVariable) topLevelNode).symbol == symbol; + case FUNCTION: + return ((BLangFunction) topLevelNode).symbol == symbol; + case TYPE_DEFINITION: + return ((BLangTypeDefinition) topLevelNode).symbol.getType().tsymbol == symbol; + case CONSTANT: + return ((BLangConstant) topLevelNode).symbol == symbol; + case SERVICE: + return ((BLangService) topLevelNode).symbol == symbol; + case CLASS_DEFN: + return ((BLangClassDefinition) topLevelNode).symbol == symbol; + default: + return false; } - topLevelPositions.sort(Comparator.comparingInt(i -> i)); - for (int i = 0; i < topLevelPositions.size(); i++) { - Integer targetIndex = topLevelPositions.get(i); - pkgNode.topLevelNodes.set(targetIndex, pkgNode.constants.get(i)); + } + + private void reorderTopLevelNodes(List orderedTopLevelNodes) { + for (int i = orderedTopLevelNodes.size() - 1; i >= 0; i--) { + TopLevelNode topLevelNode = orderedTopLevelNodes.get(i); + pkgNode.topLevelNodes.remove(topLevelNode); + pkgNode.topLevelNodes.add(0, topLevelNode); } } From 416ef627e5ec9ef02a29bb0f3f57ab29eaa22e00 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 16 May 2023 14:31:12 +0530 Subject: [PATCH 45/58] Add closures to top level nodes --- .../wso2/ballerinalang/compiler/desugar/ClosureGenerator.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureGenerator.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureGenerator.java index 3ff21a53e246..a5d724833caa 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureGenerator.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureGenerator.java @@ -259,7 +259,9 @@ private void addClosuresToGlobalVariableList(SymbolEnv pkgEnv) { BLangSimpleVariable simpleVariable = queue.poll().var; simpleVariable.flagSet.add(Flag.PUBLIC); simpleVariable.symbol.flags |= Flags.PUBLIC; - pkgEnv.enclPkg.globalVars.add(0, rewrite(simpleVariable, pkgEnv)); + BLangSimpleVariable variableDef = rewrite(simpleVariable, pkgEnv); + pkgEnv.enclPkg.globalVars.add(0, variableDef); + pkgEnv.enclPkg.topLevelNodes.add(0, variableDef); } for (BLangSimpleVariableDef closureReference : annotationClosureReferences) { pkgEnv.enclPkg.globalVars.add(rewrite(closureReference.var, pkgEnv)); From a28787441bab8dc3315f7232ff3a37450d79c15d Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 16 May 2023 16:12:53 +0530 Subject: [PATCH 46/58] Add annotations to typedesc instructions --- .../org/wso2/ballerinalang/compiler/bir/BIRGen.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index d780ec7013fe..23743ba60e0f 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -2415,7 +2415,16 @@ private void createNewTypedescInst(BType type, Location position) { VarKind.TEMP); this.env.enclFunc.localVars.add(tempVarDcl); toVarRef = new BIROperand(tempVarDcl); - newTypeDesc = new BIRNonTerminator.NewTypeDesc(position, toVarRef, type, varDcls); + BIRVariableDcl annotationVarDcl = new BIRVariableDcl(symTable.mapType, this.env.nextLocalVarId(names), + VarScope.FUNCTION, VarKind.TEMP); + this.env.enclFunc.localVars.add(annotationVarDcl); + if (typeSymbol != null && typeSymbol.annotations != null && + globalVarMap.containsKey(typeSymbol.annotations)) { + newTypeDesc = new BIRNonTerminator.NewTypeDesc(position, toVarRef, type, varDcls, + new BIROperand(globalVarMap.get(typeSymbol.annotations))); + } else { + newTypeDesc = new BIRNonTerminator.NewTypeDesc(position, toVarRef, type, varDcls); + } this.env.targetOperand = toVarRef; setScopeAndEmit(newTypeDesc); localTypedescMap.put(type, toVarRef); From 2e97c693f3d79572b3b07b36b830a72c231a7f5a Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 16 May 2023 16:19:51 +0530 Subject: [PATCH 47/58] Exclude generation of typedesc for records prior to the initialization function --- .../compiler/bir/codegen/split/JvmCreateTypeGen.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java index e40af097b96c..98b90b951c29 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java @@ -18,7 +18,6 @@ package org.wso2.ballerinalang.compiler.bir.codegen.split; import org.ballerinalang.model.elements.PackageID; -import org.ballerinalang.model.symbols.SymbolKind; import org.ballerinalang.model.types.SelectivelyImmutableReferenceType; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Label; @@ -44,7 +43,6 @@ import org.wso2.ballerinalang.compiler.semantics.analyzer.TypeHashVisitor; import org.wso2.ballerinalang.compiler.semantics.analyzer.Types; import org.wso2.ballerinalang.compiler.semantics.model.SymbolTable; -import org.wso2.ballerinalang.compiler.semantics.model.symbols.BSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.Symbols; import org.wso2.ballerinalang.compiler.semantics.model.types.BErrorType; import org.wso2.ballerinalang.compiler.semantics.model.types.BField; @@ -141,8 +139,8 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.SET_IMMUTABLE_TYPE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.SET_LINKED_HASH_MAP; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.TYPE_DESC_CONSTRUCTOR; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmTypeGen.getTypeDesc; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.VOID_METHOD_DESC; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmTypeGen.getTypeDesc; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmTypeGen.getTypeFieldName; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmValueGen.getTypeDescClassName; import static org.wso2.ballerinalang.compiler.semantics.analyzer.Types.getEffectiveType; @@ -283,8 +281,7 @@ private void createTypedescInstances(ClassWriter cw, List typ mv.visitCode(); for (BIRTypeDefinition typeDefinition : typeDefs) { BType bType = JvmCodeGenUtil.getReferredType(typeDefinition.type); - BSymbol owner = bType.tsymbol.owner; - if (bType.tag == TypeTags.RECORD && (owner != null && owner.getKind() != SymbolKind.PACKAGE)) { + if (bType.tag == TypeTags.RECORD) { continue; } createTypedescInstance(mv, bType, typeDefinition, moduleInitClass); From a07302f2d6e66c28a274b271f92d5f7456f8457a Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 16 May 2023 17:15:44 +0530 Subject: [PATCH 48/58] Generation of typedesc for records type definitions --- .../bir/codegen/JvmInstructionGen.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java index f9e455a67514..c4a7e6a7987a 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java @@ -247,6 +247,7 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmTypeGen.getTypeDesc; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmValueGen.getTypeDescClassName; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmValueGen.getTypeValueClassName; +import static org.wso2.ballerinalang.compiler.semantics.analyzer.Types.getEffectiveType; /** * Instruction generator helper class to hold its enclosing pkg and index map. @@ -2109,6 +2110,7 @@ void generateNewTypedescIns(BIRNonTerminator.NewTypeDesc newTypeDesc) { PackageID packageID = type.tsymbol.pkgID; String typeOwner = JvmCodeGenUtil.getPackageName(packageID) + MODULE_INIT_CLASS_NAME; String fieldName = jvmTypeGen.getTypedescFieldName(toNameString(type)); + createTypedescInstance(mv, newTypeDesc.type, newTypeDesc, typeOwner); mv.visitFieldInsn(GETSTATIC, typeOwner, fieldName, GET_TYPEDESC); } else { generateNewTypedescCreate(newTypeDesc.type, closureVars, newTypeDesc.annotations); @@ -2116,6 +2118,33 @@ void generateNewTypedescIns(BIRNonTerminator.NewTypeDesc newTypeDesc) { this.storeToVar(newTypeDesc.lhsOp.variableDcl); } + private void createTypedescInstance(MethodVisitor mv, BType bType, BIRNonTerminator.NewTypeDesc typedesc, + String moduleInitClass) { + String className; + BType effectiveType = getEffectiveType(bType); + if (bType.tag == TypeTags.RECORD) { + PackageID pkgID = bType.tsymbol.pkgID; + String packageName = JvmCodeGenUtil.getPackageName(pkgID); + className = getTypeDescClassName(packageName, toNameString(bType)); + } else if (effectiveType.tag == TypeTags.TUPLE) { + bType = effectiveType; + className = TYPEDESC_VALUE_IMPL; + } else { + return; + } + + mv.visitTypeInsn(NEW, className); + mv.visitInsn(DUP); + jvmTypeGen.loadType(mv, JvmCodeGenUtil.getReferredType(bType)); + + mv.visitInsn(ACONST_NULL); + String constructorDesc = + typedesc.annotations != null ? TYPE_DESC_CONSTRUCTOR_WITH_ANNOTATIONS : TYPE_DESC_CONSTRUCTOR; + mv.visitMethodInsn(INVOKESPECIAL, className, JVM_INIT_METHOD, constructorDesc, false); + mv.visitFieldInsn(PUTSTATIC, moduleInitClass, + jvmTypeGen.getTypedescFieldName(typedesc.type.tsymbol.name.getValue()), GET_TYPEDESC); + } + private void generateNewTypedescCreate(BType btype, List closureVars, BIROperand annotations) { BType type = JvmCodeGenUtil.getReferredType(btype); String className = TYPEDESC_VALUE_IMPL; From 3d7c1fe43d52f92448af6a321af03ce5eceb9774 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Tue, 16 May 2023 20:00:11 +0530 Subject: [PATCH 49/58] Generate init function based on the order of top level nodes --- .../internal/values/TypedescValueImpl.java | 2 +- .../codegen/split/types/JvmRecordTypeGen.java | 2 - .../compiler/desugar/AnnotationDesugar.java | 60 +++--- .../compiler/desugar/Desugar.java | 176 ++++++++++++------ 4 files changed, 150 insertions(+), 90 deletions(-) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java index 0e78df4a23ad..e2b452039fd4 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java @@ -25,8 +25,8 @@ import io.ballerina.runtime.api.values.BMapInitialValueEntry; import io.ballerina.runtime.api.values.BTypedesc; import io.ballerina.runtime.internal.scheduling.Strand; -import io.ballerina.runtime.internal.types.BTypeReferenceType; import io.ballerina.runtime.internal.types.BAnnotatableType; +import io.ballerina.runtime.internal.types.BTypeReferenceType; import io.ballerina.runtime.internal.types.BTypedescType; import io.ballerina.runtime.internal.util.exceptions.BallerinaException; diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/types/JvmRecordTypeGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/types/JvmRecordTypeGen.java index e6c387e2cdb0..d89e87f9db71 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/types/JvmRecordTypeGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/types/JvmRecordTypeGen.java @@ -57,9 +57,7 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.RECORD_TYPE_IMPL_INIT; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.SET_LINKED_HASH_MAP; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.SET_MAP; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.TYPE_DESC_CONSTRUCTOR; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.VOID_METHOD_DESC; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmValueGen.getTypeDescClassName; /** * BIR record type to JVM byte code generation class. diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/AnnotationDesugar.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/AnnotationDesugar.java index dcd4f491994a..e89b8ac47209 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/AnnotationDesugar.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/AnnotationDesugar.java @@ -160,25 +160,22 @@ private AnnotationDesugar(CompilerContext context) { this.closureGenerator = ClosureGenerator.getInstance(context); } - /** - * Initialize annotation map. - * - * @param pkgNode package node - */ - void initializeAnnotationMap(BLangPackage pkgNode) { - annotationMap = createGlobalAnnotationMapVar(pkgNode); + void initializeAnnotationMap(BLangPackage pkgNode, BLangBlockFunctionBody initFnBody) { + annotationMap = createGlobalAnnotationMapVar(pkgNode, initFnBody); } - void rewritePackageAnnotations(BLangPackage pkgNode, SymbolEnv env) { + BLangBlockStmt rewritePackageAnnotations(BLangPackage pkgNode, SymbolEnv env) { BLangFunction initFunction = pkgNode.initFunction; - + BLangBlockStmt blockStmt = (BLangBlockStmt) TreeBuilder.createBlockNode(); defineTypeAnnotations(pkgNode, env, initFunction); - defineClassAnnotations(pkgNode, env, initFunction); - defineFunctionAnnotations(pkgNode, env, initFunction); + blockStmt.stmts.addAll(defineClassAnnotations(pkgNode, env, initFunction).stmts); + blockStmt.stmts.addAll(defineFunctionAnnotations(pkgNode, env, initFunction).stmts); + return blockStmt; } - private void defineClassAnnotations(BLangPackage pkgNode, SymbolEnv env2, BLangFunction initFunction) { + private BLangBlockStmt defineClassAnnotations(BLangPackage pkgNode, SymbolEnv env2, BLangFunction initFunction) { List topLevelNodes = pkgNode.topLevelNodes; + BLangBlockStmt blockStmt = (BLangBlockStmt) TreeBuilder.createBlockNode(); for (int i = 0, topLevelNodesSize = topLevelNodes.size(); i < topLevelNodesSize; i++) { TopLevelNode topLevelNode = topLevelNodes.get(i); @@ -228,27 +225,26 @@ private void defineClassAnnotations(BLangPackage pkgNode, SymbolEnv env2, BLangF BLangBlockStmt target = (BLangBlockStmt) TreeBuilder.createBlockNode(); target.pos = initBody.pos; addLambdaToGlobalAnnotMap(classDef.name.value, lambdaFunction, target); - int index = calculateIndex((initBody).stmts, type.tsymbol); - for (BLangStatement stmt : target.stmts) { - initBody.stmts.add(index++, stmt); - } + blockStmt.stmts.addAll(target.stmts); } else { // Add the lambda/invocation in a temporary block. LocationData locationData = new LocationData(pkgID, owner, pos, initBody); addAnnotationLambdaToGlobalAnnotationMapWithBlockDef(pkgNode, classDef, locationData, - lambdaFunction); + lambdaFunction, blockStmt); } } else { addInvocationToGlobalAnnotMap(classDef.name.value, lambdaFunction, initBody); } } } + return blockStmt; } private void addAnnotationLambdaToGlobalAnnotationMapWithBlockDef(BLangPackage pkgNode, BLangClassDefinition classDef, LocationData location, - BLangLambdaFunction lambdaFunction) { + BLangLambdaFunction lambdaFunction, + BLangBlockStmt allStmt) { BLangBlockStmt target = (BLangBlockStmt) TreeBuilder.createBlockNode(); PackageID pkgID = location.pkgID; Location pos = location.pos; @@ -291,10 +287,7 @@ private void addAnnotationLambdaToGlobalAnnotationMapWithBlockDef(BLangPackage p simpleVarRef.parent = initBody; assignmentStmt.parent = initBody; - int index = calculateOCEExprIndex(initBody.stmts, classDef.getBType().tsymbol); - for (BLangStatement stmt : target.stmts) { - initBody.stmts.add(index++, stmt); - } + allStmt.stmts.addAll(target.stmts); } private boolean isServiceDeclaration(BLangClassDefinition serviceClass) { @@ -480,9 +473,10 @@ private void defineTypeAnnotations(BLangPackage pkgNode, SymbolEnv env, BLangFun } } - private void defineFunctionAnnotations(BLangPackage pkgNode, SymbolEnv env, BLangFunction initFunction) { + private BLangBlockStmt defineFunctionAnnotations(BLangPackage pkgNode, SymbolEnv env, BLangFunction initFunction) { BLangBlockFunctionBody initFnBody = (BLangBlockFunctionBody) initFunction.body; BLangFunction[] functions = pkgNode.functions.toArray(new BLangFunction[pkgNode.functions.size()]); + BLangBlockStmt blockStmt = (BLangBlockStmt) TreeBuilder.createBlockNode(); for (BLangFunction function : functions) { PackageID pkgID = function.symbol.pkgID; BSymbol owner = function.symbol.owner; @@ -501,22 +495,18 @@ private void defineFunctionAnnotations(BLangPackage pkgNode, SymbolEnv env, BLan target.pos = initFnBody.pos; String identifier = function.attachedFunction ? function.symbol.name.value : function.name.value; - int index; if (function.attachedFunction && Symbols.isFlagOn(function.receiver.getBType().flags, Flags.OBJECT_CTOR)) { addLambdaToGlobalAnnotMap(identifier, lambdaFunction, target); - index = calculateIndex(initFnBody.stmts, function.receiver.getBType().tsymbol); } else { addInvocationToGlobalAnnotMap(identifier, lambdaFunction, target); - index = initFnBody.stmts.size(); } // Add the annotation assignment for resources to immediately before the service init. - for (BLangStatement stmt : target.stmts) { - initFnBody.stmts.add(index++, stmt); - } + blockStmt.stmts.addAll(target.stmts); } } + return blockStmt; } private void attachSchedulerPolicy(BLangFunction function) { @@ -930,6 +920,18 @@ private BLangSimpleVariable createGlobalAnnotationMapVar(BLangPackage pkgNode) { return annotationMap; } + private BLangSimpleVariable createGlobalAnnotationMapVar(BLangPackage pkgNode, BLangBlockFunctionBody initFnBody) { + BLangSimpleVariable annotationMap = ASTBuilderUtil.createVariable(pkgNode.pos, ANNOTATION_DATA, + symTable.mapType, + ASTBuilderUtil.createEmptyRecordLiteral( + pkgNode.pos, symTable.mapType), null); + ASTBuilderUtil.defineVariable(annotationMap, pkgNode.symbol, names); + pkgNode.globalVars.add(0, annotationMap); // TODO fix this + pkgNode.topLevelNodes.add(0, annotationMap); + desugar.addToInitFunction(annotationMap, initFnBody); + return annotationMap; + } + private void addTrueAnnot(BLangAnnotationAttachment attachment, BLangRecordLiteral recordLiteral, boolean isLocalObjectCtor) { // Handle scenarios where type is a subtype of `true` explicitly or implicitly (by omission). diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java index 74788bd05e79..0110d66b8e76 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java @@ -32,6 +32,7 @@ import org.ballerinalang.model.tree.NodeKind; import org.ballerinalang.model.tree.OperatorKind; import org.ballerinalang.model.tree.TopLevelNode; +import org.ballerinalang.model.tree.TypeDefinition; import org.ballerinalang.model.tree.expressions.NamedArgNode; import org.ballerinalang.model.tree.expressions.RecordLiteralNode; import org.ballerinalang.model.tree.expressions.XMLNavigationAccess; @@ -777,9 +778,6 @@ public void visit(BLangPackage pkgNode) { // create closures for default values closureGenerator.visit(pkgNode); - // Initialize the annotation map - annotationDesugar.initializeAnnotationMap(pkgNode); - pkgNode.constants.stream() .filter(constant -> constant.expr.getKind() == NodeKind.LITERAL || constant.expr.getKind() == NodeKind.NUMERIC_LITERAL) @@ -788,16 +786,16 @@ public void visit(BLangPackage pkgNode) { BLangBlockStmt serviceAttachments = serviceDesugar.rewriteServiceVariables(pkgNode.services, env); BLangBlockFunctionBody initFnBody = (BLangBlockFunctionBody) pkgNode.initFunction.body; - rewriteConstants(pkgNode, initFnBody); + // Initialize the annotation map + annotationDesugar.initializeAnnotationMap(pkgNode, initFnBody); pkgNode.constants = removeDuplicateConstants(pkgNode); - pkgNode.globalVars = desugarGlobalVariables(pkgNode, initFnBody); - pkgNode.services.forEach(service -> serviceDesugar.engageCustomServiceDesugar(service, env)); - desugarAnnotations(pkgNode); - + BLangBlockStmt bLangBlockStmt = desugarAnnotations(pkgNode); + desugarTopLevelNodes(pkgNode, initFnBody); + initFnBody.stmts.addAll(bLangBlockStmt.stmts); // Add invocation for user specified module init function (`init()`) if present and return. addUserDefinedModuleInitInvocationAndReturn(pkgNode); @@ -845,12 +843,13 @@ public void visit(BLangPackage pkgNode) { result = pkgNode; } - private void desugarAnnotations(BLangPackage pkgNode) { + private BLangBlockStmt desugarAnnotations(BLangPackage pkgNode) { List prevTypeDefinitions = new ArrayList<>(pkgNode.typeDefinitions); - annotationDesugar.rewritePackageAnnotations(pkgNode, env); + BLangBlockStmt bLangBlockStmt = annotationDesugar.rewritePackageAnnotations(pkgNode, env); addInitFunctionForRecordTypeNodeInTypeDef(pkgNode, prevTypeDefinitions); + return bLangBlockStmt; } private void addInitFunctionForRecordTypeNodeInTypeDef(BLangPackage pkgNode, @@ -986,64 +985,125 @@ private List getConfigurableLangLibInvocationParam(BLangSimpleV return new ArrayList<>(Arrays.asList(orgLiteral, moduleNameLiteral, versionLiteral, configNameLiteral, typedescExpr)); } + private BLangSimpleVariableDef createSimpleVarDef(BLangPackage pkgNode, String name, + BLangRecordTypeNode recordTypeNode) { + BType type = recordTypeNode.getBType(); + BVarSymbol varSymbol = new BVarSymbol(0, Names.fromString(name), pkgNode.packageID, type, + pkgNode.symbol, pkgNode.pos, VIRTUAL); + BLangSimpleVariable simpleVariable = ASTBuilderUtil.createVariable(pkgNode.pos, name, type, null, varSymbol); + BLangSimpleVariableDef simpleVariableDef = ASTBuilderUtil.createVariableDef(pkgNode.pos); + simpleVariableDef.var = simpleVariable; + simpleVariable.typeNode = recordTypeNode; + simpleVariableDef.setBType(simpleVariable.getBType()); + return simpleVariableDef; + } - private List desugarGlobalVariables(BLangPackage pkgNode, BLangBlockFunctionBody initFnBody) { + private void desugarTopLevelNodes(BLangPackage pkgNode, BLangBlockFunctionBody initFnBody) { List desugaredGlobalVarList = new ArrayList<>(); SymbolEnv initFunctionEnv = SymbolEnv.createFunctionEnv(pkgNode.initFunction, pkgNode.initFunction.symbol.scope, env); - for (BLangVariable globalVar : pkgNode.globalVars) { - this.env.enclPkg.topLevelNodes.remove(globalVar); - // This will convert complex variables to simple variables. - switch (globalVar.getKind()) { - case TUPLE_VARIABLE: - BLangNode blockStatementNode = rewrite(globalVar, initFunctionEnv); - List statements = ((BLangBlockStmt) blockStatementNode).stmts; - - int statementSize = statements.size(); - for (int i = 0; i < statementSize; i++) { - addToGlobalVariableList(statements.get(i), initFnBody, globalVar, desugaredGlobalVarList); - } - break; - case RECORD_VARIABLE: - case ERROR_VARIABLE: - blockStatementNode = rewrite(globalVar, initFunctionEnv); - for (BLangStatement statement : ((BLangBlockStmt) blockStatementNode).stmts) { - addToGlobalVariableList(statement, initFnBody, globalVar, desugaredGlobalVarList); - } - break; - default: - long globalVarFlags = globalVar.symbol.flags; - BLangSimpleVariable simpleGlobalVar = (BLangSimpleVariable) globalVar; - if (Symbols.isFlagOn(globalVarFlags, Flags.CONFIGURABLE)) { - if (Symbols.isFlagOn(globalVarFlags, Flags.REQUIRED)) { - // If it is required configuration get directly - List args = getConfigurableLangLibInvocationParam(simpleGlobalVar); - BLangInvocation getValueInvocation = createLangLibInvocationNode("getConfigurableValue", - args, symTable.anydataType, simpleGlobalVar.pos); - simpleGlobalVar.expr = getValueInvocation; - } else { - // If it is optional configuration create if else - simpleGlobalVar.expr = createIfElseFromConfigurable(simpleGlobalVar, initFunctionEnv); - } - } + int size = pkgNode.topLevelNodes.size(); + for (int j = 0; j < size; j++) { + TopLevelNode topLevelNode = pkgNode.topLevelNodes.remove(0); + if (topLevelNode.getKind() == NodeKind.TYPE_DEFINITION) { + desugarTypeDefinitions((TypeDefinition) topLevelNode, pkgNode, initFnBody); + } else if (topLevelNode.getKind() == NodeKind.CONSTANT) { + desugarConstantVariables((BLangConstant) topLevelNode, initFunctionEnv, initFnBody); + } + if (!(pkgNode.globalVars.contains(topLevelNode))) { + pkgNode.topLevelNodes.add(topLevelNode); + continue; + } - // Module init should fail if listener is a error value. - if (Symbols.isFlagOn(globalVarFlags, Flags.LISTENER) - && types.containsErrorType(globalVar.expr.getBType())) { - globalVar.expr = ASTBuilderUtil.createCheckExpr(globalVar.expr.pos, globalVar.expr, - globalVar.getBType()); - } + BLangVariable globalVar = (BLangVariable) topLevelNode; + desugaredGlobalVarList.addAll(desugarGlobalVariables(globalVar, initFunctionEnv, initFnBody)); - addToInitFunction(simpleGlobalVar, initFnBody); - desugaredGlobalVarList.add(simpleGlobalVar); - break; - } } this.env.enclPkg.topLevelNodes.addAll(desugaredGlobalVarList); - return desugaredGlobalVarList; + this.env.enclPkg.globalVars = desugaredGlobalVarList; + } + + private void desugarTypeDefinitions(TypeDefinition typeDefinition , BLangPackage pkgNode, + BLangBlockFunctionBody initFnBody) { + TypeNode typeNode = typeDefinition.getTypeNode(); + if (typeNode != null && typeNode.getKind() == NodeKind.RECORD_TYPE) { + BLangRecordTypeNode recordTypeNode = (BLangRecordTypeNode) typeNode; + BLangSimpleVariableDef bLangSimpleVariableDef = + createSimpleVarDef(pkgNode, recordTypeNode.getBType().tsymbol.name.getValue(), recordTypeNode); + initFnBody.stmts.add(bLangSimpleVariableDef); + } + } + + private void desugarConstantVariables(BLangConstant constant, SymbolEnv initFunctionEnv, + BLangBlockFunctionBody initFnBody) { + BType constType = Types.getReferredType(constant.symbol.type); + if (constType.tag != TypeTags.INTERSECTION) { + return; + } + for (BType memberType : ((BIntersectionType) constType).getConstituentTypes()) { + if (memberType.tag != TypeTags.RECORD) { + continue; + } + BLangSimpleVarRef constVarRef = ASTBuilderUtil.createVariableRef(constant.pos, constant.symbol); + constant.expr = rewrite(constant.expr, initFunctionEnv); + BLangAssignment constInit = ASTBuilderUtil.createAssignmentStmt(constant.pos, constVarRef, + constant.expr); + initFnBody.stmts.add(constInit); + } + } + +private List desugarGlobalVariables(BLangVariable globalVar, SymbolEnv initFunctionEnv, + BLangBlockFunctionBody initFnBody) { + List desugaredGlobalVarList = new ArrayList<>(); + // This will convert complex variables to simple variables. + switch (globalVar.getKind()) { + case TUPLE_VARIABLE: + BLangNode blockStatementNode = rewrite(globalVar, initFunctionEnv); + List statements = ((BLangBlockStmt) blockStatementNode).stmts; + + int statementSize = statements.size(); + for (int i = 0; i < statementSize; i++) { + addToGlobalVariableList(statements.get(i), initFnBody, globalVar, desugaredGlobalVarList); + } + break; + case RECORD_VARIABLE: + case ERROR_VARIABLE: + blockStatementNode = rewrite(globalVar, initFunctionEnv); + for (BLangStatement statement : ((BLangBlockStmt) blockStatementNode).stmts) { + addToGlobalVariableList(statement, initFnBody, globalVar, desugaredGlobalVarList); + } + break; + default: + long globalVarFlags = globalVar.symbol.flags; + BLangSimpleVariable simpleGlobalVar = (BLangSimpleVariable) globalVar; + if (Symbols.isFlagOn(globalVarFlags, Flags.CONFIGURABLE)) { + if (Symbols.isFlagOn(globalVarFlags, Flags.REQUIRED)) { + // If it is required configuration get directly + List args = getConfigurableLangLibInvocationParam(simpleGlobalVar); + BLangInvocation getValueInvocation = createLangLibInvocationNode("getConfigurableValue", + args, symTable.anydataType, simpleGlobalVar.pos); + simpleGlobalVar.expr = getValueInvocation; + } else { + // If it is optional configuration create if else + simpleGlobalVar.expr = createIfElseFromConfigurable(simpleGlobalVar, initFunctionEnv); + } + } + + // Module init should fail if listener is a error value. + if (Symbols.isFlagOn(globalVarFlags, Flags.LISTENER) + && types.containsErrorType(globalVar.expr.getBType())) { + globalVar.expr = ASTBuilderUtil.createCheckExpr(globalVar.expr.pos, globalVar.expr, + globalVar.getBType()); + } + + addToInitFunction(simpleGlobalVar, initFnBody); + desugaredGlobalVarList.add(simpleGlobalVar); + break; } + return desugaredGlobalVarList; +} private void addToGlobalVariableList(BLangStatement bLangStatement, BLangBlockFunctionBody initFnBody, BLangVariable globalVar, List desugaredGlobalVarList) { @@ -1063,7 +1123,7 @@ private void addToGlobalVariableList(BLangStatement bLangStatement, BLangBlockFu } } - private void addToInitFunction(BLangSimpleVariable globalVar, BLangBlockFunctionBody initFnBody) { + public void addToInitFunction(BLangSimpleVariable globalVar, BLangBlockFunctionBody initFnBody) { if (globalVar.expr == null) { return; } From b97793505beb2a79fdd4b5ffabbd357539e09db8 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Sun, 21 May 2023 20:25:46 +0530 Subject: [PATCH 50/58] Update dependency relations logic --- .../semantics/analyzer/DataflowAnalyzer.java | 19 ++++++--- .../cyclefind/GlobalVariableRefAnalyzer.java | 41 ------------------- 2 files changed, 13 insertions(+), 47 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/DataflowAnalyzer.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/DataflowAnalyzer.java index 6de493dace9f..465c77cf62a5 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/DataflowAnalyzer.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/DataflowAnalyzer.java @@ -1445,6 +1445,8 @@ public void visit(BLangRecordLiteral recordLiteral) { analyzeNode(((BLangRecordLiteral.BLangRecordSpreadOperatorField) field).expr, env); } } + BType type = recordLiteral.getBType(); + recordGlobalVariableReferenceRelationship(Types.getReferredType(type).tsymbol); } @Override @@ -1544,6 +1546,7 @@ public void visit(BLangInvocation invocationExpr) { @Override public void visit(BLangErrorConstructorExpr errorConstructorExpr) { + analyzeNode(errorConstructorExpr.errorTypeRef, env); for (BLangExpression positionalArg : errorConstructorExpr.positionalArgs) { analyzeNode(positionalArg, env); } @@ -1740,11 +1743,7 @@ private boolean isGlobalVarSymbol(BSymbol symbol) { return false; } else if (symbol.owner == null) { return false; - } else if (symbol.owner.tag != SymTag.PACKAGE) { - return false; - } - - return isVariableOrConstant(symbol); + } else return symbol.owner.tag == SymTag.PACKAGE; } private boolean isVariableOrConstant(BSymbol symbol) { @@ -2085,6 +2084,7 @@ public void visit(BLangObjectTypeNode objectTypeNode) { @Override public void visit(BLangRecordTypeNode recordTypeNode) { BTypeSymbol tsymbol = Types.getReferredType(recordTypeNode.getBType()).tsymbol; + recordGlobalVariableReferenceRelationship(tsymbol); for (TypeNode type : recordTypeNode.getTypeReferences()) { BLangType bLangType = (BLangType) type; analyzeNode(bLangType, env); @@ -2217,6 +2217,7 @@ public void visit(BLangInferredTypedescDefaultNode inferTypedescExpr) { @Override public void visit(BLangErrorType errorType) { + analyzeNode(errorType.detailType, env); } @Override @@ -2269,7 +2270,13 @@ public void visit(BLangTupleVariableDef bLangTupleVariableDef) { @Override public void visit(BLangRecordVariable bLangRecordVariable) { - analyzeNode(bLangRecordVariable.typeNode, env); + BLangType typeNode = bLangRecordVariable.typeNode; + if (typeNode != null) { + analyzeNode(typeNode, env); + } else { + BType type = bLangRecordVariable.symbol.getType(); + recordGlobalVariableReferenceRelationship(Types.getReferredType(type).tsymbol); + } populateUnusedVariableMapForNonSimpleBindingPatternVariables(this.unusedLocalVariables, bLangRecordVariable); this.currDependentSymbolDeque.push(bLangRecordVariable.symbol); analyzeNode(bLangRecordVariable.expr, env); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/cyclefind/GlobalVariableRefAnalyzer.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/cyclefind/GlobalVariableRefAnalyzer.java index 453a2eedad09..6306a9e67d4b 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/cyclefind/GlobalVariableRefAnalyzer.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/cyclefind/GlobalVariableRefAnalyzer.java @@ -242,8 +242,6 @@ public void analyzeAndReOrder(BLangPackage pkgNode, Map> g List globalVarsAndDependentFuncs = getGlobalVariablesAndDependentFunctions(); - pruneDependencyRelations(); - Set sorted = new LinkedHashSet<>(); LinkedList dependencies = new LinkedList<>(); @@ -299,45 +297,6 @@ private List analyzeDependenciesStartingFrom(BSymbol symbol) { return new ArrayList<>(); } - private void pruneDependencyRelations() { - List dependents = new ArrayList<>(this.globalNodeDependsOn.keySet()); - Set visited = new HashSet<>(); - for (BSymbol dependent : dependents) { - // Taking a copy as we need to modify the original list. - List providers = new ArrayList<>(this.globalNodeDependsOn.get(dependent)); - for (BSymbol provider : providers) { - pruneFunctions(dependent, provider, this.globalNodeDependsOn, visited); - } - } - } - - private void pruneFunctions(BSymbol dependent, BSymbol provider, Map> globalNodeDependsOn, - Set visited) { - if (visited.contains(provider)) { - return; - } else { - visited.add(provider); - } - - // Dependent has a dependency on a global var. - if (provider.tag != SymTag.FUNCTION) { - return; - } - - // Provider is a function. - // And doesn't have dependency on a global variable. We can prune provider. - if (!globalNodeDependsOn.containsKey(provider) || globalNodeDependsOn.get(provider).isEmpty()) { - globalNodeDependsOn.get(dependent).remove(provider); - return; - } - - // Taking a copy as we need to modify the original list. - List providersProviders = new ArrayList<>(globalNodeDependsOn.get(provider)); - for (BSymbol prov : providersProviders) { - pruneFunctions(provider, prov, globalNodeDependsOn, visited); - } - } - private void addDependenciesDependencies(LinkedList dependencies, Set sorted) { // For each dependency if they satisfy their dependencies in sorted list, then add them to sorted list. ArrayList depCopy = new ArrayList<>(dependencies); From 3de5bb878f51448756e7c81b504553bbf59342a2 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Sun, 21 May 2023 20:32:07 +0530 Subject: [PATCH 51/58] Add generated global level stmts related to annotations after generating the init function with global variables --- .../compiler/desugar/ASTBuilderUtil.java | 6 ++ .../compiler/desugar/AnnotationDesugar.java | 55 ++++++++++--------- .../semantics/analyzer/DataflowAnalyzer.java | 4 +- 3 files changed, 37 insertions(+), 28 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ASTBuilderUtil.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ASTBuilderUtil.java index 977f838261e5..937d93c8c7f9 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ASTBuilderUtil.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ASTBuilderUtil.java @@ -290,6 +290,12 @@ static BLangAssignment createAssignmentStmt(Location pos, BlockNode target) { return assignment; } + static BLangAssignment createAssignmentStmt(Location pos) { + final BLangAssignment assignment = (BLangAssignment) TreeBuilder.createAssignmentNode(); + assignment.pos = pos; + return assignment; + } + static BLangAssignment createAssignmentStmt(Location pos, BLangExpression varRef, BLangExpression rhsExpr) { final BLangAssignment assignment = (BLangAssignment) TreeBuilder.createAssignmentNode(); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/AnnotationDesugar.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/AnnotationDesugar.java index e89b8ac47209..4417893fe85f 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/AnnotationDesugar.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/AnnotationDesugar.java @@ -167,7 +167,7 @@ void initializeAnnotationMap(BLangPackage pkgNode, BLangBlockFunctionBody initFn BLangBlockStmt rewritePackageAnnotations(BLangPackage pkgNode, SymbolEnv env) { BLangFunction initFunction = pkgNode.initFunction; BLangBlockStmt blockStmt = (BLangBlockStmt) TreeBuilder.createBlockNode(); - defineTypeAnnotations(pkgNode, env, initFunction); + blockStmt.stmts.addAll(defineTypeAnnotations(pkgNode, env, initFunction).stmts); blockStmt.stmts.addAll(defineClassAnnotations(pkgNode, env, initFunction).stmts); blockStmt.stmts.addAll(defineFunctionAnnotations(pkgNode, env, initFunction).stmts); return blockStmt; @@ -224,8 +224,8 @@ private BLangBlockStmt defineClassAnnotations(BLangPackage pkgNode, SymbolEnv en // Add the lambda/invocation in a temporary block. BLangBlockStmt target = (BLangBlockStmt) TreeBuilder.createBlockNode(); target.pos = initBody.pos; - addLambdaToGlobalAnnotMap(classDef.name.value, lambdaFunction, target); blockStmt.stmts.addAll(target.stmts); + blockStmt.stmts.add(addLambdaToGlobalAnnotMap(classDef.name.value, lambdaFunction, target)); } else { // Add the lambda/invocation in a temporary block. LocationData locationData = new LocationData(pkgID, owner, pos, initBody); @@ -233,7 +233,7 @@ private BLangBlockStmt defineClassAnnotations(BLangPackage pkgNode, SymbolEnv en lambdaFunction, blockStmt); } } else { - addInvocationToGlobalAnnotMap(classDef.name.value, lambdaFunction, initBody); + blockStmt.stmts.add(addInvocationToGlobalAnnotMap(classDef.name.value, lambdaFunction, initBody)); } } } @@ -278,16 +278,15 @@ private void addAnnotationLambdaToGlobalAnnotationMapWithBlockDef(BLangPackage p StringEscapeUtils.unescapeJava(classDef.name.value)); indexAccessNode.expr = ASTBuilderUtil.createVariableRef(pos, annotationMap.symbol); indexAccessNode.setBType(((BMapType) annotationMap.getBType()).constraint); - + allStmt.stmts.addAll(target.stmts); // $annotation_data[$anonType$_1] = $anon$anonType$_1_lamda - BLangAssignment assignmentStmt = ASTBuilderUtil.createAssignmentStmt(pos, target); + BLangAssignment assignmentStmt = ASTBuilderUtil.createAssignmentStmt(pos); + allStmt.stmts.add(assignmentStmt); assignmentStmt.expr = simpleVarRef; assignmentStmt.varRef = indexAccessNode; simpleVarRef.parent = initBody; assignmentStmt.parent = initBody; - - allStmt.stmts.addAll(target.stmts); } private boolean isServiceDeclaration(BLangClassDefinition serviceClass) { @@ -448,7 +447,8 @@ void defineStatementAnnotations(List attachments, addAnnotsToLiteral(attachments, mapLiteral, location, env, false); } - private void defineTypeAnnotations(BLangPackage pkgNode, SymbolEnv env, BLangFunction initFunction) { + private BLangBlockStmt defineTypeAnnotations(BLangPackage pkgNode, SymbolEnv env, BLangFunction initFunction) { + BLangBlockStmt blockStmt = (BLangBlockStmt) TreeBuilder.createBlockNode(); for (BLangTypeDefinition typeDef : pkgNode.typeDefinitions) { if (typeDef.isBuiltinTypeDef) { continue; @@ -468,9 +468,11 @@ private void defineTypeAnnotations(BLangPackage pkgNode, SymbolEnv env, BLangFun } if (lambdaFunction != null) { - addInvocationToGlobalAnnotMap(typeDef.name.value, lambdaFunction, initFunction.body); + blockStmt.stmts.add(addInvocationToGlobalAnnotMap(typeDef.name.value, lambdaFunction, + initFunction.body)); } } + return blockStmt; } private BLangBlockStmt defineFunctionAnnotations(BLangPackage pkgNode, SymbolEnv env, BLangFunction initFunction) { @@ -494,16 +496,14 @@ private BLangBlockStmt defineFunctionAnnotations(BLangPackage pkgNode, SymbolEnv BLangBlockStmt target = (BLangBlockStmt) TreeBuilder.createBlockNode(); target.pos = initFnBody.pos; String identifier = function.attachedFunction ? function.symbol.name.value : function.name.value; - + // Add the annotation assignment for resources to immediately before the service init. + blockStmt.stmts.addAll(target.stmts); if (function.attachedFunction && Symbols.isFlagOn(function.receiver.getBType().flags, Flags.OBJECT_CTOR)) { - addLambdaToGlobalAnnotMap(identifier, lambdaFunction, target); + blockStmt.stmts.add(addLambdaToGlobalAnnotMap(identifier, lambdaFunction, target)); } else { - addInvocationToGlobalAnnotMap(identifier, lambdaFunction, target); + blockStmt.stmts.add(addInvocationToGlobalAnnotMap(identifier, lambdaFunction, target)); } - - // Add the annotation assignment for resources to immediately before the service init. - blockStmt.stmts.addAll(target.stmts); } } return blockStmt; @@ -968,24 +968,24 @@ private void addAnnotArray(Location pos, String name, BType annotType, addAnnotValueToLiteral(recordLiteral, name, arrayLiteral, pos); } - private void addInvocationToGlobalAnnotMap(String identifier, BLangLambdaFunction lambdaFunction, + private BLangAssignment addInvocationToGlobalAnnotMap(String identifier, BLangLambdaFunction lambdaFunction, BLangBlockStmt target) { // create: $annotation_data["identifier"] = $annot_func$.call(); - addAnnotValueAssignmentToMap(annotationMap, identifier, target, + return addAnnotValueAssignmentToMap(annotationMap, identifier, target, getInvocation(lambdaFunction)); } - private void addInvocationToGlobalAnnotMap(String identifier, BLangLambdaFunction lambdaFunction, + private BLangAssignment addInvocationToGlobalAnnotMap(String identifier, BLangLambdaFunction lambdaFunction, BLangFunctionBody target) { // create: $annotation_data["identifier"] = $annot_func$.call(); - addAnnotValueAssignmentToMap(annotationMap, identifier, (BLangBlockFunctionBody) target, + return addAnnotValueAssignmentToMap(annotationMap, identifier, (BLangBlockFunctionBody) target, getInvocation(lambdaFunction)); } - private void addLambdaToGlobalAnnotMap(String identifier, BLangLambdaFunction lambdaFunction, + private BLangAssignment addLambdaToGlobalAnnotMap(String identifier, BLangLambdaFunction lambdaFunction, BLangBlockStmt target) { // create: $annotation_data["identifier"] = $annot_func$; - addAnnotValueAssignmentToMap(annotationMap, identifier, target, + return addAnnotValueAssignmentToMap(annotationMap, identifier, target, ASTBuilderUtil.createVariableRef(lambdaFunction.pos, lambdaFunction.function.symbol)); } @@ -1013,10 +1013,10 @@ private BLangInvocation getInvocation(BInvokableSymbol symbol) { return funcInvocation; } - private void addAnnotValueAssignmentToMap(BLangSimpleVariable mapVar, String identifier, + private BLangAssignment addAnnotValueAssignmentToMap(BLangSimpleVariable mapVar, String identifier, BlockNode target, Location targetPos, BLangExpression expression) { - BLangAssignment assignmentStmt = ASTBuilderUtil.createAssignmentStmt(targetPos, target); + BLangAssignment assignmentStmt = ASTBuilderUtil.createAssignmentStmt(targetPos); assignmentStmt.expr = expression; BLangIndexBasedAccess indexAccessNode = (BLangIndexBasedAccess) TreeBuilder.createIndexBasedAccessNode(); @@ -1026,16 +1026,17 @@ private void addAnnotValueAssignmentToMap(BLangSimpleVariable mapVar, String ide indexAccessNode.expr = ASTBuilderUtil.createVariableRef(targetPos, mapVar.symbol); indexAccessNode.setBType(((BMapType) mapVar.getBType()).constraint); assignmentStmt.varRef = indexAccessNode; + return assignmentStmt; } - private void addAnnotValueAssignmentToMap(BLangSimpleVariable mapVar, String identifier, + private BLangAssignment addAnnotValueAssignmentToMap(BLangSimpleVariable mapVar, String identifier, BLangBlockFunctionBody target, BLangExpression expression) { - addAnnotValueAssignmentToMap(mapVar, identifier, target, target.pos, expression); + return addAnnotValueAssignmentToMap(mapVar, identifier, target, target.pos, expression); } - private void addAnnotValueAssignmentToMap(BLangSimpleVariable mapVar, String identifier, + private BLangAssignment addAnnotValueAssignmentToMap(BLangSimpleVariable mapVar, String identifier, BLangBlockStmt target, BLangExpression expression) { - addAnnotValueAssignmentToMap(mapVar, identifier, target, target.pos, expression); + return addAnnotValueAssignmentToMap(mapVar, identifier, target, target.pos, expression); } private void addAnnotValueToLiteral(BLangRecordLiteral recordLiteral, String identifier, diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/DataflowAnalyzer.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/DataflowAnalyzer.java index 465c77cf62a5..7cf7a94461af 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/DataflowAnalyzer.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/DataflowAnalyzer.java @@ -1743,7 +1743,9 @@ private boolean isGlobalVarSymbol(BSymbol symbol) { return false; } else if (symbol.owner == null) { return false; - } else return symbol.owner.tag == SymTag.PACKAGE; + } else { + return symbol.owner.tag == SymTag.PACKAGE; + } } private boolean isVariableOrConstant(BSymbol symbol) { From 3ef8c5d484b48403cf3220d2601a0e5e5e93060f Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Mon, 22 May 2023 12:05:15 +0530 Subject: [PATCH 52/58] Update type of `astStructLiteralExpr` --- .../main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index 57a5df8e233f..f8d3fea3178f 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -1754,7 +1754,7 @@ public void visit(BLangTypeConversionExpr astTypeConversionExpr) { @Override public void visit(BLangStructLiteral astStructLiteralExpr) { - BType type = astStructLiteralExpr.getBType(); + BType type = Types.getReferredType(astStructLiteralExpr.getBType()); BIRVariableDcl tempVarDcl = new BIRVariableDcl(type, this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind.TEMP); this.env.enclFunc.localVars.add(tempVarDcl); From 6f37020e43846e23dbe6263bd668a061ef75cdb8 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Mon, 2 Oct 2023 11:59:44 +0530 Subject: [PATCH 53/58] Get annotation from typedesc --- .../java/io/ballerina/runtime/internal/TypeChecker.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java index 70ef768c9c92..9a7ec4dfae5e 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java @@ -544,6 +544,11 @@ public static Object getAnnotValue(TypedescValue typedescValue, BString annotTag if (!(describingType instanceof BAnnotatableType)) { return null; } + if (typedescValue instanceof TypedescValueImpl && ((TypedescValueImpl) typedescValue).annotations != null) { + if (((TypedescValueImpl) typedescValue).annotations.containsKey(annotTag)) { + return ((TypedescValueImpl) typedescValue).annotations.get(annotTag); + } + } return ((BAnnotatableType) describingType).getAnnotation(annotTag); } @@ -2151,7 +2156,7 @@ private static boolean checkIsNeverTypeOrStructureTypeWithARequiredNeverMember(T private static boolean checkIsLikeType(List errors, Object sourceValue, Type targetType, List unresolvedValues, boolean allowNumericConversion, String varName) { - Type sourceType = getReferredType(getType(sourceValue)); + Type sourceType = getImpliedType(getType(sourceValue)); if (checkIsType(sourceType, targetType, new ArrayList<>())) { return true; } From 5072e8c212a45090c8d749804b011a54c5f5c3bf Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Mon, 2 Oct 2023 12:24:49 +0530 Subject: [PATCH 54/58] Rearrange top level nodes for improve order --- .../semantics/analyzer/DataflowAnalyzer.java | 54 ++++++------------- .../cyclefind/GlobalVariableRefAnalyzer.java | 21 ++++++++ 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/DataflowAnalyzer.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/DataflowAnalyzer.java index 9e3424a17aad..6e53d71a0196 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/DataflowAnalyzer.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/DataflowAnalyzer.java @@ -527,9 +527,6 @@ public void visit(BLangTypeDefinition typeDefinition) { } this.currDependentSymbolDeque.push(symbol); analyzeNode(typeDefinition.typeNode, env); - for (BLangAnnotationAttachment annAttachment : typeDefinition.annAttachments) { - analyzeNode(annAttachment, env); - } this.currDependentSymbolDeque.pop(); } @@ -664,14 +661,14 @@ public void visit(BLangSimpleVariable variable) { } return; } - - this.currDependentSymbolDeque.push(symbol); + if (!variable.flagSet.contains(Flag.FIELD)) { + this.currDependentSymbolDeque.push(symbol); + } BLangType typeNode = variable.typeNode; - if (typeNode != null) { - analyzeNode(typeNode, env); - } else { - BType type = variable.symbol.getType(); - recordGlobalVariableReferenceRelationship(Types.getImpliedType(type).tsymbol); + analyzeNode(typeNode, env); + if (variable.typeNode != null && variable.typeNode.getBType() != null) { + BType type = variable.typeNode.getBType(); + recordGlobalVariableReferenceRelationship(Types.getReferredType(type).tsymbol); } boolean withInModuleVarLetExpr = symbol.owner.tag == SymTag.LET && isGlobalVarSymbol(env.enclVarSym); if (withInModuleVarLetExpr) { @@ -711,7 +708,9 @@ public void visit(BLangSimpleVariable variable) { if (withInModuleVarLetExpr) { // double pop this.currDependentSymbolDeque.pop(); } - this.currDependentSymbolDeque.pop(); + if (!variable.flagSet.contains(Flag.FIELD)) { + this.currDependentSymbolDeque.pop(); + } } } @@ -1582,8 +1581,6 @@ public void visit(BLangRecordLiteral recordLiteral) { analyzeNode(((BLangRecordLiteral.BLangRecordSpreadOperatorField) field).expr, env); } } - BType type = recordLiteral.getBType(); - recordGlobalVariableReferenceRelationship(Types.getReferredType(type).tsymbol); } @Override @@ -1686,7 +1683,6 @@ public void visit(BLangCollectContextInvocation collectContextInvocation) { @Override public void visit(BLangErrorConstructorExpr errorConstructorExpr) { - analyzeNode(errorConstructorExpr.errorTypeRef, env); for (BLangExpression positionalArg : errorConstructorExpr.positionalArgs) { analyzeNode(positionalArg, env); } @@ -1919,9 +1915,10 @@ private boolean isGlobalVarSymbol(BSymbol symbol) { return false; } else if (symbol.owner == null) { return false; - } else { - return symbol.owner.tag == SymTag.PACKAGE; + } else if (symbol.owner.tag != SymTag.PACKAGE) { + return false; } + return isVariableOrConstant(symbol); } private boolean isVariableOrConstant(BSymbol symbol) { @@ -2122,7 +2119,6 @@ public void visit(BLangAnnotation annotationNode) { @Override public void visit(BLangAnnotationAttachment annAttachmentNode) { - analyzeNode(annAttachmentNode.expr, env); } @Override @@ -2171,17 +2167,6 @@ public void visit(BLangConstant constant) { boolean validVariable = constant.symbol != null; if (validVariable) { this.currDependentSymbolDeque.push(constant.symbol); - BLangType typeNode = constant.typeNode; - if (typeNode != null) { - analyzeNode(typeNode, env); - } else { - BType type = constant.symbol.getType(); - recordGlobalVariableReferenceRelationship(Types.getReferredType(type).tsymbol); - } - } - if (constant.associatedTypeDefinition != null) { - BLangType bLangType = constant.associatedTypeDefinition.typeNode; - analyzeNode(bLangType, env); } try { analyzeNode(constant.expr, env); @@ -2262,7 +2247,8 @@ public void visit(BLangObjectTypeNode objectTypeNode) { @Override public void visit(BLangRecordTypeNode recordTypeNode) { BTypeSymbol tsymbol = Types.getImpliedType(recordTypeNode.getBType()).tsymbol; - recordGlobalVariableReferenceRelationship(tsymbol); + BSymbol symbol = recordTypeNode.symbol; + recordGlobalVariableReferenceRelationship(symbol); for (TypeNode type : recordTypeNode.getTypeReferences()) { BLangType bLangType = (BLangType) type; analyzeNode(bLangType, env); @@ -2277,6 +2263,7 @@ public void visit(BLangRecordTypeNode recordTypeNode) { } recordGlobalVariableReferenceRelationship(field.symbol); } + analyzeNode(recordTypeNode.restFieldType, env); } private void addTypeDependency(BTypeSymbol dependentTypeSymbol, BType providerType, Set unresolvedTypes) { @@ -2392,7 +2379,6 @@ public void visit(BLangInferredTypedescDefaultNode inferTypedescExpr) { @Override public void visit(BLangErrorType errorType) { - analyzeNode(errorType.detailType, env); } @Override @@ -2445,13 +2431,7 @@ public void visit(BLangTupleVariableDef bLangTupleVariableDef) { @Override public void visit(BLangRecordVariable bLangRecordVariable) { - BLangType typeNode = bLangRecordVariable.typeNode; - if (typeNode != null) { - analyzeNode(typeNode, env); - } else { - BType type = bLangRecordVariable.symbol.getType(); - recordGlobalVariableReferenceRelationship(Types.getReferredType(type).tsymbol); - } + analyzeNode(bLangRecordVariable.typeNode, env); populateUnusedVariableMapForNonSimpleBindingPatternVariables(this.unusedLocalVariables, bLangRecordVariable); this.currDependentSymbolDeque.push(bLangRecordVariable.symbol); analyzeNode(bLangRecordVariable.expr, env); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/cyclefind/GlobalVariableRefAnalyzer.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/cyclefind/GlobalVariableRefAnalyzer.java index 6306a9e67d4b..3570d9ec08f8 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/cyclefind/GlobalVariableRefAnalyzer.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/cyclefind/GlobalVariableRefAnalyzer.java @@ -27,14 +27,21 @@ import org.wso2.ballerinalang.compiler.semantics.model.symbols.BSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BVarSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.SymTag; +import org.wso2.ballerinalang.compiler.tree.BLangAnnotation; import org.wso2.ballerinalang.compiler.tree.BLangClassDefinition; +import org.wso2.ballerinalang.compiler.tree.BLangErrorVariable; import org.wso2.ballerinalang.compiler.tree.BLangFunction; import org.wso2.ballerinalang.compiler.tree.BLangIdentifier; +import org.wso2.ballerinalang.compiler.tree.BLangImportPackage; import org.wso2.ballerinalang.compiler.tree.BLangPackage; +import org.wso2.ballerinalang.compiler.tree.BLangRecordVariable; +import org.wso2.ballerinalang.compiler.tree.BLangResourceFunction; import org.wso2.ballerinalang.compiler.tree.BLangService; import org.wso2.ballerinalang.compiler.tree.BLangSimpleVariable; +import org.wso2.ballerinalang.compiler.tree.BLangTupleVariable; import org.wso2.ballerinalang.compiler.tree.BLangTypeDefinition; import org.wso2.ballerinalang.compiler.tree.BLangVariable; +import org.wso2.ballerinalang.compiler.tree.BLangXMLNS; import org.wso2.ballerinalang.compiler.tree.expressions.BLangConstant; import org.wso2.ballerinalang.compiler.tree.types.BLangStructureTypeNode; import org.wso2.ballerinalang.compiler.tree.types.BLangType; @@ -344,6 +351,20 @@ private boolean isMatchingNode(TopLevelNode topLevelNode, BSymbol symbol) { return ((BLangService) topLevelNode).symbol == symbol; case CLASS_DEFN: return ((BLangClassDefinition) topLevelNode).symbol == symbol; + case TUPLE_VARIABLE: + return ((BLangTupleVariable) topLevelNode).symbol == symbol; + case RECORD_VARIABLE: + return ((BLangRecordVariable) topLevelNode).symbol == symbol; + case ANNOTATION: + return ((BLangAnnotation) topLevelNode).symbol == symbol; + case ERROR_VARIABLE: + return ((BLangErrorVariable) topLevelNode).symbol == symbol; + case RESOURCE_FUNC: + return ((BLangResourceFunction) topLevelNode).symbol == symbol; + case XMLNS: + return ((BLangXMLNS) topLevelNode).symbol == symbol; + case IMPORT: + return ((BLangImportPackage) topLevelNode).symbol == symbol; default: return false; } From 182e46c93ee9b91f2f800896c0f6c63bdb36cfd0 Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Mon, 2 Oct 2023 12:36:16 +0530 Subject: [PATCH 55/58] Implement Block Statement for store TypeNode Details --- .../compiler/desugar/ClosureDesugar.java | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java index 35258bb519c8..4cdf75cea157 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java @@ -748,8 +748,8 @@ public void visit(BLangSimpleVariableDef varDefNode) { // If its a variable declaration with a RHS value, and also a closure. varDefNode.var.typeNode = rewrite(varDefNode.var.typeNode, env); if (varDefNode.var.expr != null) { - BLangAssignment stmt = createAssignmentToClosureMap(varDefNode); - result = rewrite(stmt, env); + BLangBlockStmt stmt = createAssignmentToClosureMap(varDefNode); + result = stmt; } else { // Note: Although it's illegal to use a closure variable without initializing it in it's declared scope, // when we access (initialize) a variable from outer scope, since we desugar transaction block into a @@ -765,7 +765,9 @@ public void visit(BLangSimpleVariableDef varDefNode) { * @param varDefNode variable definition node * @return assignment statement created */ - private BLangAssignment createAssignmentToClosureMap(BLangSimpleVariableDef varDefNode) { + private BLangBlockStmt createAssignmentToClosureMap(BLangSimpleVariableDef varDefNode) { + BLangBlockStmt blockStmt = ASTBuilderUtil.createBlockStmt(varDefNode.pos); + blockStmt.addStatement(createSimpleVarDef(varDefNode)); BVarSymbol mapSymbol = createMapSymbolIfAbsent(env.node, blockClosureMapCount); // Add the variable to the created map. @@ -777,7 +779,20 @@ private BLangAssignment createAssignmentToClosureMap(BLangSimpleVariableDef varD accessExpr.setBType(((BMapType) mapSymbol.type).constraint); accessExpr.isLValue = true; // Written to: 'map["x"] = 8'. - return ASTBuilderUtil.createAssignmentStmt(varDefNode.pos, accessExpr, varDefNode.var.expr); + blockStmt.addStatement(rewrite(ASTBuilderUtil.createAssignmentStmt(varDefNode.pos, accessExpr, + varDefNode.var.expr), env)); + return blockStmt; + } + + private BLangSimpleVariableDef createSimpleVarDef(BLangSimpleVariableDef varDefNode) { + BLangSimpleVariable variable = varDefNode.var; + BLangSimpleVariable simpleVariable = ASTBuilderUtil.createVariable(variable.pos, variable.name.value, + variable.getBType(), null, variable.symbol); + BLangSimpleVariableDef simpleVariableDef = ASTBuilderUtil.createVariableDef(varDefNode.pos); + simpleVariableDef.var = simpleVariable; + simpleVariable.typeNode = variable.typeNode; + simpleVariableDef.setBType(simpleVariable.getBType()); + return simpleVariableDef; } private BVarSymbol createMapSymbolIfAbsent(BLangNode node, int closureMapCount) { From 64522f50c94cb35c3c950bcc7597d867b24620ba Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Mon, 2 Oct 2023 12:36:48 +0530 Subject: [PATCH 56/58] Add global variables to top level nodes --- .../ballerinalang/compiler/desugar/ClosureGenerator.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureGenerator.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureGenerator.java index 6e5ab6d084eb..69176eee89b6 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureGenerator.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureGenerator.java @@ -265,7 +265,9 @@ private void addClosuresToGlobalVariableList(SymbolEnv pkgEnv) { pkgEnv.enclPkg.topLevelNodes.add(0, variableDef); } for (BLangSimpleVariableDef closureReference : annotationClosureReferences) { - pkgEnv.enclPkg.globalVars.add(rewrite(closureReference.var, pkgEnv)); + BLangSimpleVariable simpleVariable = rewrite(closureReference.var, pkgEnv); + pkgEnv.enclPkg.globalVars.add(simpleVariable); + pkgEnv.enclPkg.topLevelNodes.add(simpleVariable); } } @@ -1612,7 +1614,9 @@ private List rewrite(List nodeList, SymbolEnv env) { E node = rewrite(nodeList.remove(0), env); Iterator iterator = annotationClosureReferences.iterator(); while (iterator.hasNext()) { - nodeList.add(rewrite((E) annotationClosureReferences.poll().var, env)); + E simpleVariable = rewrite((E) annotationClosureReferences.poll().var, env); + nodeList.add(simpleVariable); + env.enclPkg.topLevelNodes.add((BLangSimpleVariable)simpleVariable); } nodeList.add(node); } From 05f67bcb1fae30f22f2b318b8850fa6333cdefdd Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Mon, 2 Oct 2023 12:41:45 +0530 Subject: [PATCH 57/58] Generate a typedesc instruction when visiting type node --- .../ballerinalang/compiler/bir/BIRGen.java | 89 +++++++------------ .../bir/codegen/JvmInstructionGen.java | 10 +-- .../compiler/bir/codegen/JvmTypeGen.java | 4 +- .../bir/codegen/split/JvmCreateTypeGen.java | 22 ++--- .../compiler/util/ImmutableTypeCloner.java | 12 +++ 5 files changed, 60 insertions(+), 77 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index 272f05b0e606..e85ee3a81312 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -379,10 +379,6 @@ private void generateClassDefinitions(List topLevelNodes) { @Override public void visit(BLangTypeDefinition astTypeDefinition) { - BLangType bLangType = astTypeDefinition.typeNode; - if (bLangType != null) { - bLangType.accept(this); - } BType type = getDefinedType(astTypeDefinition); BType referredType = Types.getImpliedType(type); BSymbol symbol = astTypeDefinition.symbol; @@ -490,12 +486,6 @@ private BType getDefinedType(BLangTypeDefinition astTypeDefinition) { @Override public void visit(BLangClassDefinition classDefinition) { - for (BLangSimpleVariable bLangSimpleVariable : classDefinition.fields) { - BLangType typeNode = bLangSimpleVariable.typeNode; - if (typeNode != null) { - typeNode.accept(this); - } - } BIRTypeDefinition typeDef = new BIRTypeDefinition(classDefinition.pos, classDefinition.symbol.name, classDefinition.symbol.originalName, @@ -609,7 +599,6 @@ public void visit(BLangFunction astFunc) { List requiredParams = astFunc.requiredParams; BLangSimpleVariable restParam = astFunc.restParam; BLangType returnTypeNode = astFunc.returnTypeNode; - analyzeParametersAndReturnType(requiredParams, restParam, returnTypeNode); if (isTypeAttachedFunction) { funcName = names.fromString(astFunc.symbol.name.value); } else { @@ -728,6 +717,7 @@ public void visit(BLangFunction astFunc) { this.env.enclBB = entryBB; this.localTypedescMap = new HashMap<>(); addToTrapStack(entryBB); + analyzeParametersAndReturnType(requiredParams, restParam, returnTypeNode); astFunc.body.accept(this); birFunc.basicBlocks.add(this.env.returnBB); @@ -1176,7 +1166,6 @@ public void visit(BLangValueType valueType) { @Override public void visit(BLangUnionTypeNode unionTypeNode) { - unionTypeNode.memberTypeNodes.forEach(typeNode -> typeNode.accept(this)); } @Override @@ -1263,8 +1252,9 @@ public void visit(BLangFiniteTypeNode finiteTypeNode) { @Override public void visit(BLangIntersectionTypeNode intersectionTypeNode) { - for (BLangType typeNode : intersectionTypeNode.constituentTypeNodes) { - typeNode.accept(this); + BType effectiveType = Types.getImpliedType(intersectionTypeNode.getBType()); + if (effectiveType.tag == TypeTags.RECORD || effectiveType.tag == TypeTags.TUPLE) { + createNewTypedescInst(effectiveType, intersectionTypeNode.pos); } } @@ -1732,15 +1722,12 @@ public void visit(BLangLiteral astLiteralExpr) { public void visit(BLangMapLiteral astMapLiteralExpr) { this.env.isInArrayOrStructure++; BType type = astMapLiteralExpr.getBType(); - createNewTypedescInst(type, astMapLiteralExpr.pos); BIRVariableDcl tempVarDcl = new BIRVariableDcl(type, this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind.TEMP); this.env.enclFunc.localVars.add(tempVarDcl); BIROperand toVarRef = new BIROperand(tempVarDcl); - - setScopeAndEmit(new BIRNonTerminator.NewStructure(astMapLiteralExpr.pos, toVarRef, this.env.targetOperand, - generateMappingConstructorEntries(astMapLiteralExpr.fields), type)); + setScopeAndEmit(createNewStructureInst(generateMappingConstructorEntries(astMapLiteralExpr.fields), toVarRef, Types.getImpliedType(type), astMapLiteralExpr.pos)); this.env.targetOperand = toVarRef; this.env.isInArrayOrStructure--; } @@ -1781,8 +1768,6 @@ private BIRNonTerminator.NewStructure createNewStructureInst(List varDcls = mapToVarDcls(type); BTypeSymbol typeSymbol = type.tsymbol; BIRVariableDcl tempVarDcl; BIROperand toVarRef; BIRNonTerminator.NewTypeDesc newTypeDesc; - if (this.env.enclBB == null) { - if (type.tag == TypeTags.RECORD || typeSymbol.name != Names.EMPTY) { - return; - } - tempVarDcl = new BIRGlobalVariableDcl(symTable.typeDesc, this.env.nextTypedescId(names), VarScope.GLOBAL, - VarKind.GLOBAL, 0, typeSymbol.pkgID, SymbolOrigin.VIRTUAL); - this.env.enclPkg.globalVars.add((BIRGlobalVariableDcl) tempVarDcl); - toVarRef = new BIROperand(tempVarDcl); - globalTypedescMap.put(type, toVarRef); - newTypeDesc = new BIRNonTerminator.NewTypeDesc(position, toVarRef, type, varDcls); - this.env.enclPkg.typedescs.add(newTypeDesc); - } else { - tempVarDcl = new BIRVariableDcl(symTable.typeDesc, this.env.nextLocalVarId(names), VarScope.FUNCTION, - VarKind.TEMP); - this.env.enclFunc.localVars.add(tempVarDcl); - toVarRef = new BIROperand(tempVarDcl); - BIRVariableDcl annotationVarDcl = new BIRVariableDcl(symTable.mapType, this.env.nextLocalVarId(names), - VarScope.FUNCTION, VarKind.TEMP); - this.env.enclFunc.localVars.add(annotationVarDcl); - if (typeSymbol != null && typeSymbol.annotations != null && - globalVarMap.containsKey(typeSymbol.annotations)) { + tempVarDcl = + new BIRVariableDcl(symTable.typeDesc, this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind.TEMP); + this.env.enclFunc.localVars.add(tempVarDcl); + toVarRef = new BIROperand(tempVarDcl); + BIRVariableDcl annotationVarDcl = new BIRVariableDcl(symTable.mapType, this.env.nextLocalVarId(names), + VarScope.FUNCTION, VarKind.TEMP); + this.env.enclFunc.localVars.add(annotationVarDcl); + if (typeSymbol != null && typeSymbol.annotations != null) { + if (this.env.symbolVarMap.containsKey(typeSymbol.annotations)) { newTypeDesc = new BIRNonTerminator.NewTypeDesc(position, toVarRef, type, varDcls, - new BIROperand(globalVarMap.get(typeSymbol.annotations))); + new BIROperand(this.env.symbolVarMap.get(typeSymbol.annotations))); } else { - newTypeDesc = new BIRNonTerminator.NewTypeDesc(position, toVarRef, type, varDcls); + newTypeDesc = new BIRNonTerminator.NewTypeDesc(position, toVarRef, type, varDcls, + new BIROperand(this.globalVarMap.get(typeSymbol.annotations))); } - this.env.targetOperand = toVarRef; - setScopeAndEmit(newTypeDesc); - localTypedescMap.put(type, toVarRef); + } else { + newTypeDesc = new BIRNonTerminator.NewTypeDesc(position, toVarRef, type, varDcls); } + this.env.targetOperand = toVarRef; + setScopeAndEmit(newTypeDesc); + localTypedescMap.put(type, toVarRef); } @Override @@ -2905,6 +2884,7 @@ private void generateListConstructorExpr(BLangListConstructorExpr listConstructo } setScopeAndEmit(createNewArrayInst(initialValues, type, sizeOp, toVarRef, referredType, pos)); this.env.targetOperand = toVarRef; + this.env.isInArrayOrStructure--; } private BIRNonTerminator.NewArray createNewArrayInst(List initialValues, @@ -2914,23 +2894,14 @@ private BIRNonTerminator.NewArray createNewArrayInst(List typeDefs) { // create the type for (BIRTypeDefinition typeDef : typeDefs) { - BType bType = JvmCodeGenUtil.getReferredType(typeDef.type); + BType bType = JvmCodeGenUtil.getImpliedType(typeDef.type); if (bType.tag == TypeTags.RECORD || bType.tag == TypeTags.ERROR || bType.tag == TypeTags.OBJECT - || bType.tag == TypeTags.UNION || Types.getEffectiveType(bType).tag == TypeTags.TUPLE) { + || bType.tag == TypeTags.UNION || Types.getImpliedType(bType).tag == TypeTags.TUPLE) { String name = typeDef.internalName.value; generateTypeField(cw, name); generateTypedescField(cw, name); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java index 0e2004ff87d9..e367a313ec75 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/split/JvmCreateTypeGen.java @@ -96,6 +96,7 @@ import static org.objectweb.asm.Opcodes.RETURN; import static org.objectweb.asm.Opcodes.V1_8; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil.createDefaultCase; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil.getImpliedType; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil.getModuleLevelClassName; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil.toNameString; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.ADD_METHOD; @@ -143,7 +144,6 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmTypeGen.getTypeDesc; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmTypeGen.getTypeFieldName; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmValueGen.getTypeDescClassName; -import static org.wso2.ballerinalang.compiler.semantics.analyzer.Types.getEffectiveType; /** * BIR types to JVM byte code generation class. @@ -280,7 +280,7 @@ private void createTypedescInstances(ClassWriter cw, List typ "()V", null, null); mv.visitCode(); for (BIRTypeDefinition typeDefinition : typeDefs) { - BType bType = JvmCodeGenUtil.getReferredType(typeDefinition.type); + BType bType = getImpliedType(typeDefinition.type); if (bType.tag == TypeTags.RECORD) { continue; } @@ -296,7 +296,7 @@ private void createTypedescInstances(ClassWriter cw, List typ } private void createTypedescInstances(MethodVisitor mv, BIRNonTerminator.NewTypeDesc typeDesc) { - BType type = JvmCodeGenUtil.getReferredType(typeDesc.type); + BType type = getImpliedType(typeDesc.type); String className = TYPEDESC_VALUE_IMPL; if (type.tag == TypeTags.RECORD) { className = getTypeDescClassName(JvmCodeGenUtil.getPackageName(type.tsymbol.pkgID), toNameString(type)); @@ -311,7 +311,7 @@ private void createTypedescInstances(MethodVisitor mv, BIRNonTerminator.NewTypeD } public void generateGlobalVarStore(MethodVisitor mv, BIRNode.BIRVariableDcl varDcl) { - BType bType = JvmCodeGenUtil.getReferredType(varDcl.type); + BType bType = getImpliedType(varDcl.type); String varName = varDcl.name.value; PackageID moduleId = ((BIRNode.BIRGlobalVariableDcl) varDcl).pkgId; String pkgName = JvmCodeGenUtil.getPackageName(moduleId); @@ -327,8 +327,8 @@ private void createTypedescInstance(MethodVisitor mv, BType bType, BIRTypeDefini PackageID pkgID = bType.tsymbol.pkgID; String packageName = JvmCodeGenUtil.getPackageName(pkgID); className = getTypeDescClassName(packageName, toNameString(bType)); - } else if (getEffectiveType(bType).tag == TypeTags.TUPLE) { - bType = getEffectiveType(bType); + } else if (getImpliedType(bType).tag == TypeTags.TUPLE) { + bType = getImpliedType(bType); className = TYPEDESC_VALUE_IMPL; } else { return; @@ -338,7 +338,7 @@ private void createTypedescInstance(MethodVisitor mv, BType bType, BIRTypeDefini mv.visitInsn(DUP); BType referenceType = typeDefinition.referenceType; if (referenceType == null) { - jvmTypeGen.loadType(mv, JvmCodeGenUtil.getReferredType(bType)); + jvmTypeGen.loadType(mv, getImpliedType(bType)); } else { BType referredType = ((BTypeReferenceType) referenceType).referredType; if (referredType.tag == TypeTags.TYPEREFDESC || bType.tag == TypeTags.TUPLE) { @@ -365,9 +365,9 @@ private int createTypesInstanceSplits(ClassWriter cw, List ty // Create the type for (BIRTypeDefinition optionalTypeDef : typeDefs) { String name = optionalTypeDef.internalName.value; - BType bType = JvmCodeGenUtil.getReferredType(optionalTypeDef.type); + BType bType = getImpliedType(optionalTypeDef.type); if (bType.tag != TypeTags.RECORD && bType.tag != TypeTags.OBJECT && bType.tag != TypeTags.ERROR && - bType.tag != TypeTags.UNION && getEffectiveType(bType).tag != TypeTags.TUPLE) { + bType.tag != TypeTags.UNION && getImpliedType(bType).tag != TypeTags.TUPLE) { // do not generate anything for other types (e.g.: finite type, etc.) continue; } else { @@ -378,7 +378,7 @@ private int createTypesInstanceSplits(ClassWriter cw, List ty mv.visitCode(); } } - switch (getEffectiveType(bType).tag) { + switch (getImpliedType(bType).tag) { case TypeTags.RECORD: jvmRecordTypeGen.createRecordType(mv, (BRecordType) bType, name); break; @@ -389,7 +389,7 @@ private int createTypesInstanceSplits(ClassWriter cw, List ty jvmErrorTypeGen.createErrorType(mv, (BErrorType) bType, bType.tsymbol.name.value); break; case TypeTags.TUPLE: - jvmTupleTypeGen.createTupleType(mv, (BTupleType) getEffectiveType(bType)); + jvmTupleTypeGen.createTupleType(mv, (BTupleType) getImpliedType(bType)); break; default: jvmUnionTypeGen.createUnionType(mv, (BUnionType) bType); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/util/ImmutableTypeCloner.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/util/ImmutableTypeCloner.java index 367bc372193c..571808ade3a0 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/util/ImmutableTypeCloner.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/util/ImmutableTypeCloner.java @@ -621,6 +621,18 @@ private static BIntersectionType defineImmutableRecordType(Location pos, BRecord setRestType(types, symTable, anonymousModelHelper, names, immutableRecordType, origRecordType, pos, env, unresolvedTypes); + for (BLangTypeDefinition typeDefinition : env.enclPkg.typeDefinitions) { + BType type = typeDefinition.getBType(); + if (type != null && type.tag != TypeTags.RECORD) { + continue; + } + if (type == originalType) { + BLangRecordTypeNode originRecordType = (BLangRecordTypeNode) typeDefinition.typeNode; + recordTypeNode.isAnonymous = originRecordType.isAnonymous; + recordTypeNode.isLocal = originRecordType.isLocal; + } + } + TypeDefBuilderHelper.createInitFunctionForRecordType(recordTypeNode, env, names, symTable); TypeDefBuilderHelper.addTypeDefinition(immutableRecordType, recordSymbol, recordTypeNode, env); return immutableRecordIntersectionType; From c99c7d488c065376c9d17fb99ee979620bb0a7da Mon Sep 17 00:00:00 2001 From: chiranSachintha Date: Mon, 2 Oct 2023 13:45:20 +0530 Subject: [PATCH 58/58] Desugar local record type nodes --- .../ballerinalang/compiler/bir/BIRGen.java | 3 +- .../compiler/desugar/ClosureGenerator.java | 2 +- .../compiler/desugar/Desugar.java | 67 +++++++++++++++---- 3 files changed, 57 insertions(+), 15 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index e85ee3a81312..dcdf43376d8b 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -1727,7 +1727,8 @@ public void visit(BLangMapLiteral astMapLiteralExpr) { VarScope.FUNCTION, VarKind.TEMP); this.env.enclFunc.localVars.add(tempVarDcl); BIROperand toVarRef = new BIROperand(tempVarDcl); - setScopeAndEmit(createNewStructureInst(generateMappingConstructorEntries(astMapLiteralExpr.fields), toVarRef, Types.getImpliedType(type), astMapLiteralExpr.pos)); + setScopeAndEmit(createNewStructureInst(generateMappingConstructorEntries(astMapLiteralExpr.fields), toVarRef, + Types.getImpliedType(type), astMapLiteralExpr.pos)); this.env.targetOperand = toVarRef; this.env.isInArrayOrStructure--; } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureGenerator.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureGenerator.java index 69176eee89b6..5d9c0fde5484 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureGenerator.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureGenerator.java @@ -1616,7 +1616,7 @@ private List rewrite(List nodeList, SymbolEnv env) { while (iterator.hasNext()) { E simpleVariable = rewrite((E) annotationClosureReferences.poll().var, env); nodeList.add(simpleVariable); - env.enclPkg.topLevelNodes.add((BLangSimpleVariable)simpleVariable); + env.enclPkg.topLevelNodes.add((BLangSimpleVariable) simpleVariable); } nodeList.add(node); } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java index d5080aae602e..77e26602ada0 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java @@ -33,7 +33,6 @@ import org.ballerinalang.model.tree.NodeKind; import org.ballerinalang.model.tree.OperatorKind; import org.ballerinalang.model.tree.TopLevelNode; -import org.ballerinalang.model.tree.TypeDefinition; import org.ballerinalang.model.tree.expressions.NamedArgNode; import org.ballerinalang.model.tree.expressions.RecordLiteralNode; import org.ballerinalang.model.tree.expressions.XMLNavigationAccess; @@ -1005,6 +1004,19 @@ private BLangSimpleVariableDef createSimpleVarDef(BLangPackage pkgNode, String n return simpleVariableDef; } + private BLangSimpleVariableDef createSimpleVarDefForTupleType(BLangPackage pkgNode, String name, + BLangTupleTypeNode tupleTypeNode) { + BType type = tupleTypeNode.getBType(); + BVarSymbol varSymbol = new BVarSymbol(0, Names.fromString(name), pkgNode.packageID, type, + pkgNode.symbol, pkgNode.pos, VIRTUAL); + BLangSimpleVariable simpleVariable = ASTBuilderUtil.createVariable(pkgNode.pos, name, type, null, varSymbol); + BLangSimpleVariableDef simpleVariableDef = ASTBuilderUtil.createVariableDef(pkgNode.pos); + simpleVariableDef.var = simpleVariable; + simpleVariable.typeNode = tupleTypeNode; + simpleVariableDef.setBType(simpleVariable.getBType()); + return simpleVariableDef; + } + private void desugarTopLevelNodes(BLangPackage pkgNode, BLangBlockFunctionBody initFnBody) { List desugaredGlobalVarList = new ArrayList<>(); SymbolEnv initFunctionEnv = @@ -1014,7 +1026,7 @@ private void desugarTopLevelNodes(BLangPackage pkgNode, BLangBlockFunctionBody i for (int j = 0; j < size; j++) { TopLevelNode topLevelNode = pkgNode.topLevelNodes.remove(0); if (topLevelNode.getKind() == NodeKind.TYPE_DEFINITION) { - desugarTypeDefinitions((TypeDefinition) topLevelNode, pkgNode, initFnBody); + desugarTypeDefinitions((BLangTypeDefinition) topLevelNode, pkgNode, initFnBody); } else if (topLevelNode.getKind() == NodeKind.CONSTANT) { desugarConstantVariables((BLangConstant) topLevelNode, initFunctionEnv, initFnBody); } @@ -1032,15 +1044,25 @@ private void desugarTopLevelNodes(BLangPackage pkgNode, BLangBlockFunctionBody i this.env.enclPkg.globalVars = desugaredGlobalVarList; } - private void desugarTypeDefinitions(TypeDefinition typeDefinition , BLangPackage pkgNode, + private void desugarTypeDefinitions(BLangTypeDefinition typeDefinition , BLangPackage pkgNode, BLangBlockFunctionBody initFnBody) { - TypeNode typeNode = typeDefinition.getTypeNode(); + BLangType typeNode = typeDefinition.getTypeNode(); + if (typeDefinition.symbol.origin == VIRTUAL) { + return; + } if (typeNode != null && typeNode.getKind() == NodeKind.RECORD_TYPE) { BLangRecordTypeNode recordTypeNode = (BLangRecordTypeNode) typeNode; BLangSimpleVariableDef bLangSimpleVariableDef = createSimpleVarDef(pkgNode, recordTypeNode.getBType().tsymbol.name.getValue(), recordTypeNode); initFnBody.stmts.add(bLangSimpleVariableDef); } + + if (typeNode != null && typeNode.getKind() == NodeKind.TUPLE_TYPE_NODE) { + BLangTupleTypeNode tupleTypeNode = (BLangTupleTypeNode) typeNode; + BLangSimpleVariableDef bLangSimpleVariableDef = createSimpleVarDefForTupleType(pkgNode, + tupleTypeNode.getBType().tsymbol.name.getValue(), tupleTypeNode); + initFnBody.stmts.add(bLangSimpleVariableDef); + } } private void desugarConstantVariables(BLangConstant constant, SymbolEnv initFunctionEnv, @@ -1050,14 +1072,13 @@ private void desugarConstantVariables(BLangConstant constant, SymbolEnv initFunc return; } for (BType memberType : ((BIntersectionType) constType).getConstituentTypes()) { - if (memberType.tag != TypeTags.RECORD) { - continue; + if (memberType.tag == TypeTags.RECORD || memberType.tag == TypeTags.TUPLE) { + BLangSimpleVarRef constVarRef = ASTBuilderUtil.createVariableRef(constant.pos, constant.symbol); + constant.expr = rewrite(constant.expr, initFunctionEnv); + BLangAssignment constInit = ASTBuilderUtil.createAssignmentStmt(constant.pos, constVarRef, + constant.expr); + initFnBody.stmts.add(constInit); } - BLangSimpleVarRef constVarRef = ASTBuilderUtil.createVariableRef(constant.pos, constant.symbol); - constant.expr = rewrite(constant.expr, initFunctionEnv); - BLangAssignment constInit = ASTBuilderUtil.createAssignmentStmt(constant.pos, constVarRef, - constant.expr); - initFnBody.stmts.add(constInit); } } @@ -1313,8 +1334,19 @@ public void visit(BLangRecordTypeNode recordTypeNode) { // referenced types are invoked on the current record type. if (recordTypeNode.isAnonymous && recordTypeNode.isLocal) { - TypeDefBuilderHelper.createTypeDefinitionForTSymbol(recordTypeNode.getBType(), - recordTypeNode.getBType().tsymbol, recordTypeNode, env); + // TODO: + BLangTypeDefinition typeDefinition = + TypeDefBuilderHelper.createTypeDefinitionForTSymbol(recordTypeNode.getBType(), + recordTypeNode.getBType().tsymbol, recordTypeNode, env); + BLangTypedescExpr typedescExpr = + ASTBuilderUtil.createTypedescExpr(recordTypeNode.pos, recordTypeNode.getBType(), + recordTypeNode.getBType()); + typedescExpr.typeNode = typeDefinition.getTypeNode(); + BType typedescType = new BTypedescType(recordTypeNode.getBType(), symTable.typeDesc.tsymbol); + BVarSymbol varSymbol = new BVarSymbol(0, recordTypeNode.symbol.name, this.env.scope.owner.pkgID, + typedescType, this.env.scope.owner, recordTypeNode.pos, VIRTUAL); + BLangSimpleVariableDef simpleVariableDef = createSimpleVariableDef(recordTypeNode.pos, + recordTypeNode.symbol.name.value, typedescType, typedescExpr, varSymbol); recordTypeNode.desugared = true; result = recordTypeNode; return; @@ -1323,6 +1355,15 @@ public void visit(BLangRecordTypeNode recordTypeNode) { result = recordTypeNode; } + private BLangSimpleVariableDef createSimpleVariableDef(Location pos, String name, BType type, BLangExpression expr, + BVarSymbol varSymbol) { + BLangSimpleVariable simpleVariable = ASTBuilderUtil.createVariable(pos, name, type, expr, varSymbol); + BLangSimpleVariableDef variableDef = ASTBuilderUtil.createVariableDef(pos); + variableDef.var = simpleVariable; + variableDef.setBType(type); + return variableDef; + } + @Override public void visit(BLangArrayType arrayType) { arrayType.elemtype = rewrite(arrayType.elemtype, env);