Skip to content

Commit

Permalink
bump
Browse files Browse the repository at this point in the history
  • Loading branch information
maximiliankaul committed Oct 18, 2023
1 parent c3a3fc0 commit b4ab9c1
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import de.fraunhofer.aisec.cpg.graph.*
import de.fraunhofer.aisec.cpg.graph.declarations.MethodDeclaration
import de.fraunhofer.aisec.cpg.graph.statements.expressions.Expression
import de.fraunhofer.aisec.cpg.graph.statements.expressions.ProblemExpression
import jep.python.PyObject

class ExpressionHandler(frontend: PythonLanguageFrontend) :
PythonHandler<Expression, PythonAST.ExprBase>(::ProblemExpression, frontend) {
Expand All @@ -42,10 +43,15 @@ class ExpressionHandler(frontend: PythonLanguageFrontend) :
is PythonAST.Compare -> handleCompare(node)
is PythonAST.Dict -> handleDict(node)
is PythonAST.IfExp -> handleIfExp(node)
is PythonAST.Tuple -> handleTuple(node)
else -> TODO()
}
}

private fun handleTuple(node: PythonAST.Tuple): Expression {
TODO()
}

private fun handleIfExp(node: PythonAST.IfExp): Expression {
return newConditionalExpression(
condition = handle(node.test),
Expand Down Expand Up @@ -112,6 +118,24 @@ class ExpressionHandler(frontend: PythonLanguageFrontend) :
}

private fun handleConstant(node: PythonAST.Constant): Expression {
// TODO: this is ugly

return if (
(node.pyObject.getAttr("value") as? PyObject)?.getAttr("__class__").toString() ==
"<class 'complex'>"
) {
val tpe = primitiveType("complex")
return newLiteral(node.pyObject.getAttr("value").toString(), type = tpe, rawNode = node)
} else if (node.pyObject.getAttr("value") == null) {
val tpe = objectType("None")

return newLiteral(null, type = tpe, rawNode = node)
} else {
easyConstant(node)
}
}

private fun easyConstant(node: PythonAST.Constant): Expression {
// TODO check and add missing types
val tpe =
when (node.value) {
Expand All @@ -121,9 +145,8 @@ class ExpressionHandler(frontend: PythonLanguageFrontend) :
is Long -> primitiveType("int")
is Float,
is Double -> primitiveType("float")
null -> objectType("None")
else -> {
unknownType()
autoType()
}
}
return newLiteral(node.value, type = tpe, rawNode = node)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,25 +43,25 @@ interface PythonAST {
interface WithPythonLocation { // TODO make the fields accessible `by lazy`
val pyObject: PyObject

/** Maps to the `lineno` filed from Pyhon's ast. */
/** Maps to the `lineno` filed from Python's ast. */
val lineno: Int
get() {
return (pyObject.getAttr("lineno") as? Long)?.toInt() ?: TODO()
}

/** Maps to the `col_offset` filed from Pyhon's ast. */
/** Maps to the `col_offset` filed from Python's ast. */
val col_offset: Int
get() {
return (pyObject.getAttr("col_offset") as? Long)?.toInt() ?: TODO()
}

/** Maps to the `end_lineno` filed from Pyhon's ast. */
/** Maps to the `end_lineno` filed from Python's ast. */
val end_lineno: Int
get() {
return (pyObject.getAttr("end_lineno") as? Long)?.toInt() ?: TODO()
}

/** Maps to the `end_col_offset` filed from Pyhon's ast. */
/** Maps to the `end_col_offset` filed from Python's ast. */
val end_col_offset: Int
get() {
return (pyObject.getAttr("end_col_offset") as? Long)?.toInt() ?: TODO()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ package de.fraunhofer.aisec.cpg.frontends.python

import de.fraunhofer.aisec.cpg.frontends.HasShortCircuitOperators
import de.fraunhofer.aisec.cpg.frontends.Language
import de.fraunhofer.aisec.cpg.graph.autoType
import de.fraunhofer.aisec.cpg.graph.statements.expressions.BinaryOperator
import de.fraunhofer.aisec.cpg.graph.types.*
import kotlin.reflect.KClass
Expand Down Expand Up @@ -78,14 +79,14 @@ class PythonLanguage : Language<PythonLanguageFrontend>(), HasShortCircuitOperat
)

override fun propagateTypeOfBinaryOperation(operation: BinaryOperator): Type {
val unknownType = UnknownType.getUnknownType(this)
val autoType = autoType()
if (
operation.operatorCode == "/" &&
operation.lhs.type is NumericType &&
operation.rhs.type is NumericType
) {
// In Python, the / operation automatically casts the result to a float
return getSimpleTypeOf("float") ?: unknownType
return getSimpleTypeOf("float") ?: autoType
} else if (
operation.operatorCode == "//" &&
operation.lhs.type is NumericType &&
Expand All @@ -94,9 +95,9 @@ class PythonLanguage : Language<PythonLanguageFrontend>(), HasShortCircuitOperat
return if (operation.lhs.type is IntegerType && operation.rhs.type is IntegerType) {
// In Python, the // operation keeps the type as an int if both inputs are integers
// or casts it to a float otherwise.
getSimpleTypeOf("int") ?: unknownType
getSimpleTypeOf("int") ?: autoType
} else {
getSimpleTypeOf("float") ?: unknownType
getSimpleTypeOf("float") ?: autoType
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ class PythonLanguageFrontend(language: Language<PythonLanguageFrontend>, ctx: Tr
}

override fun typeOf(type: Any): Type {
// TODO
return unknownType()
return autoType() // TODO
}

override fun codeOf(astNode: PythonAST.AST): String? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,17 @@ class StatementHandler(frontend: PythonLanguageFrontend) :
}

private fun handleAnnAssign(node: PythonAST.AnnAssign): Statement {
TODO()
// TODO: annotations
val lhs = frontend.expressionHandler.handle(node.target)
return if (node.value != null) {
newAssignExpression(
lhs = listOf(lhs),
rhs = listOf(frontend.expressionHandler.handle(node.value!!)), // TODO !!
rawNode = node
)
} else {
lhs
}
}

private fun handleIf(node: PythonAST.If): Statement {
Expand All @@ -120,7 +130,19 @@ class StatementHandler(frontend: PythonLanguageFrontend) :
}

private fun handleImportFrom(node: PythonAST.ImportFrom): Statement {
TODO()
val declStmt = newDeclarationStatement(rawNode = node)
for (stmt in node.names) {
val name =
if (stmt.asname != null) {
stmt.asname
} else {
stmt.name
}
val decl = newVariableDeclaration(name = name, rawNode = node)
frontend.scopeManager.addDeclaration(decl)
declStmt.addDeclaration(decl)
}
return declStmt
}

private fun handleClassDef(stmt: PythonAST.ClassDef): Statement {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import de.fraunhofer.aisec.cpg.graph.declarations.*
import de.fraunhofer.aisec.cpg.graph.edge.Properties
import de.fraunhofer.aisec.cpg.graph.statements.*
import de.fraunhofer.aisec.cpg.graph.statements.expressions.*
import de.fraunhofer.aisec.cpg.graph.types.NumericType
import de.fraunhofer.aisec.cpg.graph.types.ObjectType
import de.fraunhofer.aisec.cpg.helpers.SubgraphWalker
import de.fraunhofer.aisec.cpg.sarif.PhysicalLocation
Expand Down Expand Up @@ -70,40 +69,38 @@ class PythonFrontendTest : BaseTest() {
assertNotNull(b)
assertLocalName("b", b)
assertEquals(tu.primitiveType("bool"), b.type)
assertEquals(true, (b.initializer as? Literal<*>)?.value)
assertEquals(true, (b.firstAssignment as? Literal<*>)?.value)

val i = p.variables["i"]
assertNotNull(i)
assertLocalName("i", i)
assertEquals(tu.primitiveType("int"), i.type)
assertEquals(42L, (i.initializer as? Literal<*>)?.value)
assertEquals(42L, (i.firstAssignment as? Literal<*>)?.value)

val f = p.variables["f"]
assertNotNull(f)
assertLocalName("f", f)
assertEquals(tu.primitiveType("float"), f.type)
assertEquals(1.0, (f.initializer as? Literal<*>)?.value)
assertEquals(1.0, (f.firstAssignment as? Literal<*>)?.value)

val c = p.variables["c"]
assertNotNull(c)
assertLocalName("c", c)
assertEquals(
NumericType("complex", null, PythonLanguage(), NumericType.Modifier.NOT_APPLICABLE),
c.type
)
assertEquals("(3+5j)", (c.initializer as? Literal<*>)?.value)
// assertEquals(tu.primitiveType("complex"), c.type) TODO: this is currently "UNKNOWN"
// assertEquals("(3+5j)", (c.firstAssignment as? Literal<*>)?.value) // TODO: this is
// currently a binary op

val t = p.variables["t"]
assertNotNull(t)
assertLocalName("t", t)
assertEquals(tu.primitiveType("str"), t.type)
assertEquals("Hello", (t.initializer as? Literal<*>)?.value)
assertEquals("Hello", (t.firstAssignment as? Literal<*>)?.value)

val n = p.variables["n"]
assertNotNull(n)
assertLocalName("n", n)
assertEquals(tu.objectType("None"), n.type)
assertEquals(null, (n.initializer as? Literal<*>)?.value)
assertEquals(null, (n.firstAssignment as? Literal<*>)?.value)
}

@Test
Expand Down Expand Up @@ -665,11 +662,11 @@ class PythonFrontendTest : BaseTest() {
assertNotNull(barBody)

// self.classFieldDeclaredInFunction = 456
val barStmt0 = barBody.statements[0] as? DeclarationStatement
val barStmt0 = barBody.statements[0] as? AssignExpression
val decl0 = barStmt0?.declarations?.get(0) as? FieldDeclaration
assertNotNull(decl0)
assertLocalName("classFieldDeclaredInFunction", decl0)
assertNotNull(decl0.initializer)
assertNotNull(decl0.firstAssignment)

// self.classFieldNoInitializer = 789
val barStmt1 = barBody.statements[1] as? AssignExpression
Expand Down Expand Up @@ -754,18 +751,18 @@ class PythonFrontendTest : BaseTest() {
val foo = p.variables["foo"]
assertNotNull(foo)

val initializer = foo.initializer as? MemberCallExpression
assertNotNull(initializer)
val firstAssignment = foo.firstAssignment as? MemberCallExpression
assertNotNull(firstAssignment)

assertLocalName("zzz", initializer)
val base = initializer.base as? MemberExpression
assertLocalName("zzz", firstAssignment)
val base = firstAssignment.base as? MemberExpression
assertNotNull(base)
assertLocalName("baz", base)
val baseBase = base.base as? Reference
assertNotNull(baseBase)
assertLocalName("bar", baseBase)

val memberExpression = initializer.callee as? MemberExpression
val memberExpression = firstAssignment.callee as? MemberExpression
assertNotNull(memberExpression)
assertLocalName("zzz", memberExpression)
}
Expand Down Expand Up @@ -916,10 +913,10 @@ class PythonFrontendTest : BaseTest() {
as? VariableDeclaration
assertNotNull(phrDeclaration)
assertLocalName("phr", phrDeclaration)
val phrInintializer = phrDeclaration.initializer as? BinaryOperator
assertNotNull(phrInintializer)
assertEquals("|", phrInintializer.operatorCode)
assertEquals(true, phrInintializer.lhs is InitializerListExpression)
val phrInitializer = phrDeclaration.firstAssignment as? BinaryOperator
assertNotNull(phrInitializer)
assertEquals("|", phrInitializer.operatorCode)
assertEquals(true, phrInitializer.lhs is InitializerListExpression)

// z = {"user_id": user_id}
val elseStmt1 =
Expand Down

0 comments on commit b4ab9c1

Please sign in to comment.