use of org.wso2.ballerinalang.compiler.semantics.model.types.BArrayType in project ballerina by ballerina-lang.
the class TaintAnalyzer method isEntryPoint.
// Private methods related to invokable node analysis and taint-table generation.
private boolean isEntryPoint(BLangFunction funcNode) {
// Service resources are handled through BLangResource visitor.
boolean isMainFunction = false;
if (funcNode.name.value.equals(MAIN_FUNCTION_NAME) && funcNode.symbol.params.size() == 1 && funcNode.symbol.retParams.size() == 0) {
BType paramType = funcNode.symbol.params.get(0).type;
BArrayType arrayType = (BArrayType) paramType;
if (paramType.tag == TypeTags.ARRAY && arrayType.eType.tag == TypeTags.STRING) {
isMainFunction = true;
}
}
return isMainFunction;
}
use of org.wso2.ballerinalang.compiler.semantics.model.types.BArrayType in project ballerina by ballerina-lang.
the class TypeChecker method checkRestArgs.
private void checkRestArgs(List<BLangExpression> restArgExprs, BLangExpression vararg, BVarSymbol restParam) {
if (vararg != null && !restArgExprs.isEmpty()) {
dlog.error(vararg.pos, DiagnosticCode.INVALID_REST_ARGS);
return;
}
if (vararg != null) {
checkExpr(vararg, this.env, Lists.of(restParam.type));
restArgExprs.add(vararg);
return;
}
for (BLangExpression arg : restArgExprs) {
checkExpr(arg, this.env, Lists.of(((BArrayType) restParam.type).eType));
}
}
use of org.wso2.ballerinalang.compiler.semantics.model.types.BArrayType 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.types.BArrayType 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.semantics.model.types.BArrayType in project ballerina by ballerina-lang.
the class CodeGenerator method visit.
@Override
public void visit(BLangArrayAccessExpr arrayIndexAccessExpr) {
boolean variableStore = this.varAssignment;
this.varAssignment = false;
genNode(arrayIndexAccessExpr.expr, this.env);
Operand varRefRegIndex = arrayIndexAccessExpr.expr.regIndex;
genNode(arrayIndexAccessExpr.indexExpr, this.env);
Operand indexRegIndex = arrayIndexAccessExpr.indexExpr.regIndex;
BArrayType arrayType = (BArrayType) arrayIndexAccessExpr.expr.type;
if (variableStore) {
int opcode = getOpcode(arrayType.eType.tag, InstructionCodes.IASTORE);
emit(opcode, varRefRegIndex, indexRegIndex, arrayIndexAccessExpr.regIndex);
} else {
int opcode = getOpcode(arrayType.eType.tag, InstructionCodes.IALOAD);
emit(opcode, varRefRegIndex, indexRegIndex, calcAndGetExprRegIndex(arrayIndexAccessExpr));
}
this.varAssignment = variableStore;
}
Aggregations