use of org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol.BAttachedFunction in project ballerina by ballerina-lang.
the class SymbolEnter method validateFunctionsAttachedToStructs.
private void validateFunctionsAttachedToStructs(BLangFunction funcNode, BInvokableSymbol funcSymbol, SymbolEnv invokableEnv) {
BInvokableType funcType = (BInvokableType) funcSymbol.type;
BStructSymbol structSymbol = (BStructSymbol) funcNode.receiver.type.tsymbol;
BSymbol symbol = symResolver.lookupMemberSymbol(funcNode.receiver.pos, structSymbol.scope, invokableEnv, names.fromIdNode(funcNode.name), SymTag.VARIABLE);
if (symbol != symTable.notFoundSymbol) {
dlog.error(funcNode.pos, DiagnosticCode.STRUCT_FIELD_AND_FUNC_WITH_SAME_NAME, funcNode.name.value, funcNode.receiver.type.toString());
return;
}
BStructType structType = (BStructType) funcNode.receiver.type;
BAttachedFunction attachedFunc = new BAttachedFunction(names.fromIdNode(funcNode.name), funcSymbol, funcType);
structSymbol.attachedFuncs.add(attachedFunc);
if (funcNode.name.value.equals(structType.tsymbol.name.value + Names.INIT_FUNCTION_SUFFIX.value)) {
structSymbol.defaultsValuesInitFunc = attachedFunc;
return;
}
// Check whether this attached function is a struct initializer.
if (!structType.tsymbol.name.value.equals(funcNode.name.value)) {
// Not a struct initializer.
return;
}
if (!funcNode.requiredParams.isEmpty() || !funcNode.retParams.isEmpty()) {
dlog.error(funcNode.pos, DiagnosticCode.INVALID_STRUCT_INITIALIZER_FUNCTION, funcNode.name.value, funcNode.receiver.type.toString());
}
structSymbol.initializerFunc = attachedFunc;
}
use of org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol.BAttachedFunction in project ballerina by ballerina-lang.
the class SymbolEnter method validateFunctionsAttachedToObject.
private void validateFunctionsAttachedToObject(BLangFunction funcNode, BInvokableSymbol funcSymbol, SymbolEnv invokableEnv) {
BInvokableType funcType = (BInvokableType) funcSymbol.type;
BStructSymbol objectSymbol = (BStructSymbol) funcNode.receiver.type.tsymbol;
BSymbol symbol = symResolver.lookupMemberSymbol(funcNode.receiver.pos, objectSymbol.scope, invokableEnv, names.fromIdNode(funcNode.name), SymTag.VARIABLE);
if (symbol != symTable.notFoundSymbol) {
dlog.error(funcNode.pos, DiagnosticCode.STRUCT_FIELD_AND_FUNC_WITH_SAME_NAME, funcNode.name.value, funcNode.receiver.type.toString());
return;
}
BAttachedFunction attachedFunc = new BAttachedFunction(names.fromIdNode(funcNode.name), funcSymbol, funcType);
objectSymbol.attachedFuncs.add(attachedFunc);
// Check whether this attached function is a object initializer.
if (!Names.OBJECT_INIT_SUFFIX.value.equals(funcNode.name.value)) {
// Not a object initializer.
return;
}
if (!funcNode.retParams.isEmpty()) {
// TODO change message
dlog.error(funcNode.pos, DiagnosticCode.INVALID_STRUCT_INITIALIZER_FUNCTION, funcNode.name.value, funcNode.receiver.type.toString());
}
objectSymbol.initializerFunc = attachedFunc;
}
use of org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol.BAttachedFunction in project ballerina by ballerina-lang.
the class Types method checkEquivalencyOfTwoPrivateStructs.
private boolean checkEquivalencyOfTwoPrivateStructs(BStructType lhsType, BStructType rhsType) {
for (int fieldCounter = 0; fieldCounter < lhsType.fields.size(); fieldCounter++) {
BStructField lhsField = lhsType.fields.get(fieldCounter);
BStructField rhsField = rhsType.fields.get(fieldCounter);
if (lhsField.name.equals(rhsField.name) && isSameType(rhsField.type, lhsField.type)) {
continue;
}
return false;
}
BStructSymbol lhsStructSymbol = (BStructSymbol) lhsType.tsymbol;
List<BAttachedFunction> lhsFuncs = lhsStructSymbol.attachedFuncs;
List<BAttachedFunction> rhsFuncs = ((BStructSymbol) rhsType.tsymbol).attachedFuncs;
int lhsAttachedFuncCount = lhsStructSymbol.initializerFunc != null ? lhsFuncs.size() - 1 : lhsFuncs.size();
if (lhsAttachedFuncCount > rhsFuncs.size()) {
return false;
}
for (BAttachedFunction lhsFunc : lhsFuncs) {
if (lhsFunc == lhsStructSymbol.initializerFunc || lhsFunc == lhsStructSymbol.defaultsValuesInitFunc) {
continue;
}
BAttachedFunction rhsFunc = getMatchingInvokableType(rhsFuncs, lhsFunc);
if (rhsFunc == null) {
return false;
}
}
return true;
}
use of org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol.BAttachedFunction in project ballerina by ballerina-lang.
the class Types method checkEquivalencyOfPublicStructs.
private boolean checkEquivalencyOfPublicStructs(BStructType lhsType, BStructType rhsType) {
int fieldCounter = 0;
for (; fieldCounter < lhsType.fields.size(); fieldCounter++) {
BStructField lhsField = lhsType.fields.get(fieldCounter);
BStructField rhsField = rhsType.fields.get(fieldCounter);
if (Symbols.isPrivate(lhsField.symbol) || Symbols.isPrivate(rhsField.symbol)) {
return false;
}
if (lhsField.name.equals(rhsField.name) && isSameType(rhsField.type, lhsField.type)) {
continue;
}
return false;
}
// Check the rest of the fields in RHS type
for (; fieldCounter < rhsType.fields.size(); fieldCounter++) {
if (Symbols.isPrivate(rhsType.fields.get(fieldCounter).symbol)) {
return false;
}
}
BStructSymbol lhsStructSymbol = (BStructSymbol) lhsType.tsymbol;
List<BAttachedFunction> lhsFuncs = lhsStructSymbol.attachedFuncs;
List<BAttachedFunction> rhsFuncs = ((BStructSymbol) rhsType.tsymbol).attachedFuncs;
int lhsAttachedFuncCount = lhsStructSymbol.initializerFunc != null ? lhsFuncs.size() - 1 : lhsFuncs.size();
if (lhsAttachedFuncCount > rhsFuncs.size()) {
return false;
}
for (BAttachedFunction lhsFunc : lhsFuncs) {
if (lhsFunc == lhsStructSymbol.initializerFunc || lhsFunc == lhsStructSymbol.defaultsValuesInitFunc) {
continue;
}
if (Symbols.isPrivate(lhsFunc.symbol)) {
return false;
}
BAttachedFunction rhsFunc = getMatchingInvokableType(rhsFuncs, lhsFunc);
if (rhsFunc == null || Symbols.isPrivate(rhsFunc.symbol)) {
return false;
}
}
// Check for private attached function of the RHS type
for (BAttachedFunction rhsFunc : rhsFuncs) {
if (Symbols.isPrivate(rhsFunc.symbol)) {
return false;
}
}
return true;
}
use of org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol.BAttachedFunction in project ballerina by ballerina-lang.
the class CodeGenerator method createStructInfoEntry.
private void createStructInfoEntry(BLangStruct structNode) {
BStructSymbol structSymbol = (BStructSymbol) structNode.symbol;
// Add Struct name as an UTFCPEntry to the constant pool
int structNameCPIndex = addUTF8CPEntry(currentPkgInfo, structSymbol.name.value);
StructInfo structInfo = new StructInfo(currentPackageRefCPIndex, structNameCPIndex, structSymbol.flags);
currentPkgInfo.addStructInfo(structSymbol.name.value, structInfo);
structInfo.structType = (BStructType) structSymbol.type;
List<BLangVariable> structFields = structNode.fields;
for (BLangVariable structField : structFields) {
// Create StructFieldInfo Entry
int fieldNameCPIndex = addUTF8CPEntry(currentPkgInfo, structField.name.value);
int sigCPIndex = addUTF8CPEntry(currentPkgInfo, structField.type.getDesc());
StructFieldInfo structFieldInfo = new StructFieldInfo(fieldNameCPIndex, sigCPIndex, structField.symbol.flags);
structFieldInfo.fieldType = structField.type;
// Populate default values
if (structField.expr != null && structField.expr.getKind() == NodeKind.LITERAL) {
DefaultValueAttributeInfo defaultVal = getDefaultValueAttributeInfo((BLangLiteral) structField.expr);
structFieldInfo.addAttributeInfo(AttributeInfo.Kind.DEFAULT_VALUE_ATTRIBUTE, defaultVal);
}
structInfo.fieldInfoEntries.add(structFieldInfo);
structField.symbol.varIndex = getFieldIndex(structField.symbol.type.tag);
}
// Create variable count attribute info
prepareIndexes(fieldIndexes);
int[] fieldCount = new int[] { fieldIndexes.tInt, fieldIndexes.tFloat, fieldIndexes.tString, fieldIndexes.tBoolean, fieldIndexes.tBlob, fieldIndexes.tRef };
addVariableCountAttributeInfo(currentPkgInfo, structInfo, fieldCount);
fieldIndexes = new VariableIndex(FIELD);
// Create attached function info entries
for (BAttachedFunction attachedFunc : structSymbol.attachedFuncs) {
int funcNameCPIndex = addUTF8CPEntry(currentPkgInfo, attachedFunc.funcName.value);
// Remove the first type. The first type is always the type to which the function is attached to
BType[] paramTypes = attachedFunc.type.paramTypes.toArray(new BType[0]);
if (paramTypes.length == 1) {
paramTypes = new BType[0];
} else {
paramTypes = attachedFunc.type.paramTypes.toArray(new BType[0]);
paramTypes = Arrays.copyOfRange(paramTypes, 1, paramTypes.length);
}
int sigCPIndex = addUTF8CPEntry(currentPkgInfo, generateFunctionSig(paramTypes, attachedFunc.type.retTypes.toArray(new BType[0])));
int flags = attachedFunc.symbol.flags;
structInfo.attachedFuncInfoEntries.add(new AttachedFunctionInfo(funcNameCPIndex, sigCPIndex, flags));
}
}
Aggregations