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 35405da873ed..c4ae8a663456 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 @@ -214,10 +214,8 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.function.Supplier; import java.util.regex.Pattern; import java.util.stream.Collectors; - import javax.xml.XMLConstants; import static org.ballerinalang.model.tree.NodeKind.CLASS_DEFN; @@ -2235,7 +2233,7 @@ public void visit(BLangXMLAccessExpr xmlAccessExpr) { @Override public void visit(BLangTypedescExpr accessExpr) { - createNewTypedescInst(accessExpr.resolvedType, accessExpr.pos); + this.env.targetOperand = new BIROperand(getTypedescVariable(accessExpr.resolvedType, accessExpr.pos)); } @Override @@ -2410,23 +2408,24 @@ private BIRNonTerminator.NewStructure createNewStructureInst(BIROperand typeDesc } private BIRVariableDcl getTypedescVariable(BType type, Location pos) { - Supplier[] checks = new Supplier[] { - () -> findInPackageScope(type), - () -> findInLocalSymbolVarMap(type, env.symbolVarMap, false), - () -> findInLocalSymbolVarMap(type, env.symbolVarMap, true), - () -> findInGlobalSymbolVarMap(type, this.globalVarMap, false), - () -> findInGlobalSymbolVarMap(type, this.globalVarMap, true) - }; + BIRVariableDcl variableDcl = findInPackageScope(type); + if (variableDcl != null && variableDcl.initialized) return variableDcl; - // Iterate through the suppliers and return the first non-null result - for (Supplier check : checks) { - BIRVariableDcl variableDcl = check.get(); - if (variableDcl != null) { - return variableDcl; - } - } + variableDcl = findInLocalSymbolVarMap(type, env.symbolVarMap, false); + if (variableDcl != null && variableDcl.initialized) return variableDcl; + + variableDcl = findInLocalSymbolVarMap(type, env.symbolVarMap, true); + if (variableDcl != null && variableDcl.initialized) return variableDcl; + + variableDcl = findInGlobalSymbolVarMap(type, this.globalVarMap, false); + if (variableDcl != null && variableDcl.initialized) return variableDcl; + + variableDcl = findInGlobalSymbolVarMap(type, this.globalVarMap, true); + if (variableDcl != null && variableDcl.initialized) return variableDcl; - // TODO: we need to remove typedesc creating completely from here and handle it in the Desugar phase + // Create new type desc instruction if the typedesc variable is not found + // TODO: we need to handle duplicate typedesc creation for some cases. + // eg: function params ie `foo(record {int a;})` createNewTypedescInst(type, pos); return this.env.targetOperand.variableDcl; } 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 c6a880d0031b..109858a0dd13 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 @@ -146,6 +146,7 @@ public static class BIRVariableDcl extends BIRDocumentableNode { public BIRBasicBlock startBB; public int insOffset; public boolean onlyUsedInSingleBB; + public boolean initialized = false; // Stores the scope of the current instruction with respect to local variables. public BirScope insScope; 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 efac43fbef9c..9cc5628bbf6b 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 @@ -57,6 +57,7 @@ public Move(Location pos, BIROperand fromOperand, BIROperand toOperand) { super(pos, InstructionKind.MOVE); this.rhsOp = fromOperand; this.lhsOp = toOperand; + toOperand.variableDcl.initialized = true; } @Override