Skip to content

Commit

Permalink
Corrects region and code for case, default and compound statement of …
Browse files Browse the repository at this point in the history
…a switch (#711)

* Corrects region computation and code extraction for the adapted case, default and compound statements in java
* Check for existence of the cast expression token range before the access.
  • Loading branch information
konradweiss authored Feb 16, 2022
1 parent de517dd commit 716f905
Showing 1 changed file with 12 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -402,9 +402,8 @@ public de.fraunhofer.aisec.cpg.graph.statements.Statement handleCaseDefaultState
PhysicalLocation parentLocation = lang.getLocationFromRawNode(sEntry);

Optional<TokenRange> optionalTokenRange = sEntry.getTokenRange();
Pair<JavaToken, JavaToken> caseTokens = null;
Pair<JavaToken, JavaToken> caseTokens = new Pair<>(null, null);
if (optionalTokenRange.isEmpty()) {
caseTokens = new Pair<>(null, null);
log.error("Token for Region for Default case not available");
}

Expand All @@ -416,12 +415,11 @@ public de.fraunhofer.aisec.cpg.graph.statements.Statement handleCaseDefaultState
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());
new Pair<>(
getNextTokenWith("default", optionalTokenRange.get().getBegin()),
getNextTokenWith(":", optionalTokenRange.get().getBegin()));
}
DefaultStatement defaultStatement =
NodeBuilder.newDefaultStatement(getCodeBetweenTokens(caseTokens.a, caseTokens.b));
Expand All @@ -430,31 +428,28 @@ public de.fraunhofer.aisec.cpg.graph.statements.Statement handleCaseDefaultState
return defaultStatement;
}

if (optionalTokenRange.isPresent()) {
Optional<TokenRange> caseExprTokenRange = caseExpression.getTokenRange();
if (optionalTokenRange.isPresent() && caseExprTokenRange.isPresent()) {
// Compute region and code for self generated case statement to match the c++ versions
caseTokens =
getOuterTokensWithText(
"case", ":", optionalTokenRange.get().getBegin(), optionalTokenRange.get().getEnd());
new Pair<>(
getPreviousTokenWith("case", optionalTokenRange.get().getBegin()),
getNextTokenWith(":", caseExprTokenRange.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<JavaToken> optional = token.getPreviousToken();
while (token.getText().equals(text) && optional.isPresent()) {
while (!token.getText().equals(text) && optional.isPresent()) {
token = optional.get();
optional = token.getPreviousToken();
}
Expand All @@ -463,18 +458,13 @@ public JavaToken getPreviousTokenWith(String text, JavaToken token) {

public JavaToken getNextTokenWith(String text, JavaToken token) {
Optional<JavaToken> optional = token.getNextToken();
while (token.getText().equals(text) && optional.isPresent()) {
while (!token.getText().equals(text) && optional.isPresent()) {
token = optional.get();
optional = token.getNextToken();
}
return token;
}

public Pair<JavaToken, JavaToken> 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) {
Expand Down

0 comments on commit 716f905

Please sign in to comment.