Search in sources :

Example 1 with BAttachedFunction

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;
}
Also used : BStructType(org.wso2.ballerinalang.compiler.semantics.model.types.BStructType) BAttachedFunction(org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol.BAttachedFunction) BSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BSymbol) BInvokableType(org.wso2.ballerinalang.compiler.semantics.model.types.BInvokableType) BStructSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol)

Example 2 with BAttachedFunction

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;
}
Also used : BAttachedFunction(org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol.BAttachedFunction) BSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BSymbol) BInvokableType(org.wso2.ballerinalang.compiler.semantics.model.types.BInvokableType) BStructSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol)

Example 3 with BAttachedFunction

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;
}
Also used : BStructField(org.wso2.ballerinalang.compiler.semantics.model.types.BStructType.BStructField) BAttachedFunction(org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol.BAttachedFunction) BStructSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol)

Example 4 with BAttachedFunction

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;
}
Also used : BStructField(org.wso2.ballerinalang.compiler.semantics.model.types.BStructType.BStructField) BAttachedFunction(org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol.BAttachedFunction) BStructSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol)

Example 5 with BAttachedFunction

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));
    }
}
Also used : BAttachedFunction(org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol.BAttachedFunction) AttachedFunctionInfo(org.wso2.ballerinalang.programfile.AttachedFunctionInfo) StructInfo(org.wso2.ballerinalang.programfile.StructInfo) StructFieldInfo(org.wso2.ballerinalang.programfile.StructFieldInfo) BStructSymbol(org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol) BLangEndpoint(org.wso2.ballerinalang.compiler.tree.BLangEndpoint) BLangVariable(org.wso2.ballerinalang.compiler.tree.BLangVariable) ParamDefaultValueAttributeInfo(org.wso2.ballerinalang.programfile.attributes.ParamDefaultValueAttributeInfo) DefaultValueAttributeInfo(org.wso2.ballerinalang.programfile.attributes.DefaultValueAttributeInfo) BType(org.wso2.ballerinalang.compiler.semantics.model.types.BType)

Aggregations

BStructSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol)6 BAttachedFunction (org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructSymbol.BAttachedFunction)5 BSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BSymbol)2 BInvokableType (org.wso2.ballerinalang.compiler.semantics.model.types.BInvokableType)2 BStructType (org.wso2.ballerinalang.compiler.semantics.model.types.BStructType)2 BStructField (org.wso2.ballerinalang.compiler.semantics.model.types.BStructType.BStructField)2 BType (org.wso2.ballerinalang.compiler.semantics.model.types.BType)2 BLangEndpoint (org.wso2.ballerinalang.compiler.tree.BLangEndpoint)2 ArrayList (java.util.ArrayList)1 SymbolInfo (org.ballerinalang.langserver.completions.SymbolInfo)1 CompletionItem (org.eclipse.lsp4j.CompletionItem)1 Scope (org.wso2.ballerinalang.compiler.semantics.model.Scope)1 BVarSymbol (org.wso2.ballerinalang.compiler.semantics.model.symbols.BVarSymbol)1 BLangNode (org.wso2.ballerinalang.compiler.tree.BLangNode)1 BLangVariable (org.wso2.ballerinalang.compiler.tree.BLangVariable)1 AttachedFunctionInfo (org.wso2.ballerinalang.programfile.AttachedFunctionInfo)1 StructFieldInfo (org.wso2.ballerinalang.programfile.StructFieldInfo)1 StructInfo (org.wso2.ballerinalang.programfile.StructInfo)1 DefaultValueAttributeInfo (org.wso2.ballerinalang.programfile.attributes.DefaultValueAttributeInfo)1 ParamDefaultValueAttributeInfo (org.wso2.ballerinalang.programfile.attributes.ParamDefaultValueAttributeInfo)1