Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fix object type referencing #15975

Merged
merged 1 commit into from
Jun 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,6 @@ private BPackageSymbol definePackage(DataInputStream dataInStream, int pkgCpInde

defineAttachedFunctions(dataInStream);

// Define constants.
// defineSymbols(dataInStream, rethrow(this::defineConstants));

// Define functions.
defineSymbols(dataInStream, rethrow(this::defineFunction));

Expand Down Expand Up @@ -330,6 +327,8 @@ private void defineFunction(DataInputStream dataInStream) throws IOException {
BInvokableType funcType = (BInvokableType) readBType(dataInStream);
BInvokableSymbol invokableSymbol = Symbols.createFunctionSymbol(flags, names.fromString(funcName),
this.env.pkgSymbol.pkgID, funcType, this.env.pkgSymbol, Symbols.isFlagOn(flags, Flags.NATIVE));
invokableSymbol.retType = funcType.retType;

Scope scopeToDefine = this.env.pkgSymbol.scope;

if (this.currentStructure != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import org.wso2.ballerinalang.compiler.bir.writer.BIRBinaryWriter;
import org.wso2.ballerinalang.compiler.semantics.model.SymbolTable;
import org.wso2.ballerinalang.compiler.semantics.model.symbols.BAnnotationSymbol;
import org.wso2.ballerinalang.compiler.semantics.model.symbols.BAttachedFunction;
import org.wso2.ballerinalang.compiler.semantics.model.symbols.BConstantSymbol;
import org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol;
import org.wso2.ballerinalang.compiler.semantics.model.symbols.BObjectTypeSymbol;
Expand Down Expand Up @@ -157,6 +158,7 @@
import org.wso2.ballerinalang.compiler.util.TypeTags;
import org.wso2.ballerinalang.compiler.util.diagnotic.DiagnosticPos;
import org.wso2.ballerinalang.programfile.CompiledBinaryFile.BIRPackageFile;
import org.wso2.ballerinalang.util.Flags;

import java.util.ArrayList;
import java.util.Comparator;
Expand Down Expand Up @@ -267,6 +269,36 @@ public void visit(BLangTypeDefinition astTypeDefinition) {
typeDefs.put(astTypeDefinition.symbol, typeDef);
this.env.enclPkg.typeDefs.add(typeDef);
typeDef.index = this.env.enclPkg.typeDefs.size() - 1;

// Write referenced functions, if this is an abstract-object
if (astTypeDefinition.symbol.tag != SymTag.OBJECT ||
!Symbols.isFlagOn(astTypeDefinition.symbol.flags, Flags.ABSTRACT)) {
return;
}

for (BAttachedFunction func : ((BObjectTypeSymbol) astTypeDefinition.symbol).referencedFunctions) {
if (!Symbols.isFlagOn(func.symbol.flags, Flags.INTERFACE)) {
return;
}

BInvokableSymbol funcSymbol = func.symbol;
BIRFunction birFunc = new BIRFunction(astTypeDefinition.pos, func.funcName, funcSymbol.flags, func.type,
funcSymbol.receiverSymbol.type, names.fromString(DEFAULT_WORKER_NAME), 0, new TaintTable());

birFunc.argsCount = funcSymbol.params.size() + funcSymbol.defaultableParams.size() +
(funcSymbol.restParam != null ? 1 : 0);
funcSymbol.params.forEach(requiredParam -> addParam(birFunc, requiredParam, true, astTypeDefinition.pos));
funcSymbol.defaultableParams
.forEach(defaultableParam -> addParam(birFunc, defaultableParam, false, astTypeDefinition.pos));
if (funcSymbol.restParam != null) {
addRestParam(birFunc, funcSymbol.restParam, astTypeDefinition.pos);
}

birFunc.returnVariable = new BIRVariableDcl(astTypeDefinition.pos, funcSymbol.retType,
this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind.RETURN);

typeDef.attachedFuncs.add(birFunc);
}
}

@Override
Expand Down Expand Up @@ -361,7 +393,7 @@ public void visit(BLangFunction astFunc) {
astFunc.requiredParams.forEach(requiredParam -> addParam(birFunc, requiredParam, true));
astFunc.defaultableParams.forEach(defaultableParam -> addParam(birFunc, defaultableParam.var, false));
if (astFunc.restParam != null) {
addRestParam(birFunc, astFunc.restParam);
addRestParam(birFunc, astFunc.restParam.symbol, astFunc.restParam.pos);
}

if (astFunc.interfaceFunction || Symbols.isNative(astFunc.symbol)) {
Expand Down Expand Up @@ -540,25 +572,34 @@ private Name getFuncName(BInvokableSymbol symbol) {
}

private void addParam(BIRFunction birFunc, BLangVariable functionParam, boolean required) {
BIRFunctionParameter birVarDcl = new BIRFunctionParameter(functionParam.pos, functionParam.symbol.type,
this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind.ARG, functionParam.expr != null);
addParam(birFunc, functionParam.symbol, functionParam.expr, required, functionParam.pos);
}

private void addParam(BIRFunction birFunc, BVarSymbol paramSymbol, boolean required, DiagnosticPos pos) {
addParam(birFunc, paramSymbol, null, required, pos);
}

private void addParam(BIRFunction birFunc, BVarSymbol paramSymbol, BLangExpression defaultValExpr, boolean required,
DiagnosticPos pos) {
BIRFunctionParameter birVarDcl = new BIRFunctionParameter(pos, paramSymbol.type,
this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind.ARG, defaultValExpr != null);

List<BIRBasicBlock> bbsOfDefaultValueExpr = new ArrayList<>();
if (functionParam.expr != null) {
if (defaultValExpr != null) {
// Parameter has a default value expression.
BIRBasicBlock defaultExprBB = new BIRBasicBlock(this.env.nextBBId(names));
bbsOfDefaultValueExpr.add(defaultExprBB);
this.env.enclBB = defaultExprBB;
this.env.enclBasicBlocks = bbsOfDefaultValueExpr;
functionParam.expr.accept(this);
defaultValExpr.accept(this);

// Create a variable reference for the function param and emit move instruction.
BIROperand varRef = new BIROperand(birVarDcl);
emit(new Move(birFunc.pos, this.env.targetOperand, varRef));

this.env.enclBB.terminator = new BIRTerminator.Return(birFunc.pos);
}
BIRParameter parameter = new BIRParameter(functionParam.pos, functionParam.symbol.name);
BIRParameter parameter = new BIRParameter(pos, paramSymbol.name);
if (required) {
birFunc.requiredParams.add(parameter);
} else {
Expand All @@ -569,19 +610,19 @@ private void addParam(BIRFunction birFunc, BLangVariable functionParam, boolean

// We maintain a mapping from variable symbol to the bir_variable declaration.
// This is required to pull the correct bir_variable declaration for variable references.
this.env.symbolVarMap.put(functionParam.symbol, birVarDcl);
this.env.symbolVarMap.put(paramSymbol, birVarDcl);
}

private void addRestParam(BIRFunction birFunc, BLangVariable requiredParam) {
BIRFunctionParameter birVarDcl = new BIRFunctionParameter(requiredParam.pos, requiredParam.symbol.type,
private void addRestParam(BIRFunction birFunc, BVarSymbol paramSymbol, DiagnosticPos pos) {
BIRFunctionParameter birVarDcl = new BIRFunctionParameter(pos, paramSymbol.type,
this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind.ARG, false);
birFunc.parameters.put(birVarDcl, new ArrayList<>());

birFunc.restParam = new BIRParameter(requiredParam.pos, requiredParam.symbol.name);
birFunc.restParam = new BIRParameter(pos, paramSymbol.name);

// We maintain a mapping from variable symbol to the bir_variable declaration.
// This is required to pull the correct bir_variable declaration for variable references.
this.env.symbolVarMap.put(requiredParam.symbol, birVarDcl);
this.env.symbolVarMap.put(paramSymbol, birVarDcl);
}

private void addRequiredParam(BIRFunction birFunc, BVarSymbol paramSymbol, DiagnosticPos pos) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,6 @@ public static class BIRTypeDefinition extends BIRNode {
*/
public Name name;


public List<BIRFunction> attachedFuncs;

public int flags;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
/**
* Test cases for user defined object types in ballerina.
*/
@Test(groups = { "brokenOnJBallerina" })
public class ObjectInBaloTest {

private CompileResult result;
Expand Down