-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
481 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
69 changes: 69 additions & 0 deletions
69
src/main/java/de/fraunhofer/aisec/cpg/frontends/python/DefinitionHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/* | ||
* Copyright (c) 2019, Fraunhofer AISEC. All rights reserved. | ||
* | ||
* $$$$$$\ $$$$$$$\ $$$$$$\ | ||
* $$ __$$\ $$ __$$\ $$ __$$\ | ||
* $$ / \__|$$ | $$ |$$ / \__| | ||
* $$ | $$$$$$$ |$$ |$$$$\ | ||
* $$ | $$ ____/ $$ |\_$$ | | ||
* $$ | $$\ $$ | $$ | $$ | | ||
* \$$$$$ |$$ | \$$$$$ | | ||
* \______/ \__| \______/ | ||
* | ||
*/ | ||
|
||
package de.fraunhofer.aisec.cpg.frontends.python; | ||
|
||
import de.fraunhofer.aisec.cpg.frontends.Handler; | ||
import de.fraunhofer.aisec.cpg.graph.CompoundStatement; | ||
import de.fraunhofer.aisec.cpg.graph.Declaration; | ||
import de.fraunhofer.aisec.cpg.graph.FunctionDeclaration; | ||
import de.fraunhofer.aisec.cpg.graph.NodeBuilder; | ||
import de.fraunhofer.aisec.cpg.graph.ParamVariableDeclaration; | ||
import de.fraunhofer.aisec.cpg.graph.Type; | ||
import io.github.oxisto.reticulated.ast.statement.Definition; | ||
import io.github.oxisto.reticulated.ast.statement.FunctionDefinition; | ||
import io.github.oxisto.reticulated.ast.statement.Parameter; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
/** Transforms python definitions into declarations. */ | ||
public class DefinitionHandler extends Handler<Declaration, Definition, PythonLanguageFrontend> { | ||
|
||
public DefinitionHandler(PythonLanguageFrontend lang) { | ||
super(Declaration::new, lang); | ||
|
||
this.map.put(FunctionDefinition.class, this::handleFunctionDefinition); | ||
} | ||
|
||
private Declaration handleFunctionDefinition(Definition def) { | ||
FunctionDefinition func = def.asFunctionDefinition(); | ||
|
||
FunctionDeclaration declaration = | ||
NodeBuilder.newFunctionDeclaration(func.getId().getName(), null); | ||
|
||
this.lang.getScopeManager().enterScope(declaration); | ||
|
||
// build parameters | ||
List<ParamVariableDeclaration> parameters = new ArrayList<>(); | ||
for (Parameter parameter : func.getParameterList()) { | ||
String name = parameter.getId().getName(); | ||
Type type = Type.UNKNOWN; | ||
|
||
// TODO: resolve parameter/type | ||
|
||
ParamVariableDeclaration param = NodeBuilder.newMethodParameterIn(name, type, false, null); | ||
parameters.add(param); | ||
} | ||
declaration.setParameters(parameters); | ||
|
||
// build function body | ||
CompoundStatement body = this.lang.getSuiteHandler().handle(func.getSuite()); | ||
|
||
declaration.setBody(body); | ||
|
||
this.lang.getScopeManager().leaveScope(declaration); | ||
|
||
return declaration; | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
src/main/java/de/fraunhofer/aisec/cpg/frontends/python/ExpressionHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Copyright (c) 2019, Fraunhofer AISEC. All rights reserved. | ||
* | ||
* $$$$$$\ $$$$$$$\ $$$$$$\ | ||
* $$ __$$\ $$ __$$\ $$ __$$\ | ||
* $$ / \__|$$ | $$ |$$ / \__| | ||
* $$ | $$$$$$$ |$$ |$$$$\ | ||
* $$ | $$ ____/ $$ |\_$$ | | ||
* $$ | $$\ $$ | $$ | $$ | | ||
* \$$$$$ |$$ | \$$$$$ | | ||
* \______/ \__| \______/ | ||
* | ||
*/ | ||
|
||
package de.fraunhofer.aisec.cpg.frontends.python; | ||
|
||
import de.fraunhofer.aisec.cpg.frontends.Handler; | ||
import de.fraunhofer.aisec.cpg.graph.CallExpression; | ||
import de.fraunhofer.aisec.cpg.graph.NodeBuilder; | ||
import io.github.oxisto.reticulated.ast.expression.Call; | ||
import io.github.oxisto.reticulated.ast.expression.Expression; | ||
import io.github.oxisto.reticulated.ast.expression.Identifier; | ||
|
||
public class ExpressionHandler | ||
extends Handler<de.fraunhofer.aisec.cpg.graph.Expression, Expression, PythonLanguageFrontend> { | ||
|
||
public ExpressionHandler(PythonLanguageFrontend lang) { | ||
super(de.fraunhofer.aisec.cpg.graph.Expression::new, lang); | ||
|
||
this.map.put(Call.class, this::handleCall); | ||
} | ||
|
||
private CallExpression handleCall(Expression expression) { | ||
Call call = expression.asCall(); | ||
|
||
Identifier id = call.getPrimary().asIdentifier(); | ||
|
||
String name = id.getName(); | ||
String fqn = name; | ||
|
||
CallExpression callExpression = NodeBuilder.newCallExpression(name, fqn, null); | ||
|
||
return callExpression; | ||
} | ||
} |
107 changes: 107 additions & 0 deletions
107
src/main/java/de/fraunhofer/aisec/cpg/frontends/python/PythonLanguageFrontend.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* | ||
* Copyright (c) 2019, Fraunhofer AISEC. All rights reserved. | ||
* | ||
* $$$$$$\ $$$$$$$\ $$$$$$\ | ||
* $$ __$$\ $$ __$$\ $$ __$$\ | ||
* $$ / \__|$$ | $$ |$$ / \__| | ||
* $$ | $$$$$$$ |$$ |$$$$\ | ||
* $$ | $$ ____/ $$ |\_$$ | | ||
* $$ | $$\ $$ | $$ | $$ | | ||
* \$$$$$ |$$ | \$$$$$ | | ||
* \______/ \__| \______/ | ||
* | ||
*/ | ||
|
||
package de.fraunhofer.aisec.cpg.frontends.python; | ||
|
||
import de.fraunhofer.aisec.cpg.TranslationConfiguration; | ||
import de.fraunhofer.aisec.cpg.frontends.LanguageFrontend; | ||
import de.fraunhofer.aisec.cpg.frontends.TranslationException; | ||
import de.fraunhofer.aisec.cpg.graph.Region; | ||
import de.fraunhofer.aisec.cpg.graph.TranslationUnitDeclaration; | ||
import io.github.oxisto.reticulated.ParserResult; | ||
import io.github.oxisto.reticulated.PythonParser; | ||
import io.github.oxisto.reticulated.ast.FileInput; | ||
import io.github.oxisto.reticulated.ast.statement.Definition; | ||
import io.github.oxisto.reticulated.ast.statement.Statement; | ||
import java.io.File; | ||
import org.checkerframework.checker.nullness.qual.NonNull; | ||
|
||
/** | ||
* The language frontend for translating python language into the graph. It uses antlr to parse the | ||
* actual source code into an AST. | ||
*/ | ||
public class PythonLanguageFrontend extends LanguageFrontend { | ||
|
||
private StatementHandler statementHandler = new StatementHandler(this); | ||
private StatementListHandler statementListHandler = new StatementListHandler(this); | ||
private DefinitionHandler definitionHandler = new DefinitionHandler(this); | ||
private SuiteHandler suiteHandler = new SuiteHandler(this); | ||
private ExpressionHandler expressionHandler = new ExpressionHandler(this); | ||
private SimpleStatementHandler simpleStatementHandler = new SimpleStatementHandler(this); | ||
|
||
public PythonLanguageFrontend(TranslationConfiguration config) { | ||
super(config, ""); | ||
} | ||
|
||
@Override | ||
public TranslationUnitDeclaration parse(File file) throws TranslationException { | ||
PythonParser app = new PythonParser(); | ||
ParserResult result = app.parse(file.getPath()); | ||
FileInput input = result.getRoot(); | ||
|
||
TranslationUnitDeclaration tu = new TranslationUnitDeclaration(); | ||
|
||
for (Statement ctx : input.getStatements()) { | ||
// now things get a little tricky, since python does not distinguish between statements and | ||
// declarations, but the python parser has an utility class called 'Definition' to distinguish | ||
// class and function definitions from other statements such as 'if' and 'for'. | ||
if (ctx instanceof Definition) { | ||
tu.add(definitionHandler.handle((Definition) ctx)); | ||
} | ||
|
||
// additionally, python allows statement on a global level, something we also do not allow, so | ||
// we need to put them into a virtual function | ||
|
||
} | ||
|
||
return tu; | ||
} | ||
|
||
@Override | ||
public <T> String getCodeFromRawNode(T astNode) { | ||
return null; | ||
} | ||
|
||
@Override | ||
public @NonNull <T> Region getRegionFromRawNode(T astNode) { | ||
return Region.UNKNOWN_REGION; | ||
} | ||
|
||
@Override | ||
public <S, T> void setComment(S s, T ctx) {} | ||
|
||
public StatementHandler getStatementHandler() { | ||
return statementHandler; | ||
} | ||
|
||
public DefinitionHandler getDefinitionHandler() { | ||
return definitionHandler; | ||
} | ||
|
||
public SuiteHandler getSuiteHandler() { | ||
return suiteHandler; | ||
} | ||
|
||
public StatementListHandler getStatementListHandler() { | ||
return statementListHandler; | ||
} | ||
|
||
public ExpressionHandler getExpressionHandler() { | ||
return expressionHandler; | ||
} | ||
|
||
public SimpleStatementHandler getSimpleStatementHandler() { | ||
return simpleStatementHandler; | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
src/main/java/de/fraunhofer/aisec/cpg/frontends/python/SimpleStatementHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* Copyright (c) 2019, Fraunhofer AISEC. All rights reserved. | ||
* | ||
* $$$$$$\ $$$$$$$\ $$$$$$\ | ||
* $$ __$$\ $$ __$$\ $$ __$$\ | ||
* $$ / \__|$$ | $$ |$$ / \__| | ||
* $$ | $$$$$$$ |$$ |$$$$\ | ||
* $$ | $$ ____/ $$ |\_$$ | | ||
* $$ | $$\ $$ | $$ | $$ | | ||
* \$$$$$ |$$ | \$$$$$ | | ||
* \______/ \__| \______/ | ||
* | ||
*/ | ||
|
||
package de.fraunhofer.aisec.cpg.frontends.python; | ||
|
||
import de.fraunhofer.aisec.cpg.frontends.Handler; | ||
import de.fraunhofer.aisec.cpg.graph.Statement; | ||
import io.github.oxisto.reticulated.ast.simple.ExpressionStatement; | ||
import io.github.oxisto.reticulated.ast.simple.SimpleStatement; | ||
|
||
public class SimpleStatementHandler | ||
extends Handler<Statement, SimpleStatement, PythonLanguageFrontend> { | ||
|
||
public SimpleStatementHandler(PythonLanguageFrontend lang) { | ||
super(Statement::new, lang); | ||
|
||
this.map.put(ExpressionStatement.class, this::handleExpressionStatement); | ||
} | ||
|
||
private Statement handleExpressionStatement(SimpleStatement simpleStatement) { | ||
ExpressionStatement expressionStatement = simpleStatement.asExpressionStatement(); | ||
|
||
// un-wrap it | ||
return this.lang.getExpressionHandler().handle(expressionStatement.getExpression()); | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
src/main/java/de/fraunhofer/aisec/cpg/frontends/python/StatementHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/* | ||
* Copyright (c) 2019, Fraunhofer AISEC. All rights reserved. | ||
* | ||
* $$$$$$\ $$$$$$$\ $$$$$$\ | ||
* $$ __$$\ $$ __$$\ $$ __$$\ | ||
* $$ / \__|$$ | $$ |$$ / \__| | ||
* $$ | $$$$$$$ |$$ |$$$$\ | ||
* $$ | $$ ____/ $$ |\_$$ | | ||
* $$ | $$\ $$ | $$ | $$ | | ||
* \$$$$$ |$$ | \$$$$$ | | ||
* \______/ \__| \______/ | ||
* | ||
*/ | ||
|
||
package de.fraunhofer.aisec.cpg.frontends.python; | ||
|
||
import de.fraunhofer.aisec.cpg.frontends.Handler; | ||
import io.github.oxisto.reticulated.ast.statement.Statement; | ||
|
||
public class StatementHandler | ||
extends Handler<de.fraunhofer.aisec.cpg.graph.Statement, Statement, PythonLanguageFrontend> { | ||
|
||
public StatementHandler(PythonLanguageFrontend lang) { | ||
super(de.fraunhofer.aisec.cpg.graph.Statement::new, lang); | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
src/main/java/de/fraunhofer/aisec/cpg/frontends/python/StatementListHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
/* | ||
* Copyright (c) 2019, Fraunhofer AISEC. All rights reserved. | ||
* | ||
* $$$$$$\ $$$$$$$\ $$$$$$\ | ||
* $$ __$$\ $$ __$$\ $$ __$$\ | ||
* $$ / \__|$$ | $$ |$$ / \__| | ||
* $$ | $$$$$$$ |$$ |$$$$\ | ||
* $$ | $$ ____/ $$ |\_$$ | | ||
* $$ | $$\ $$ | $$ | $$ | | ||
* \$$$$$ |$$ | \$$$$$ | | ||
* \______/ \__| \______/ | ||
* | ||
*/ | ||
|
||
package de.fraunhofer.aisec.cpg.frontends.python; | ||
|
||
import de.fraunhofer.aisec.cpg.frontends.Handler; | ||
import de.fraunhofer.aisec.cpg.graph.Statement; | ||
import io.github.oxisto.reticulated.ast.simple.SimpleStatement; | ||
import io.github.oxisto.reticulated.ast.statement.StatementList; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
public class StatementListHandler | ||
extends Handler<List<Statement>, StatementList, PythonLanguageFrontend> { | ||
|
||
public StatementListHandler(PythonLanguageFrontend lang) { | ||
super(ArrayList::new, lang); | ||
|
||
this.map.put(StatementList.class, this::handleStatementList); | ||
} | ||
|
||
private List<Statement> handleStatementList(StatementList statementList) { | ||
List<Statement> list = new ArrayList<>(); | ||
|
||
for (SimpleStatement node : statementList) { | ||
list.add(this.lang.getSimpleStatementHandler().handle(node)); | ||
} | ||
|
||
return list; | ||
} | ||
} |
Oops, something went wrong.