use of org.wso2.ballerinalang.compiler.semantics.model.iterable.IterableContext in project ballerina by ballerina-lang.
the class IterableAnalyzer method handlerIterableOperation.
public void handlerIterableOperation(BLangInvocation iExpr, BType expectedType, SymbolEnv env) {
final IterableContext context;
if (iExpr.expr.type.tag != TypeTags.INTERMEDIATE_COLLECTION) {
// This is a new iteration chain.
context = new IterableContext(iExpr.expr, env);
} else {
// Get context from previous invocation.
context = ((BLangInvocation) iExpr.expr).iContext;
}
iExpr.iContext = context;
final IterableKind iterableKind = IterableKind.getFromString(iExpr.name.value);
final Operation iOperation = new Operation(iterableKind, iExpr, expectedType);
iExpr.iContext.addOperation(iOperation);
if (iterableKind.isLambdaRequired()) {
handleLambdaBasedIterableOperation(context, iOperation);
} else {
handleSimpleTerminalOperations(iOperation);
}
validateIterableContext(context);
if (iOperation.resultType != symTable.errType && context.foreachTypes.isEmpty()) {
calculateForeachTypes(context);
}
}
use of org.wso2.ballerinalang.compiler.semantics.model.iterable.IterableContext in project ballerina by ballerina-lang.
the class IterableAnalyzer method validateIterableContext.
public void validateIterableContext(IterableContext context) {
final Operation lastOperation = context.operations.getLast();
final BType expectedType = lastOperation.expectedType;
final BType outputType = lastOperation.resultType;
if (expectedType.tag == TypeTags.VOID && outputType.tag == TypeTags.VOID) {
context.resultType = symTable.noType;
return;
}
if (expectedType.tag == TypeTags.VOID) {
// This error already logged.
return;
}
if (expectedType == symTable.errType) {
context.resultType = symTable.errType;
return;
}
if (outputType.tag == TypeTags.VOID) {
dlog.error(lastOperation.pos, DiagnosticCode.DOES_NOT_RETURN_VALUE, lastOperation.kind);
context.resultType = symTable.errType;
return;
}
// Calculate expected type, if this is an chained iterable operation.
if (outputType.tag == TypeTags.INTERMEDIATE_COLLECTION) {
BIntermediateCollectionType collectionType = (BIntermediateCollectionType) outputType;
final BTupleType tupleType = collectionType.tupleType;
if (expectedType.tag == TypeTags.ARRAY && tupleType.tupleTypes.size() == 1) {
// Convert result into an array.
context.resultType = new BArrayType(tupleType.tupleTypes.get(0));
return;
} else if (expectedType.tag == TypeTags.MAP && tupleType.tupleTypes.size() == 2 && tupleType.tupleTypes.get(0).tag == TypeTags.STRING) {
// Convert result into a map.
context.resultType = new BMapType(TypeTags.MAP, tupleType.tupleTypes.get(1), null);
return;
} else if (expectedType.tag == TypeTags.TABLE) {
// 3. Whether the returned struct is compatible with the constraint struct of the expected type(table)
if (tupleType.getTupleTypes().size() == 1 && tupleType.getTupleTypes().get(0).tag == TypeTags.STRUCT && types.isAssignable(tupleType.getTupleTypes().get(0), ((BTableType) expectedType).constraint)) {
context.resultType = symTable.tableType;
} else {
context.resultType = types.checkType(lastOperation.pos, outputType, ((BTableType) expectedType).constraint, DiagnosticCode.INCOMPATIBLE_TYPES);
}
return;
} else if (expectedType.tag == TypeTags.ANY) {
context.resultType = symTable.errType;
dlog.error(lastOperation.pos, DiagnosticCode.ITERABLE_RETURN_TYPE_MISMATCH, lastOperation.kind);
return;
} else if (expectedType.tag == TypeTags.NONE) {
context.resultType = symTable.noType;
return;
}
}
// Validate compatibility with calculated and expected type.
context.resultType = types.checkType(lastOperation.pos, outputType, expectedType, DiagnosticCode.INCOMPATIBLE_TYPES);
}
use of org.wso2.ballerinalang.compiler.semantics.model.iterable.IterableContext in project ballerina by ballerina-lang.
the class IterableCodeDesugar method desugar.
public void desugar(IterableContext ctx) {
// Gather required data for code generation.
processIterableContext(ctx);
// Generate Iterable Iteration.
generateIteratorFunction(ctx);
// Create invocation expression to invoke iterable operation.
final BLangInvocation iExpr = ASTBuilderUtil.createInvocationExpr(ctx.collectionExpr.pos, ctx.iteratorFuncSymbol, Collections.emptyList(), symResolver);
iExpr.requiredArgs.add(ctx.collectionExpr);
if (ctx.getLastOperation().expectedType == symTable.noType || ctx.getLastOperation().expectedType == symTable.voidType) {
ctx.iteratorCaller = iExpr;
} else {
ctx.iteratorCaller = ASTBuilderUtil.wrapToConversionExpr(ctx.getLastOperation().expectedType, iExpr, symTable, types);
}
}
use of org.wso2.ballerinalang.compiler.semantics.model.iterable.IterableContext in project ballerina by ballerina-lang.
the class IterableCodeDesugar method generateTableAggregator.
private void generateTableAggregator(BLangBlockStmt blockStmt, IterableContext ctx) {
final DiagnosticPos pos = blockStmt.pos;
List<BLangVariable> variables = new ArrayList<>(1);
variables.add(ctx.resultVar);
variables.add(ctx.iteratorResultVariables.get(0));
BInvokableSymbol addSymbol = (BInvokableSymbol) symTable.rootScope.lookup(names.fromString(TABLE_ADD_FUNCTION)).symbol;
BLangInvocation addFunctionInvocation = ASTBuilderUtil.createInvocationExpr(pos, addSymbol, variables, symResolver);
BLangExpressionStmt expressionStmt = ASTBuilderUtil.createExpressionStmt(pos, blockStmt);
expressionStmt.expr = addFunctionInvocation;
}
use of org.wso2.ballerinalang.compiler.semantics.model.iterable.IterableContext in project ballerina by ballerina-lang.
the class IterableCodeDesugar method createIteratorResultVariables.
private List<BLangVariable> createIteratorResultVariables(IterableContext ctx, BLangVariable lastOperationArg, BLangFunction funcNode) {
List<BLangVariable> resultVariables = new ArrayList<>();
if (lastOperationArg.type.tag != TypeTags.TUPLE) {
resultVariables.add(lastOperationArg);
defineVariable(lastOperationArg, ctx.env.enclPkg.symbol.pkgID, funcNode);
return resultVariables;
}
final List<BType> tupleTypes = ((BTupleType) lastOperationArg.type).tupleTypes;
int index = 0;
for (BType type : tupleTypes) {
String varName = VAR_RESULT_VAL + index++;
final BLangVariable variable = ASTBuilderUtil.createVariable(funcNode.pos, varName, type);
resultVariables.add(variable);
defineVariable(variable, ctx.env.enclPkg.symbol.pkgID, funcNode);
}
return resultVariables;
}
Aggregations