use of org.wso2.ballerinalang.compiler.codegen.CodeGenerator.VariableIndex.Kind.FIELD in project ballerina by ballerina-lang.
the class SemanticAnalyzer method visit.
public void visit(BLangStruct structNode) {
BSymbol structSymbol = structNode.symbol;
SymbolEnv structEnv = SymbolEnv.createPkgLevelSymbolEnv(structNode, structSymbol.scope, env);
structNode.fields.forEach(field -> analyzeDef(field, structEnv));
structNode.annAttachments.forEach(annotationAttachment -> {
annotationAttachment.attachmentPoint = new BLangAnnotationAttachmentPoint(BLangAnnotationAttachmentPoint.AttachmentPoint.STRUCT);
annotationAttachment.accept(this);
});
analyzeDef(structNode.initFunction, structEnv);
structNode.docAttachments.forEach(doc -> analyzeDef(doc, structEnv));
}
use of org.wso2.ballerinalang.compiler.codegen.CodeGenerator.VariableIndex.Kind.FIELD in project ballerina by ballerina-lang.
the class TypeChecker method visit.
public void visit(BLangFieldBasedAccess fieldAccessExpr) {
// First analyze the variable reference expression.
BType actualType = symTable.errType;
BType varRefType = getTypeOfExprInFieldAccess(fieldAccessExpr.expr);
if (fieldAccessExpr.fieldType == FieldType.ALL && varRefType.tag != TypeTags.XML) {
dlog.error(fieldAccessExpr.pos, DiagnosticCode.CANNOT_GET_ALL_FIELDS, varRefType);
}
Name fieldName = names.fromIdNode(fieldAccessExpr.field);
switch(varRefType.tag) {
case TypeTags.STRUCT:
actualType = checkStructFieldAccess(fieldAccessExpr, fieldName, varRefType);
break;
case TypeTags.MAP:
actualType = ((BMapType) varRefType).getConstraint();
break;
case TypeTags.JSON:
BType constraintType = ((BJSONType) varRefType).constraint;
if (constraintType.tag == TypeTags.STRUCT) {
BType fieldType = checkStructFieldAccess(fieldAccessExpr, fieldName, constraintType);
// If the type of the field is struct, treat it as constraint JSON type.
if (fieldType.tag == TypeTags.STRUCT) {
actualType = new BJSONType(TypeTags.JSON, fieldType, symTable.jsonType.tsymbol);
break;
}
}
actualType = symTable.jsonType;
break;
case TypeTags.ENUM:
// Enumerator access expressions only allow enum type name as the first part e.g state.INSTALLED,
BEnumType enumType = (BEnumType) varRefType;
if (fieldAccessExpr.expr.getKind() != NodeKind.SIMPLE_VARIABLE_REF || !((BLangSimpleVarRef) fieldAccessExpr.expr).variableName.value.equals(enumType.tsymbol.name.value)) {
dlog.error(fieldAccessExpr.pos, DiagnosticCode.INVALID_ENUM_EXPR, enumType.tsymbol.name.value);
break;
}
BSymbol symbol = symResolver.lookupMemberSymbol(fieldAccessExpr.pos, enumType.tsymbol.scope, this.env, fieldName, SymTag.VARIABLE);
if (symbol == symTable.notFoundSymbol) {
dlog.error(fieldAccessExpr.pos, DiagnosticCode.UNDEFINED_SYMBOL, fieldName.value);
break;
}
fieldAccessExpr.symbol = (BVarSymbol) symbol;
actualType = fieldAccessExpr.expr.type;
break;
case TypeTags.XML:
if (fieldAccessExpr.lhsVar) {
dlog.error(fieldAccessExpr.pos, DiagnosticCode.CANNOT_UPDATE_XML_SEQUENCE);
break;
}
actualType = symTable.xmlType;
break;
case TypeTags.ERROR:
// Do nothing
break;
default:
dlog.error(fieldAccessExpr.pos, DiagnosticCode.OPERATION_DOES_NOT_SUPPORT_FIELD_ACCESS, varRefType);
}
resultTypes = types.checkTypes(fieldAccessExpr, Lists.of(actualType), this.expTypes);
}
use of org.wso2.ballerinalang.compiler.codegen.CodeGenerator.VariableIndex.Kind.FIELD in project ballerina by ballerina-lang.
the class TypeChecker method checkFunctionInvocationExpr.
private void checkFunctionInvocationExpr(BLangInvocation iExpr, BStructType structType) {
String funcName = iExpr.name.value;
Name uniqueFuncName = names.fromString(Symbols.getAttachedFuncSymbolName(structType.tsymbol.name.value, funcName));
BPackageSymbol packageSymbol = (BPackageSymbol) structType.tsymbol.owner;
BSymbol funcSymbol = symResolver.lookupMemberSymbol(iExpr.pos, packageSymbol.scope, this.env, uniqueFuncName, SymTag.FUNCTION);
if (funcSymbol == symTable.notFoundSymbol) {
// Check functions defined within the struct.
Name functionName = names.fromString(Symbols.getAttachedFuncSymbolName(iExpr.expr.symbol.type.tsymbol.name.value, iExpr.name.value));
funcSymbol = symResolver.resolveStructField(iExpr.pos, env, functionName, iExpr.expr.symbol.type.tsymbol);
if (funcSymbol == symTable.notFoundSymbol) {
// Check, any function pointer in struct field with given name.
funcSymbol = symResolver.resolveStructField(iExpr.pos, env, names.fromIdNode(iExpr.name), iExpr.expr.symbol.type.tsymbol);
if (funcSymbol == symTable.notFoundSymbol || funcSymbol.type.tag != TypeTags.INVOKABLE) {
dlog.error(iExpr.pos, DiagnosticCode.UNDEFINED_FUNCTION_IN_STRUCT, funcName, structType);
resultTypes = getListWithErrorTypes(expTypes.size());
return;
}
if ((funcSymbol.flags & Flags.ATTACHED) != Flags.ATTACHED) {
iExpr.functionPointerInvocation = true;
}
}
} else {
// Attached function found
// Check for the explicit initializer function invocation
BStructSymbol.BAttachedFunction initializerFunc = ((BStructSymbol) structType.tsymbol).initializerFunc;
if (initializerFunc != null && initializerFunc.funcName.value.equals(funcName)) {
dlog.error(iExpr.pos, DiagnosticCode.STRUCT_INITIALIZER_INVOKED, structType.tsymbol.toString());
}
}
iExpr.symbol = funcSymbol;
checkInvocationParamAndReturnType(iExpr);
}
use of org.wso2.ballerinalang.compiler.codegen.CodeGenerator.VariableIndex.Kind.FIELD in project ballerina by ballerina-lang.
the class TypeChecker method visit.
public void visit(BLangIndexBasedAccess indexBasedAccessExpr) {
BType actualType = symTable.errType;
// First analyze the variable reference expression.
checkExpr(indexBasedAccessExpr.expr, this.env, Lists.of(symTable.noType));
BType indexExprType;
BType varRefType = indexBasedAccessExpr.expr.type;
BLangExpression indexExpr = indexBasedAccessExpr.indexExpr;
switch(varRefType.tag) {
case TypeTags.STRUCT:
indexExprType = checkIndexExprForStructFieldAccess(indexExpr);
if (indexExprType.tag == TypeTags.STRING) {
String fieldName = (String) ((BLangLiteral) indexExpr).value;
actualType = checkStructFieldAccess(indexBasedAccessExpr, names.fromString(fieldName), varRefType);
}
break;
case TypeTags.MAP:
indexExprType = checkExpr(indexExpr, this.env, Lists.of(symTable.stringType)).get(0);
if (indexExprType.tag == TypeTags.STRING) {
actualType = ((BMapType) varRefType).getConstraint();
}
break;
case TypeTags.JSON:
BType constraintType = ((BJSONType) varRefType).constraint;
if (constraintType.tag == TypeTags.STRUCT) {
indexExprType = checkIndexExprForStructFieldAccess(indexExpr);
if (indexExprType.tag != TypeTags.STRING) {
break;
}
String fieldName = (String) ((BLangLiteral) indexExpr).value;
BType fieldType = checkStructFieldAccess(indexBasedAccessExpr, names.fromString(fieldName), constraintType);
// If the type of the field is struct, treat it as constraint JSON type.
if (fieldType.tag == TypeTags.STRUCT) {
actualType = new BJSONType(TypeTags.JSON, fieldType, symTable.jsonType.tsymbol);
break;
}
} else {
indexExprType = checkExpr(indexExpr, this.env, Lists.of(symTable.noType)).get(0);
if (indexExprType.tag != TypeTags.STRING && indexExprType.tag != TypeTags.INT) {
dlog.error(indexExpr.pos, DiagnosticCode.INCOMPATIBLE_TYPES, symTable.stringType, indexExprType);
break;
}
}
actualType = symTable.jsonType;
break;
case TypeTags.ARRAY:
indexExprType = checkExpr(indexExpr, this.env, Lists.of(symTable.intType)).get(0);
if (indexExprType.tag == TypeTags.INT) {
actualType = ((BArrayType) varRefType).getElementType();
}
break;
case TypeTags.XML:
if (indexBasedAccessExpr.lhsVar) {
dlog.error(indexBasedAccessExpr.pos, DiagnosticCode.CANNOT_UPDATE_XML_SEQUENCE);
break;
}
checkExpr(indexExpr, this.env).get(0);
actualType = symTable.xmlType;
break;
case TypeTags.ERROR:
// Do nothing
break;
default:
dlog.error(indexBasedAccessExpr.pos, DiagnosticCode.OPERATION_DOES_NOT_SUPPORT_INDEXING, indexBasedAccessExpr.expr.type);
}
resultTypes = types.checkTypes(indexBasedAccessExpr, Lists.of(actualType), this.expTypes);
}
use of org.wso2.ballerinalang.compiler.codegen.CodeGenerator.VariableIndex.Kind.FIELD in project ballerina by ballerina-lang.
the class TypeChecker method checkStructFieldAccess.
private BType checkStructFieldAccess(BLangVariableReference varReferExpr, Name fieldName, BType structType) {
BSymbol fieldSymbol = symResolver.resolveStructField(varReferExpr.pos, this.env, fieldName, structType.tsymbol);
if (fieldSymbol == symTable.notFoundSymbol) {
dlog.error(varReferExpr.pos, DiagnosticCode.UNDEFINED_STRUCT_FIELD, fieldName, structType.tsymbol);
return symTable.errType;
}
// Setting the field symbol. This is used during the code generation phase
varReferExpr.symbol = (BVarSymbol) fieldSymbol;
return fieldSymbol.type;
}
Aggregations