use of org.wso2.ballerinalang.compiler.semantics.model.types.BStructType in project ballerina by ballerina-lang.
the class SymbolEnter method defineObjectFields.
private void defineObjectFields(List<? extends BLangObject> objectNodes, SymbolEnv pkgEnv) {
objectNodes.forEach(object -> {
// Create object type
SymbolEnv objectEnv = SymbolEnv.createObjectEnv(object, object.symbol.scope, pkgEnv);
BStructType objectType = (BStructType) object.symbol.type;
objectType.fields = object.fields.stream().peek(field -> defineNode(field, objectEnv)).map(field -> new BStructField(names.fromIdNode(field.name), field.symbol)).collect(Collectors.toList());
});
}
use of org.wso2.ballerinalang.compiler.semantics.model.types.BStructType 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.types.BStructType in project ballerina by ballerina-lang.
the class TypeChecker method visit.
public void visit(BLangInvocation iExpr) {
// e.g. foo();, foo(), foo().k;
if (iExpr.expr == null) {
// This is a function invocation expression. e.g. foo()
checkFunctionInvocationExpr(iExpr);
return;
}
Name pkgAlias = names.fromIdNode(iExpr.pkgAlias);
if (pkgAlias != Names.EMPTY) {
dlog.error(iExpr.pos, DiagnosticCode.PKG_ALIAS_NOT_ALLOWED_HERE);
return;
}
// Find the variable reference expression type
final List<BType> exprTypes = checkExpr(iExpr.expr, this.env, Lists.of(symTable.noType));
if (isIterableOperationInvocation(iExpr)) {
iExpr.iterableOperationInvocation = true;
iterableAnalyzer.handlerIterableOperation(iExpr, expTypes.isEmpty() ? symTable.voidType : expTypes.get(0), env);
if (iExpr.iContext.operations.getLast().resultType == symTable.voidType) {
resultTypes = Collections.emptyList();
} else {
resultTypes = Lists.of(iExpr.iContext.operations.getLast().resultType);
}
return;
}
if (iExpr.actionInvocation) {
if (exprTypes.size() != 1) {
dlog.error(iExpr.expr.pos, DiagnosticCode.SINGLE_VALUE_RETURN_EXPECTED);
}
checkActionInvocationExpr(iExpr, exprTypes.size() > 0 ? exprTypes.get(0) : symTable.errType);
return;
}
switch(iExpr.expr.type.tag) {
case TypeTags.STRUCT:
// Invoking a function bound to a struct
// First check whether there exist a function with this name
// Then perform arg and param matching
checkFunctionInvocationExpr(iExpr, (BStructType) iExpr.expr.type);
break;
case TypeTags.CONNECTOR:
dlog.error(iExpr.pos, DiagnosticCode.INVALID_ACTION_INVOCATION_SYNTAX);
resultTypes = getListWithErrorTypes(expTypes.size());
return;
case TypeTags.BOOLEAN:
case TypeTags.STRING:
case TypeTags.INT:
case TypeTags.FLOAT:
case TypeTags.BLOB:
case TypeTags.XML:
checkFunctionInvocationExpr(iExpr, iExpr.expr.type);
break;
case TypeTags.JSON:
checkFunctionInvocationExpr(iExpr, symTable.jsonType);
break;
case TypeTags.TABLE:
checkFunctionInvocationExpr(iExpr, symTable.tableType);
break;
case TypeTags.STREAM:
checkFunctionInvocationExpr(iExpr, symTable.streamType);
break;
case TypeTags.FUTURE:
checkFunctionInvocationExpr(iExpr, symTable.futureType);
break;
case TypeTags.NONE:
dlog.error(iExpr.pos, DiagnosticCode.UNDEFINED_FUNCTION, iExpr.name);
break;
case TypeTags.MAP:
// allow map function for both constrained / un constrained maps
checkFunctionInvocationExpr(iExpr, this.symTable.mapType);
break;
case TypeTags.ERROR:
break;
case TypeTags.INTERMEDIATE_COLLECTION:
dlog.error(iExpr.pos, DiagnosticCode.INVALID_FUNCTION_INVOCATION_WITH_NAME, iExpr.name, iExpr.expr.type);
resultTypes = getListWithErrorTypes(expTypes.size());
break;
default:
dlog.error(iExpr.pos, DiagnosticCode.INVALID_FUNCTION_INVOCATION, iExpr.expr.type);
resultTypes = getListWithErrorTypes(expTypes.size());
break;
}
// TODO other types of invocation expressions
// TODO pkg alias should be null or empty here.
}
use of org.wso2.ballerinalang.compiler.semantics.model.types.BStructType in project ballerina by ballerina-lang.
the class EndpointSPIAnalyzer method getEndpointTypeFromServiceType.
public BStructType getEndpointTypeFromServiceType(DiagnosticPos pos, BType type) {
if (type.tag != TypeTags.STRUCT) {
dlog.error(pos, DiagnosticCode.ENDPOINT_STRUCT_TYPE_REQUIRED);
return null;
}
final BStructSymbol serviceType = (BStructSymbol) type.tsymbol;
for (BStructSymbol.BAttachedFunction attachedFunc : serviceType.attachedFuncs) {
if (Names.EP_SERVICE_GET_ENDPOINT.equals(attachedFunc.funcName)) {
if (attachedFunc.type.getParameterTypes().size() != 0 || attachedFunc.type.retTypes.size() != 1 || attachedFunc.type.retTypes.get(0).tag != TypeTags.STRUCT) {
dlog.error(pos, DiagnosticCode.SERVICE_INVALID_STRUCT_TYPE, serviceType);
return null;
}
final BStructSymbol endPointType = (BStructSymbol) attachedFunc.type.retTypes.get(0).tsymbol;
if (isValidEndpointSPI(pos, endPointType)) {
return (BStructType) attachedFunc.type.retTypes.get(0);
}
break;
}
}
dlog.error(pos, DiagnosticCode.SERVICE_INVALID_STRUCT_TYPE, serviceType);
return null;
}
use of org.wso2.ballerinalang.compiler.semantics.model.types.BStructType in project ballerina by ballerina-lang.
the class SemanticAnalyzer method handleServiceEndpointBinds.
private void handleServiceEndpointBinds(BLangService serviceNode, BServiceSymbol serviceSymbol) {
for (BLangSimpleVarRef ep : serviceNode.boundEndpoints) {
typeChecker.checkExpr(ep, env);
if (ep.symbol == null || (ep.symbol.tag & SymTag.ENDPOINT) != SymTag.ENDPOINT) {
dlog.error(ep.pos, DiagnosticCode.ENDPOINT_INVALID_TYPE, ep.variableName);
continue;
}
final BEndpointVarSymbol epSym = (BEndpointVarSymbol) ep.symbol;
if ((epSym.tag & SymTag.ENDPOINT) == SymTag.ENDPOINT) {
if (epSym.registrable) {
serviceSymbol.boundEndpoints.add(epSym);
if (serviceNode.endpointType == null) {
serviceNode.endpointType = (BStructType) epSym.type;
serviceNode.endpointClientType = endpointSPIAnalyzer.getClientType((BStructSymbol) serviceNode.endpointType.tsymbol);
}
// TODO : Validate serviceType endpoint type with bind endpoint types.
} else {
dlog.error(ep.pos, DiagnosticCode.ENDPOINT_NOT_SUPPORT_REGISTRATION, epSym);
}
} else {
dlog.error(ep.pos, DiagnosticCode.ENDPOINT_INVALID_TYPE, epSym);
}
}
if (serviceNode.endpointType == null) {
dlog.error(serviceNode.pos, DiagnosticCode.SERVICE_INVALID_ENDPOINT_TYPE, serviceNode.name);
}
}
Aggregations