use of org.wso2.siddhi.query.api.annotation.Annotation in project ballerina by ballerina-lang.
the class SymbolEnter method visit.
// Visitor methods
@Override
public void visit(BLangPackage pkgNode) {
if (pkgNode.completedPhases.contains(CompilerPhase.DEFINE)) {
return;
}
// Create PackageSymbol.
BPackageSymbol pSymbol = createPackageSymbol(pkgNode);
SymbolEnv builtinEnv = this.symTable.pkgEnvMap.get(symTable.builtInPackageSymbol);
SymbolEnv pkgEnv = SymbolEnv.createPkgEnv(pkgNode, pSymbol.scope, builtinEnv);
this.symTable.pkgEnvMap.put(pSymbol, pkgEnv);
createPackageInitFunctions(pkgNode);
// visit the package node recursively and define all package level symbols.
// And maintain a list of created package symbols.
pkgNode.imports.forEach(importNode -> defineNode(importNode, pkgEnv));
// Define struct nodes.
pkgNode.enums.forEach(enumNode -> defineNode(enumNode, pkgEnv));
// Define struct nodes.
pkgNode.structs.forEach(struct -> defineNode(struct, pkgEnv));
// Define object nodes
pkgNode.objects.forEach(object -> defineNode(object, pkgEnv));
// Define connector nodes.
pkgNode.connectors.forEach(con -> defineNode(con, pkgEnv));
// Define connector params and type.
defineConnectorParams(pkgNode.connectors, pkgEnv);
// Define transformer nodes.
pkgNode.transformers.forEach(tansformer -> defineNode(tansformer, pkgEnv));
// Define service and resource nodes.
pkgNode.services.forEach(service -> defineNode(service, pkgEnv));
// Define struct field nodes.
defineStructFields(pkgNode.structs, pkgEnv);
// Define object field nodes.
defineObjectFields(pkgNode.objects, pkgEnv);
// Define connector action nodes.
defineConnectorMembers(pkgNode.connectors, pkgEnv);
// Define object functions
defineObjectMembers(pkgNode.objects, pkgEnv);
// Define function nodes.
pkgNode.functions.forEach(func -> defineNode(func, pkgEnv));
// Define transformer params
defineTransformerMembers(pkgNode.transformers, pkgEnv);
// Define service resource nodes.
defineServiceMembers(pkgNode.services, pkgEnv);
// Define annotation nodes.
pkgNode.annotations.forEach(annot -> defineNode(annot, pkgEnv));
resolveAnnotationAttributeTypes(pkgNode.annotations, pkgEnv);
pkgNode.globalVars.forEach(var -> defineNode(var, pkgEnv));
pkgNode.globalEndpoints.forEach(ep -> defineNode(ep, pkgEnv));
definePackageInitFunctions(pkgNode, pkgEnv);
pkgNode.completedPhases.add(CompilerPhase.DEFINE);
}
use of org.wso2.siddhi.query.api.annotation.Annotation in project ballerina by ballerina-lang.
the class SymbolResolver method visit.
public void visit(BLangUserDefinedType userDefinedTypeNode) {
// 1) Resolve the package scope using the package alias.
// If the package alias is not empty or null, then find the package scope,
// if not use the current package scope.
// 2) lookup the typename in the package scope returned from step 1.
// 3) If the symbol is not found, then lookup in the root scope. e.g. for types such as 'error'
BSymbol pkgSymbol = resolvePkgSymbol(userDefinedTypeNode.pos, this.env, names.fromIdNode(userDefinedTypeNode.pkgAlias));
if (pkgSymbol == symTable.notFoundSymbol) {
resultType = symTable.errType;
return;
}
Name typeName = names.fromIdNode(userDefinedTypeNode.typeName);
BSymbol symbol = symTable.notFoundSymbol;
// Only valued types and ANNOTATION type allowed.
if (env.scope.owner.tag == SymTag.ANNOTATION) {
symbol = lookupMemberSymbol(userDefinedTypeNode.pos, pkgSymbol.scope, this.env, typeName, SymTag.ANNOTATION);
}
// 3) Lookup the current package scope.
if (symbol == symTable.notFoundSymbol) {
symbol = lookupMemberSymbol(userDefinedTypeNode.pos, pkgSymbol.scope, this.env, typeName, SymTag.VARIABLE_NAME);
}
if (symbol == symTable.notFoundSymbol) {
// 4) Lookup the root scope for types such as 'error'
symbol = lookupMemberSymbol(userDefinedTypeNode.pos, symTable.rootScope, this.env, typeName, SymTag.VARIABLE_NAME);
}
if (symbol == symTable.notFoundSymbol) {
dlog.error(userDefinedTypeNode.pos, diagCode, typeName);
resultType = symTable.errType;
return;
}
if (symbol.kind == SymbolKind.CONNECTOR) {
userDefinedTypeNode.flagSet = EnumSet.of(Flag.CONNECTOR);
}
resultType = symbol.type;
}
use of org.wso2.siddhi.query.api.annotation.Annotation in project ballerina by ballerina-lang.
the class TaintAnalyzer method analyzeInvocation.
// Private methods relevant to invocation analysis.
private void analyzeInvocation(BLangInvocation invocationExpr) {
BInvokableSymbol invokableSymbol = (BInvokableSymbol) invocationExpr.symbol;
Map<Integer, TaintRecord> taintTable = invokableSymbol.taintTable;
List<Boolean> returnTaintedStatus = new ArrayList<>();
TaintRecord allParamsUntaintedRecord = taintTable.get(ALL_UNTAINTED_TABLE_ENTRY_INDEX);
if (allParamsUntaintedRecord.taintError != null && allParamsUntaintedRecord.taintError.size() > 0) {
// This can occur when there is a error regardless of tainted status of parameters.
// Example: Tainted value returned by function is passed to another functions's sensitive parameter.
addTaintError(allParamsUntaintedRecord.taintError);
} else {
returnTaintedStatus = new ArrayList<>(taintTable.get(ALL_UNTAINTED_TABLE_ENTRY_INDEX).retParamTaintedStatus);
}
if (invocationExpr.argExprs != null) {
for (int argIndex = 0; argIndex < invocationExpr.argExprs.size(); argIndex++) {
BLangExpression argExpr = invocationExpr.argExprs.get(argIndex);
argExpr.accept(this);
// return-tainted-status when the given argument is in tainted state.
if (getObservedTaintedStatus()) {
TaintRecord taintRecord = taintTable.get(argIndex);
if (taintRecord == null) {
// This is when current parameter is "sensitive". Therefore, providing a tainted
// value to a sensitive parameter is invalid and should return a compiler error.
int requiredParamCount = invokableSymbol.params.size();
int defaultableParamCount = invokableSymbol.defaultableParams.size();
int totalParamCount = requiredParamCount + defaultableParamCount + (invokableSymbol.restParam == null ? 0 : 1);
BVarSymbol paramSymbol = getParamSymbol(invokableSymbol, argIndex, requiredParamCount, defaultableParamCount);
addTaintError(argExpr.pos, paramSymbol.name.value, DiagnosticCode.TAINTED_VALUE_PASSED_TO_SENSITIVE_PARAMETER);
} else if (taintRecord.taintError != null && taintRecord.taintError.size() > 0) {
// This is when current parameter is derived to be sensitive. The error already generated
// during taint-table generation will be used.
addTaintError(taintRecord.taintError);
} else {
// status of all returns to get accumulated tainted status of all returns for the invocation.
for (int returnIndex = 0; returnIndex < returnTaintedStatus.size(); returnIndex++) {
if (taintRecord.retParamTaintedStatus.get(returnIndex)) {
returnTaintedStatus.set(returnIndex, true);
}
}
}
if (stopAnalysis) {
break;
}
}
}
}
if (invocationExpr.expr != null) {
// When an invocation like stringValue.trim() happens, if stringValue is tainted, the result will
// also be tainted.
// TODO: TaintedIf annotation, so that it's possible to define what can taint or untaint the return.
invocationExpr.expr.accept(this);
for (int i = 0; i < returnTaintedStatus.size(); i++) {
if (getObservedTaintedStatus()) {
returnTaintedStatus.set(i, getObservedTaintedStatus());
}
}
}
taintedStatusList = returnTaintedStatus;
}
use of org.wso2.siddhi.query.api.annotation.Annotation in project ballerina by ballerina-lang.
the class SemanticAnalyzer method visit.
public void visit(BLangAnnotationAttachment annAttachmentNode) {
BSymbol symbol = this.symResolver.resolveAnnotation(annAttachmentNode.pos, env, names.fromString(annAttachmentNode.pkgAlias.getValue()), names.fromString(annAttachmentNode.getAnnotationName().getValue()));
if (symbol == this.symTable.notFoundSymbol) {
this.dlog.error(annAttachmentNode.pos, DiagnosticCode.UNDEFINED_ANNOTATION, annAttachmentNode.getAnnotationName().getValue());
return;
}
// Validate Attachment Point against the Annotation Definition.
BAnnotationSymbol annotationSymbol = (BAnnotationSymbol) symbol;
annAttachmentNode.annotationSymbol = annotationSymbol;
if (annotationSymbol.getAttachmentPoints() != null && annotationSymbol.getAttachmentPoints().size() > 0) {
BLangAnnotationAttachmentPoint[] attachmentPointsArrray = new BLangAnnotationAttachmentPoint[annotationSymbol.getAttachmentPoints().size()];
Optional<BLangAnnotationAttachmentPoint> matchingAttachmentPoint = Arrays.stream(annotationSymbol.getAttachmentPoints().toArray(attachmentPointsArrray)).filter(attachmentPoint -> attachmentPoint.equals(annAttachmentNode.attachmentPoint)).findAny();
if (!matchingAttachmentPoint.isPresent()) {
String msg = annAttachmentNode.attachmentPoint.getAttachmentPoint().getValue();
this.dlog.error(annAttachmentNode.pos, DiagnosticCode.ANNOTATION_NOT_ALLOWED, annotationSymbol, msg);
}
}
// Validate Annotation Attachment data struct against Annotation Definition struct.
validateAnnotationAttachmentExpr(annAttachmentNode, annotationSymbol);
}
use of org.wso2.siddhi.query.api.annotation.Annotation in project ballerina by ballerina-lang.
the class TreeVisitor method visit.
public void visit(BLangConnector connectorNode) {
String connectorName = connectorNode.getName().getValue();
BSymbol connectorSymbol = connectorNode.symbol;
SymbolEnv connectorEnv = SymbolEnv.createConnectorEnv(connectorNode, connectorSymbol.scope, symbolEnv);
if (isWithinParameterContext(connectorName, NODE_TYPE_CONNECTOR)) {
this.populateSymbols(this.resolveAllVisibleSymbols(connectorEnv), connectorEnv);
setTerminateVisitor(true);
} else if (!ScopeResolverConstants.getResolverByClass(cursorPositionResolver).isCursorBeforeNode(connectorNode.getPosition(), connectorNode, this, this.documentServiceContext)) {
// Reset the previous node
this.setPreviousNode(null);
// TODO: Handle Annotation attachments
if (!(connectorNode.actions.isEmpty() && connectorNode.varDefs.isEmpty() && connectorNode.endpoints.isEmpty())) {
// Visit the endpoints
connectorNode.endpoints.forEach(bLangEndpoint -> this.acceptNode(bLangEndpoint, connectorEnv));
// Since the connector def does not contains a block statement, we consider the block owner only.
// Here it is Connector Definition
this.blockOwnerStack.push(connectorNode);
connectorNode.varDefs.forEach(varDef -> {
// Cursor position is calculated against the Connector scope resolver
cursorPositionResolver = ConnectorScopeResolver.class;
this.acceptNode(varDef, connectorEnv);
});
connectorNode.actions.forEach(action -> {
// Cursor position is calculated against the Connector scope resolver
cursorPositionResolver = ConnectorScopeResolver.class;
this.acceptNode(action, connectorEnv);
});
if (terminateVisitor) {
this.acceptNode(null, null);
}
this.blockOwnerStack.pop();
} else {
this.isCursorWithinBlock(connectorNode.getPosition(), connectorEnv);
}
}
}
Aggregations