use of org.wso2.ballerinalang.compiler.Compiler in project ballerina by ballerina-lang.
the class BCompileUtil method getDiagnostics.
/**
* Used by IntelliJ IDEA plugin to provide semantic analyzing capability.
*
* @param classLoader a {@link ClassLoader} to be set as thread context class loader. This is used by {@link
* java.util.ServiceLoader}. Otherwise semantic analyzing capability providing wont work since it
* cant find core package.
* @param sourceRoot source root of a project
* @param fileName either the file name (if in project root) or the package name
* @return list of diagnostics
*/
public static List<Diagnostic> getDiagnostics(ClassLoader classLoader, String sourceRoot, String fileName) {
Thread.currentThread().setContextClassLoader(classLoader);
CompilerContext context = new CompilerContext();
CompilerOptions options = CompilerOptions.getInstance(context);
options.put(PROJECT_DIR, sourceRoot);
options.put(COMPILER_PHASE, CompilerPhase.CODE_GEN.toString());
options.put(PRESERVE_WHITESPACE, "false");
CompileResult comResult = new CompileResult();
// catch errors
DiagnosticListener listener = comResult::addDiagnostic;
context.put(DiagnosticListener.class, listener);
// compile
Compiler compiler = Compiler.getInstance(context);
BLangPackage entryPackageNode = compiler.compile(fileName);
CompiledBinaryFile.ProgramFile programFile = compiler.getExecutableProgram(entryPackageNode);
if (programFile != null) {
comResult.setProgFile(LauncherUtils.getExecutableProgram(programFile));
}
Diagnostic[] diagnostics = comResult.getDiagnostics();
return Arrays.stream(diagnostics).collect(Collectors.toList());
}
use of org.wso2.ballerinalang.compiler.Compiler 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.ballerinalang.compiler.Compiler in project ballerina by ballerina-lang.
the class CompilerPluginRunner method handleEndpointProcesses.
private void handleEndpointProcesses(CompilerPlugin plugin) {
// Get the list of endpoint of that this particular compiler plugin is interested in.
SupportEndpointTypes supportEndpointTypes = plugin.getClass().getAnnotation(SupportEndpointTypes.class);
if (supportEndpointTypes == null) {
return;
}
final SupportEndpointTypes.EndpointType[] endpointTypes = supportEndpointTypes.value();
if (endpointTypes.length == 0) {
return;
}
DefinitionID[] definitions = Arrays.stream(endpointTypes).map(endpointType -> new DefinitionID(endpointType.packageName(), endpointType.name())).toArray(DefinitionID[]::new);
for (DefinitionID definitionID : definitions) {
if (isValidEndpoints(definitionID, plugin)) {
List<CompilerPlugin> processorList = endpointProcessorMap.computeIfAbsent(definitionID, k -> new ArrayList<>());
processorList.add(plugin);
}
}
}
use of org.wso2.ballerinalang.compiler.Compiler in project ballerina by ballerina-lang.
the class CompilerDriver method compile.
// Private methods
private BLangPackage compile(BLangPackage bLangPackage) {
BLangPackage pkgNode = bLangPackage;
// "ballerina/built-in" packages is only the pre-known package by the Ballerina compiler. So load it first.
BLangPackage builtInPackage = loadBuiltInPackage();
if (this.stopCompilation(pkgNode, CompilerPhase.DEFINE)) {
return pkgNode;
}
pkgNode = define(pkgNode);
if (this.stopCompilation(pkgNode, CompilerPhase.TYPE_CHECK)) {
return pkgNode;
}
pkgNode = typeCheck(pkgNode);
if (this.stopCompilation(pkgNode, CompilerPhase.CODE_ANALYZE)) {
return pkgNode;
}
pkgNode = codeAnalyze(pkgNode);
if (this.stopCompilation(pkgNode, CompilerPhase.TAINT_ANALYZE)) {
return pkgNode;
}
pkgNode = taintAnalyze(pkgNode);
if (this.stopCompilation(pkgNode, CompilerPhase.COMPILER_PLUGIN)) {
return pkgNode;
}
pkgNode = annotationProcess(pkgNode);
if (this.stopCompilation(pkgNode, CompilerPhase.DESUGAR)) {
return pkgNode;
}
// TODO : Improve this.
desugar(builtInPackage);
return desugar(pkgNode);
}
use of org.wso2.ballerinalang.compiler.Compiler in project ballerina by ballerina-lang.
the class CommonUtil method prepareTempCompilerContext.
/**
* Prepare a new compiler context.
* @return {@link CompilerContext} Prepared compiler context
*/
public static CompilerContext prepareTempCompilerContext() {
CompilerContext context = new CompilerContext();
CompilerOptions options = CompilerOptions.getInstance(context);
options.put(PROJECT_DIR, "");
options.put(COMPILER_PHASE, CompilerPhase.DESUGAR.toString());
options.put(PRESERVE_WHITESPACE, "false");
context.put(SourceDirectory.class, new NullSourceDirectory());
return context;
}
Aggregations