de.fraunhofer.aisec.cpg.frontends.java.StatementAnalyzer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cpg Show documentation
Show all versions of cpg Show documentation
A simple library to extract a code property graph out of source code. It has support for multiple passes that can extend the analysis after the graph is constructed.
/*
* Copyright (c) 2019, Fraunhofer AISEC. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $$$$$$\ $$$$$$$\ $$$$$$\
* $$ __$$\ $$ __$$\ $$ __$$\
* $$ / \__|$$ | $$ |$$ / \__|
* $$ | $$$$$$$ |$$ |$$$$\
* $$ | $$ ____/ $$ |\_$$ |
* $$ | $$\ $$ | $$ | $$ |
* \$$$$$ |$$ | \$$$$$ |
* \______/ \__| \______/
*
*/
package de.fraunhofer.aisec.cpg.frontends.java;
import com.github.javaparser.JavaToken;
import com.github.javaparser.Range;
import com.github.javaparser.TokenRange;
import com.github.javaparser.ast.stmt.AssertStmt;
import com.github.javaparser.ast.stmt.BlockStmt;
import com.github.javaparser.ast.stmt.BreakStmt;
import com.github.javaparser.ast.stmt.ContinueStmt;
import com.github.javaparser.ast.stmt.DoStmt;
import com.github.javaparser.ast.stmt.EmptyStmt;
import com.github.javaparser.ast.stmt.ExplicitConstructorInvocationStmt;
import com.github.javaparser.ast.stmt.ExpressionStmt;
import com.github.javaparser.ast.stmt.ForEachStmt;
import com.github.javaparser.ast.stmt.ForStmt;
import com.github.javaparser.ast.stmt.IfStmt;
import com.github.javaparser.ast.stmt.LabeledStmt;
import com.github.javaparser.ast.stmt.ReturnStmt;
import com.github.javaparser.ast.stmt.Statement;
import com.github.javaparser.ast.stmt.SwitchEntry;
import com.github.javaparser.ast.stmt.SwitchStmt;
import com.github.javaparser.ast.stmt.SynchronizedStmt;
import com.github.javaparser.ast.stmt.ThrowStmt;
import com.github.javaparser.ast.stmt.TryStmt;
import com.github.javaparser.ast.stmt.WhileStmt;
import com.github.javaparser.ast.type.ReferenceType;
import com.github.javaparser.ast.type.UnionType;
import com.github.javaparser.utils.Pair;
import de.fraunhofer.aisec.cpg.frontends.Handler;
import de.fraunhofer.aisec.cpg.graph.AssertStatement;
import de.fraunhofer.aisec.cpg.graph.BreakStatement;
import de.fraunhofer.aisec.cpg.graph.CaseStatement;
import de.fraunhofer.aisec.cpg.graph.CatchClause;
import de.fraunhofer.aisec.cpg.graph.CompoundStatement;
import de.fraunhofer.aisec.cpg.graph.ContinueStatement;
import de.fraunhofer.aisec.cpg.graph.Declaration;
import de.fraunhofer.aisec.cpg.graph.DeclarationStatement;
import de.fraunhofer.aisec.cpg.graph.DefaultStatement;
import de.fraunhofer.aisec.cpg.graph.DoStatement;
import de.fraunhofer.aisec.cpg.graph.EmptyStatement;
import de.fraunhofer.aisec.cpg.graph.ExplicitConstructorInvocation;
import de.fraunhofer.aisec.cpg.graph.Expression;
import de.fraunhofer.aisec.cpg.graph.ExpressionList;
import de.fraunhofer.aisec.cpg.graph.ForEachStatement;
import de.fraunhofer.aisec.cpg.graph.ForStatement;
import de.fraunhofer.aisec.cpg.graph.IfStatement;
import de.fraunhofer.aisec.cpg.graph.LabelStatement;
import de.fraunhofer.aisec.cpg.graph.Literal;
import de.fraunhofer.aisec.cpg.graph.NodeBuilder;
import de.fraunhofer.aisec.cpg.graph.ReturnStatement;
import de.fraunhofer.aisec.cpg.graph.SwitchStatement;
import de.fraunhofer.aisec.cpg.graph.SynchronizedStatement;
import de.fraunhofer.aisec.cpg.graph.TryStatement;
import de.fraunhofer.aisec.cpg.graph.Type;
import de.fraunhofer.aisec.cpg.graph.UnaryOperator;
import de.fraunhofer.aisec.cpg.graph.VariableDeclaration;
import de.fraunhofer.aisec.cpg.graph.WhileStatement;
import de.fraunhofer.aisec.cpg.sarif.PhysicalLocation;
import de.fraunhofer.aisec.cpg.sarif.Region;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class StatementAnalyzer
extends Handler {
private static final Logger log = LoggerFactory.getLogger(StatementAnalyzer.class);
public StatementAnalyzer(JavaLanguageFrontend lang) {
super(de.fraunhofer.aisec.cpg.graph.Statement::new, lang);
map.put(IfStmt.class, this::handleIfStatement);
map.put(AssertStmt.class, this::handleAssertStatement);
map.put(WhileStmt.class, this::handleWhileStatement);
map.put(DoStmt.class, this::handleDoStatement);
map.put(ForEachStmt.class, this::handleForEachStatement);
map.put(ForStmt.class, this::handleForStatement);
map.put(BreakStmt.class, this::handleBreakStatement);
map.put(ContinueStmt.class, this::handleContinueStatement);
map.put(ReturnStmt.class, this::handleReturnStatement);
map.put(BlockStmt.class, this::handleBlockStatement);
map.put(LabeledStmt.class, this::handleLabelStatement);
map.put(ExplicitConstructorInvocationStmt.class, this::handleExplicitConstructorInvocation);
map.put(ExpressionStmt.class, this::handleExpressionStatement);
map.put(SwitchStmt.class, this::handleSwitchStatement);
map.put(EmptyStmt.class, this::handleEmptyStatement);
map.put(SynchronizedStmt.class, this::handleSynchronizedStatement);
map.put(TryStmt.class, this::handleTryStatement);
map.put(ThrowStmt.class, this::handleThrowStmt);
}
public de.fraunhofer.aisec.cpg.graph.Statement handleExpressionStatement(Statement stmt) {
return lang.getExpressionHandler().handle(stmt.asExpressionStmt().getExpression());
}
private de.fraunhofer.aisec.cpg.graph.Statement handleThrowStmt(Statement stmt) {
ThrowStmt throwStmt = (ThrowStmt) stmt;
UnaryOperator throwOperation =
NodeBuilder.newUnaryOperator("throw", false, true, throwStmt.toString());
throwOperation.setInput(
(Expression) lang.getExpressionHandler().handle(throwStmt.getExpression()));
return throwOperation;
}
private ReturnStatement handleReturnStatement(Statement stmt) {
ReturnStmt returnStmt = stmt.asReturnStmt();
Optional optionalExpression =
returnStmt.getExpression();
de.fraunhofer.aisec.cpg.graph.Expression expression = null;
if (optionalExpression.isPresent()) {
com.github.javaparser.ast.expr.Expression expr = optionalExpression.get();
// handle the expression as the first argument
expression = (Expression) lang.getExpressionHandler().handle(expr);
}
ReturnStatement returnStatement = NodeBuilder.newReturnStatement(returnStmt.toString());
// expressionRefersToDeclaration to arguments, if there are any
if (expression != null) {
returnStatement.setReturnValue(expression);
}
lang.setCodeAndRegion(returnStatement, stmt);
return returnStatement;
}
private IfStatement handleIfStatement(Statement stmt) {
IfStmt ifStmt = stmt.asIfStmt();
com.github.javaparser.ast.expr.Expression conditionExpression = ifStmt.getCondition();
Statement thenStatement = ifStmt.getThenStmt();
Optional optionalElseStatement = ifStmt.getElseStmt();
IfStatement ifStatement = NodeBuilder.newIfStatement(ifStmt.toString());
lang.getScopeManager().enterScope(ifStatement);
ifStatement.setThenStatement(handle(thenStatement));
ifStatement.setCondition(
(de.fraunhofer.aisec.cpg.graph.Expression)
lang.getExpressionHandler().handle(conditionExpression));
optionalElseStatement.ifPresent(statement -> ifStatement.setElseStatement(handle(statement)));
lang.getScopeManager().leaveScope(ifStatement);
return ifStatement;
}
private AssertStatement handleAssertStatement(Statement stmt) {
AssertStmt assertStmt = stmt.asAssertStmt();
com.github.javaparser.ast.expr.Expression conditionExpression = assertStmt.getCheck();
Optional thenStatement = assertStmt.getMessage();
AssertStatement assertStatement = NodeBuilder.newAssertStatement(stmt.toString());
assertStatement.setCondition(
(de.fraunhofer.aisec.cpg.graph.Expression)
lang.getExpressionHandler().handle(conditionExpression));
thenStatement.ifPresent(
statement ->
assertStatement.setMessage(lang.getExpressionHandler().handle(thenStatement.get())));
return assertStatement;
}
private WhileStatement handleWhileStatement(Statement stmt) {
WhileStmt whileStmt = stmt.asWhileStmt();
com.github.javaparser.ast.expr.Expression conditionExpression = whileStmt.getCondition();
Statement statement = whileStmt.getBody();
WhileStatement whileStatement = NodeBuilder.newWhileStatement(whileStmt.toString());
lang.getScopeManager().enterScope(whileStatement);
whileStatement.setStatement(handle(statement));
whileStatement.setCondition(
(de.fraunhofer.aisec.cpg.graph.Expression)
lang.getExpressionHandler().handle(conditionExpression));
lang.getScopeManager().leaveScope(whileStatement);
return whileStatement;
}
private ForEachStatement handleForEachStatement(Statement stmt) {
ForEachStatement statement = NodeBuilder.newForEachStatement(stmt.toString());
lang.getScopeManager().enterScope(statement);
ForEachStmt forEachStmt = stmt.asForEachStmt();
de.fraunhofer.aisec.cpg.graph.Statement var =
lang.getExpressionHandler().handle(forEachStmt.getVariable());
de.fraunhofer.aisec.cpg.graph.Statement iterable =
lang.getExpressionHandler().handle(forEachStmt.getIterable());
if (!(var instanceof DeclarationStatement
&& ((DeclarationStatement) var).isSingleDeclaration())) {
log.error("more or unknown decl in foreach");
} else {
statement.setVariable(((DeclarationStatement) var).getSingleDeclaration());
}
statement.setIterable(iterable);
statement.setStatement(handle(forEachStmt.getBody()));
lang.getScopeManager().leaveScope(statement);
return statement;
}
private ForStatement handleForStatement(Statement stmt) {
ForStmt forStmt = stmt.asForStmt();
String code;
Optional tokenRange = forStmt.getTokenRange();
if (tokenRange.isPresent()) {
code = tokenRange.get().toString();
} else {
code = stmt.toString();
}
ForStatement statement = NodeBuilder.newForStatement(code);
lang.setCodeAndRegion(statement, stmt);
lang.getScopeManager().enterScope(statement);
if (forStmt.getInitialization().size() > 1) {
PhysicalLocation ofExprList = null;
// code will be set later
ExpressionList initExprList = NodeBuilder.newExpressionList(null);
for (com.github.javaparser.ast.expr.Expression initExpr : forStmt.getInitialization()) {
de.fraunhofer.aisec.cpg.graph.Statement s = lang.getExpressionHandler().handle(initExpr);
// make sure location is set
lang.setCodeAndRegion(s, initExpr);
initExprList.addExpression(s);
// can not update location
if (s.getLocation() == null) {
continue;
}
if (ofExprList == null) {
ofExprList = s.getLocation();
}
ofExprList.setRegion(
lang.mergeRegions(ofExprList.getRegion(), s.getLocation().getRegion()));
}
// set code and location of init list
if (statement.getLocation() != null && ofExprList != null) {
String initCode =
lang.getCodeOfSubregion(
statement, statement.getLocation().getRegion(), ofExprList.getRegion());
initExprList.setLocation(ofExprList);
initExprList.setCode(initCode);
}
statement.setInitializerStatement(initExprList);
} else if (forStmt.getInitialization().size() == 1) {
statement.setInitializerStatement(
lang.getExpressionHandler().handle(forStmt.getInitialization().get(0)));
}
forStmt
.getCompare()
.ifPresent(
condition ->
statement.setCondition((Expression) lang.getExpressionHandler().handle(condition)));
// Adds true expression node where default empty condition evaluates to true, remove here and in
// cpp StatementHandler
if (statement.getCondition() == null) {
Literal literal = NodeBuilder.newLiteral(true, new Type("boolean"), "true");
statement.setCondition(literal);
}
if (forStmt.getUpdate().size() > 1) {
PhysicalLocation ofExprList = statement.getLocation();
// code will be set later
ExpressionList iterationExprList = NodeBuilder.newExpressionList(null);
for (com.github.javaparser.ast.expr.Expression updateExpr : forStmt.getUpdate()) {
de.fraunhofer.aisec.cpg.graph.Statement s = lang.getExpressionHandler().handle(updateExpr);
// make sure location is set
lang.setCodeAndRegion(s, updateExpr);
iterationExprList.addExpression(s);
// can not update location
if (s.getLocation() == null) {
continue;
}
if (ofExprList == null) {
ofExprList = s.getLocation();
}
ofExprList.setRegion(
lang.mergeRegions(ofExprList.getRegion(), s.getLocation().getRegion()));
}
// set code and location of init list
if (statement.getLocation() != null && ofExprList != null) {
String updateCode =
lang.getCodeOfSubregion(
statement, statement.getLocation().getRegion(), ofExprList.getRegion());
iterationExprList.setLocation(ofExprList);
iterationExprList.setCode(updateCode);
}
statement.setIterationExpression(iterationExprList);
} else if (forStmt.getUpdate().size() == 1) {
statement.setIterationExpression(
(Expression) lang.getExpressionHandler().handle(forStmt.getUpdate().get(0)));
}
statement.setStatement(handle(forStmt.getBody()));
lang.getScopeManager().leaveScope(statement);
return statement;
}
private DoStatement handleDoStatement(Statement stmt) {
DoStmt doStmt = stmt.asDoStmt();
com.github.javaparser.ast.expr.Expression conditionExpression = doStmt.getCondition();
Statement statement = doStmt.getBody();
DoStatement doStatement = NodeBuilder.newDoStatement(doStmt.toString());
lang.getScopeManager().enterScope(doStatement);
doStatement.setStatement(handle(statement));
doStatement.setCondition(
(de.fraunhofer.aisec.cpg.graph.Expression)
lang.getExpressionHandler().handle(conditionExpression));
lang.getScopeManager().leaveScope(doStatement);
return doStatement;
}
private EmptyStatement handleEmptyStatement(Statement stmt) {
EmptyStmt emptyStmt = stmt.asEmptyStmt();
return NodeBuilder.newEmptyStatement(emptyStmt.toString());
}
private SynchronizedStatement handleSynchronizedStatement(Statement stmt) {
SynchronizedStmt synchronizedJava = stmt.asSynchronizedStmt();
SynchronizedStatement synchronizedCPG = NodeBuilder.newSynchronizedStatement(stmt.toString());
synchronizedCPG.setExpression(
(Expression) lang.getExpressionHandler().handle(synchronizedJava.getExpression()));
synchronizedCPG.setBlockStatement((CompoundStatement) handle(synchronizedJava.getBody()));
return synchronizedCPG;
}
private LabelStatement handleLabelStatement(Statement stmt) {
LabeledStmt labelStmt = stmt.asLabeledStmt();
String label = labelStmt.getLabel().getIdentifier();
Statement statement = labelStmt.getStatement();
LabelStatement labelStatement = NodeBuilder.newLabelStatement(labelStmt.toString());
labelStatement.setSubStatement(handle(statement));
labelStatement.setLabel(label);
return labelStatement;
}
private BreakStatement handleBreakStatement(Statement stmt) {
BreakStmt breakStmt = stmt.asBreakStmt();
BreakStatement breakStatement = new BreakStatement();
breakStmt.getLabel().ifPresent(label -> breakStatement.setLabel(label.toString()));
return breakStatement;
}
private ContinueStatement handleContinueStatement(Statement stmt) {
ContinueStmt continueStmt = stmt.asContinueStmt();
ContinueStatement continueStatement = new ContinueStatement();
continueStmt.getLabel().ifPresent(label -> continueStatement.setLabel(label.toString()));
return continueStatement;
}
public CompoundStatement handleBlockStatement(Statement stmt) {
BlockStmt blockStmt = stmt.asBlockStmt();
// first of, all we need a compound statement
CompoundStatement compoundStatement = NodeBuilder.newCompoundStatement(stmt.toString());
lang.getScopeManager().enterScope(compoundStatement);
for (Statement child : blockStmt.getStatements()) {
de.fraunhofer.aisec.cpg.graph.Statement statement = handle(child);
compoundStatement.getStatements().add(statement);
}
lang.setCodeAndRegion(compoundStatement, stmt);
lang.getScopeManager().leaveScope(compoundStatement);
return compoundStatement;
}
public de.fraunhofer.aisec.cpg.graph.Statement handleCaseDefaultStatement(
com.github.javaparser.ast.expr.Expression caseExpression, SwitchEntry sEntry) {
PhysicalLocation parentLocation = lang.getLocationFromRawNode(sEntry);
Optional optionalTokenRange = sEntry.getTokenRange();
Pair caseTokens = null;
if (optionalTokenRange.isEmpty()) {
caseTokens = new Pair<>(null, null);
log.error("Token for Region for Default case not available");
}
if (caseExpression == null) {
if (optionalTokenRange.isPresent()) {
/*
TODO: not sure if this is really necessary, it seems to be the same location as
parentLocation, except that column starts 1 character later and I am not sure if
this is correct anyway
*/
// Compute region and code for self generated default statement to match the c++ versions
caseTokens =
getOuterTokensWithText(
"default",
":",
optionalTokenRange.get().getBegin(),
optionalTokenRange.get().getEnd());
}
DefaultStatement defaultStatement =
NodeBuilder.newDefaultStatement(getCodeBetweenTokens(caseTokens.a, caseTokens.b));
defaultStatement.setLocation(
getLocationsFromTokens(parentLocation, caseTokens.a, caseTokens.b));
return defaultStatement;
}
if (optionalTokenRange.isPresent()) {
// Compute region and code for self generated case statement to match the c++ versions
caseTokens =
getOuterTokensWithText(
"case", ":", optionalTokenRange.get().getBegin(), optionalTokenRange.get().getEnd());
}
CaseStatement caseStatement =
NodeBuilder.newCaseStatement(getCodeBetweenTokens(caseTokens.a, caseTokens.b));
caseStatement.setCaseExpression(
(Expression) lang.getExpressionHandler().handle(caseExpression));
/*
TODO: not sure if this is really necessary, it seems to be the same location as
parentLocation, except that column starts 1 character later and I am not sure if
this is correct anyway
*/
caseStatement.setLocation(getLocationsFromTokens(parentLocation, caseTokens.a, caseTokens.b));
return caseStatement;
}
public JavaToken getPreviousTokenWith(String text, JavaToken token) {
Optional optional = token.getPreviousToken();
while (token.getText().equals(text) && optional.isPresent()) {
token = optional.get();
optional = token.getPreviousToken();
}
return token;
}
public JavaToken getNextTokenWith(String text, JavaToken token) {
Optional optional = token.getNextToken();
while (token.getText().equals(text) && optional.isPresent()) {
token = optional.get();
optional = token.getNextToken();
}
return token;
}
public Pair getOuterTokensWithText(
String startDelim, String endDelim, JavaToken start, JavaToken end) {
return new Pair<>(getPreviousTokenWith(startDelim, start), getNextTokenWith(endDelim, end));
}
@Nullable
public PhysicalLocation getLocationsFromTokens(
PhysicalLocation parentLocation, JavaToken startToken, JavaToken endToken) {
// cannot construct location without parent location
if (parentLocation == null) {
return null;
}
if (startToken != null && endToken != null) {
Optional startOpt = startToken.getRange();
Optional endOpt = endToken.getRange();
if (startOpt.isPresent() && endOpt.isPresent()) {
Range rstart = startOpt.get();
Range rend = endOpt.get();
Region region =
new Region(rstart.begin.line, rstart.begin.column, rend.end.line, rend.end.column + 1);
return new PhysicalLocation(parentLocation.getArtifactLocation().getUri(), region);
}
}
return null;
}
public String getCodeBetweenTokens(JavaToken startToken, JavaToken endToken) {
if (startToken == null || endToken == null) {
return Type.UNKNOWN_TYPE_STRING;
}
StringBuilder newCode = new StringBuilder(startToken.getText());
JavaToken current = startToken;
do {
current = current.getNextToken().orElse(null);
if (current == null) {
break;
}
newCode.append(current.getText());
} while (current != endToken);
return newCode.toString();
}
public SwitchStatement handleSwitchStatement(Statement stmt) {
SwitchStmt switchStmt = stmt.asSwitchStmt();
SwitchStatement switchStatement = NodeBuilder.newSwitchStatement(stmt.toString());
// make sure location is set
lang.setCodeAndRegion(switchStatement, switchStmt);
lang.getScopeManager().enterScope(switchStatement);
switchStatement.setSelector(
(Expression) lang.getExpressionHandler().handle(switchStmt.getSelector()));
// Compute region and code for self generated compound statement to match the c++ versions
JavaToken start = null;
JavaToken end = null;
Optional tokenRange = switchStmt.getTokenRange();
Optional tokenRangeSelector = switchStmt.getSelector().getTokenRange();
if (tokenRange.isPresent() && tokenRangeSelector.isPresent()) {
start = getNextTokenWith("{", tokenRangeSelector.get().getEnd());
end = getPreviousTokenWith("}", tokenRange.get().getEnd());
}
CompoundStatement compoundStatement =
NodeBuilder.newCompoundStatement(getCodeBetweenTokens(start, end));
compoundStatement.setLocation(
getLocationsFromTokens(switchStatement.getLocation(), start, end));
for (SwitchEntry sentry : switchStmt.getEntries()) {
if (sentry.getLabels().isEmpty()) {
compoundStatement.getStatements().add(handleCaseDefaultStatement(null, sentry));
}
for (com.github.javaparser.ast.expr.Expression caseExp : sentry.getLabels()) {
compoundStatement.getStatements().add(handleCaseDefaultStatement(caseExp, sentry));
}
for (Statement subStmt : sentry.getStatements()) {
compoundStatement.getStatements().add(handle(subStmt));
}
}
switchStatement.setStatement(compoundStatement);
lang.getScopeManager().leaveScope(switchStatement);
return switchStatement;
}
private ExplicitConstructorInvocation handleExplicitConstructorInvocation(Statement stmt) {
ExplicitConstructorInvocationStmt eciStatement = stmt.asExplicitConstructorInvocationStmt();
String containingClass;
try {
containingClass = eciStatement.resolve().declaringType().getQualifiedName();
} catch (RuntimeException | NoClassDefFoundError e) {
containingClass = lang.recoverTypeFromUnsolvedException(e);
// base can be null here
}
ExplicitConstructorInvocation node =
NodeBuilder.newExplicitConstructorInvocation(containingClass, eciStatement.toString());
List arguments =
eciStatement.getArguments().stream()
.map(lang.getExpressionHandler()::handle)
.map(Expression.class::cast)
.collect(Collectors.toList());
node.setArguments(arguments);
return node;
}
private TryStatement handleTryStatement(Statement stmt) {
TryStmt tryStmt = stmt.asTryStmt();
TryStatement tryStatement = NodeBuilder.newTryStatement(stmt.toString());
lang.getScopeManager().enterScope(tryStatement);
List resources =
tryStmt.getResources().stream()
.map(lang.getExpressionHandler()::handle)
.collect(Collectors.toList());
CompoundStatement tryBlock = handleBlockStatement(tryStmt.getTryBlock());
List catchClauses =
tryStmt.getCatchClauses().stream()
.map(this::handleCatchClause)
.collect(Collectors.toList());
CompoundStatement finallyBlock =
tryStmt.getFinallyBlock().map(this::handleBlockStatement).orElse(null);
lang.getScopeManager().leaveScope(tryStatement);
tryStatement.setResources(resources);
tryStatement.setTryBlock(tryBlock);
tryStatement.setFinallyBlock(finallyBlock);
tryStatement.setCatchClauses(catchClauses);
for (de.fraunhofer.aisec.cpg.graph.Statement r : resources) {
if (r instanceof DeclarationStatement) {
for (Declaration d : ((DeclarationStatement) r).getDeclarations()) {
if (d instanceof VariableDeclaration) {
lang.getScopeManager().addValueDeclaration((VariableDeclaration) d);
}
}
}
}
return tryStatement;
}
private CatchClause handleCatchClause(com.github.javaparser.ast.stmt.CatchClause catchCls) {
CatchClause cClause = NodeBuilder.newCatchClause(catchCls.toString());
lang.getScopeManager().enterScope(cClause);
HashSet possibleTypes = new HashSet<>();
Type concreteType;
if (catchCls.getParameter().getType() instanceof UnionType) {
for (ReferenceType t : ((UnionType) catchCls.getParameter().getType()).getElements()) {
possibleTypes.add(lang.getTypeAsGoodAsPossible(t));
}
// we do not know which of the exceptions was actually thrown, so we assume this might be any
concreteType = new Type("java.lang.Throwable", Type.Origin.GUESSED);
} else {
concreteType = lang.getTypeAsGoodAsPossible(catchCls.getParameter().getType());
possibleTypes.add(concreteType);
}
VariableDeclaration parameter =
NodeBuilder.newVariableDeclaration(
catchCls.getParameter().getName().toString(),
concreteType,
catchCls.getParameter().toString());
parameter.setPossibleSubTypes(possibleTypes);
CompoundStatement body = handleBlockStatement(catchCls.getBody());
cClause.setBody(body);
cClause.setParameter(parameter);
lang.getScopeManager().addValueDeclaration(parameter);
lang.getScopeManager().leaveScope(cClause);
return cClause;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy