Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nullable properties #172

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/main/kotlin/astminer/common/model/FunctionInfoModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ interface FunctionInfo<T : Node> {
get() = notImplemented("root")
val filePath: String
get() = notImplemented("filePath")
val annotations: List<String>
val annotations: List<String>?
get() = notImplemented("annotations")
val modifiers: List<String>
val modifiers: List<String>?
get() = notImplemented("modifiers")
val parameters: List<FunctionInfoParameter>
val parameters: List<FunctionInfoParameter>?
get() = notImplemented("parameters")
val returnType: String?
get() = notImplemented("returnType")
Expand Down
14 changes: 9 additions & 5 deletions src/main/kotlin/astminer/filters/FunctionFilters.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,20 @@ import astminer.common.splitToSubtokens
* Filter that excludes functions that have at least one of modifiers from the [excludeModifiers] list.
*/
class ModifierFilter(private val excludeModifiers: List<String>) : FunctionFilter {
override fun validate(functionInfo: FunctionInfo<out Node>): Boolean =
!excludeModifiers.any { modifier -> modifier in functionInfo.modifiers }
override fun validate(functionInfo: FunctionInfo<out Node>): Boolean {
val functionModifiers = checkNotNull(functionInfo.modifiers) { "Modifiers weren't properly parsed" }
return functionModifiers.none { modifier -> modifier in excludeModifiers }
}
}

/**
* Filter that excludes functions that have at least one annotations from the [excludeAnnotations] list.
* Filter that excludes functions that have at least one of annotations from the [excludeAnnotations] list.
*/
class AnnotationFilter(private val excludeAnnotations: List<String>) : FunctionFilter {
override fun validate(functionInfo: FunctionInfo<out Node>): Boolean =
!excludeAnnotations.any { annotation -> annotation in functionInfo.annotations }
override fun validate(functionInfo: FunctionInfo<out Node>): Boolean {
val functionAnnotations = checkNotNull(functionInfo.annotations) { "Annotations weren't properly parsed" }
return functionAnnotations.none { annotation -> annotation in excludeAnnotations }
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,21 @@ package astminer.parse.antlr.java
import astminer.common.model.*
import astminer.parse.antlr.*
import astminer.parse.findEnclosingElementBy
import mu.KotlinLogging

private val logger = KotlinLogging.logger("Antlr-Java-function-info")

class AntlrJavaFunctionInfo(override val root: AntlrNode, override val filePath: String) : FunctionInfo<AntlrNode> {
override val nameNode: AntlrNode? = collectNameNode()
override val parameters: List<FunctionInfoParameter> = collectParameters()
override val returnType: String? = collectReturnType()
override val enclosingElement: EnclosingElement<AntlrNode>? = collectEnclosingClass()

override val parameters: List<FunctionInfoParameter>? =
try { collectParameters() } catch (e: IllegalStateException) {
logger.warn { e.message }
null
}

private fun collectNameNode(): AntlrNode? = root.getChildOfType(METHOD_NAME_NODE)

private fun collectReturnType(): String? {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package astminer.parse.antlr.javascript
import astminer.common.model.*
import astminer.parse.antlr.*
import astminer.parse.findEnclosingElementBy
import mu.KotlinLogging

private val logger = KotlinLogging.logger("Antlr-Javascript-function-info")

/**
Base class for describing JavaScript methods, functions or arrow functions.
Expand Down Expand Up @@ -76,9 +79,14 @@ abstract class AntlrJavaScriptElementInfo(override val root: AntlrNode, override
class JavaScriptArrowInfo(root: AntlrNode, filePath: String) : AntlrJavaScriptElementInfo(root, filePath) {

override val enclosingElement: EnclosingElement<AntlrNode>? = collectEnclosingElement()
override val parameters: List<FunctionInfoParameter> = collectParameters()
override val nameNode: AntlrNode? = root.getChildOfType(ARROW_NAME_NODE)

override val parameters: List<FunctionInfoParameter>? =
try { collectParameters() } catch (e: IllegalStateException) {
logger.warn { e.message }
null
}

override fun getParametersRoot(): AntlrNode? {
val parameterRoot = root.getChildOfType(ARROW_PARAMETER_NODE)
return parameterRoot?.getChildOfType(ARROW_PARAMETER_INNER_NODE) ?: parameterRoot
Expand All @@ -94,8 +102,12 @@ class JavaScriptArrowInfo(root: AntlrNode, filePath: String) : AntlrJavaScriptEl
class JavaScriptMethodInfo(root: AntlrNode, filePath: String) : AntlrJavaScriptElementInfo(root, filePath) {

override val enclosingElement: EnclosingElement<AntlrNode>? = collectEnclosingElement()
override val parameters: List<FunctionInfoParameter> = collectParameters()
override val nameNode: AntlrNode? = collectNameNode()
override val parameters: List<FunctionInfoParameter>? =
try { collectParameters() } catch (e: IllegalStateException) {
logger.warn { e.message }
null
}

private fun collectNameNode(): AntlrNode? {
val methodNameParent = root.children.firstOrNull {
Expand All @@ -119,8 +131,12 @@ class JavaScriptMethodInfo(root: AntlrNode, filePath: String) : AntlrJavaScriptE
class JavaScriptFunctionInfo(root: AntlrNode, filePath: String) : AntlrJavaScriptElementInfo(root, filePath) {

override val enclosingElement: EnclosingElement<AntlrNode>? = collectEnclosingElement()
override val parameters: List<FunctionInfoParameter> = collectParameters()
override val nameNode: AntlrNode? = root.getChildOfType(FUNCTION_NAME_NODE)
override val parameters: List<FunctionInfoParameter>? =
try { collectParameters() } catch (e: IllegalStateException) {
logger.warn { e.message }
null
}

override fun getParametersRoot(): AntlrNode? = root.getChildOfType(FUNCTION_PARAMETER_NODE)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ private val logger = KotlinLogging.logger("ANTLR-PHP-function-info")
class ANTLRPHPFunctionInfo(override val root: AntlrNode, override val filePath: String) : FunctionInfo<AntlrNode> {
override val returnType = getElementType(root)
override val nameNode: AntlrNode? = root.getChildOfType(FUNCTION_NAME)

override val parameters: List<FunctionInfoParameter> = collectParameters()
override val enclosingElement: EnclosingElement<AntlrNode>? = collectEnclosingElement()
override val parameters: List<FunctionInfoParameter>? =
try { collectParameters() } catch (e: IllegalStateException) {
logger.warn { e.message }
null
}

private fun collectParameters(): List<FunctionInfoParameter> {
// Parameters in this grammar have following structure (children order may be wrong):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@ package astminer.parse.antlr.python
import astminer.common.model.*
import astminer.parse.antlr.*
import astminer.parse.findEnclosingElementBy
import mu.KotlinLogging

private val logger = KotlinLogging.logger("Antlr-python-function-info")

class AntlrPythonFunctionInfo(override val root: AntlrNode, override val filePath: String) : FunctionInfo<AntlrNode> {
override val nameNode: AntlrNode? = collectNameNode()
override val parameters: List<FunctionInfoParameter> = collectParameters()
override val enclosingElement: EnclosingElement<AntlrNode>? = collectEnclosingElement()
override val parameters: List<FunctionInfoParameter>? =
try { collectParameters() } catch (e: IllegalStateException) {
logger.warn { e.message }
null
}

private fun collectNameNode(): AntlrNode? = root.getChildOfType(FUNCTION_NAME_NODE)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,20 @@ import astminer.common.model.FunctionInfo
import astminer.common.model.FunctionInfoParameter
import astminer.parse.findEnclosingElementBy
import astminer.parse.fuzzy.FuzzyNode
import mu.KotlinLogging

private val logger = KotlinLogging.logger("Fuzzyparser-Cpp-function-info")

class FuzzyCppFunctionInfo(override val root: FuzzyNode, override val filePath: String) : FunctionInfo<FuzzyNode> {

override val returnType: String? = collectReturnType()
override val enclosingElement: EnclosingElement<FuzzyNode>? = collectEnclosingClass()
override val parameters: List<FunctionInfoParameter> = collectParameters()
override val nameNode: FuzzyNode? = collectNameNode()
override val parameters: List<FunctionInfoParameter>? =
try { collectParameters() } catch (e: IllegalStateException) {
logger.warn { e.message }
null
}

private fun collectNameNode(): FuzzyNode? = root.getChildOfType(METHOD_NAME_NODE) as? FuzzyNode

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,23 @@ import astminer.common.model.EnclosingElementType
import astminer.common.model.FunctionInfo
import astminer.common.model.FunctionInfoParameter
import astminer.parse.gumtree.GumTreeNode
import mu.KotlinLogging

private val logger = KotlinLogging.logger("Gumtree-Java-function-info")

class GumTreeJavaFunctionInfo(
override val root: GumTreeNode,
override val filePath: String
) : FunctionInfo<GumTreeNode> {

override val nameNode: GumTreeNode? = root.getChildOfType(TypeLabels.simpleName)
override val parameters: List<FunctionInfoParameter> = collectParameters()
override val returnType: String? = root.getElementType()
override val enclosingElement: EnclosingElement<GumTreeNode>? = collectEnclosingClass()
override val parameters: List<FunctionInfoParameter>? =
try { collectParameters() } catch (e: IllegalStateException) {
logger.warn { e.message }
null
}

override val modifiers: List<String> = root.children.filter { it.typeLabel == "Modifier" }.map { it.originalToken }
override val annotations: List<String> = root
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,23 @@ import astminer.common.model.FunctionInfo
import astminer.common.model.FunctionInfoParameter
import astminer.parse.findEnclosingElementBy
import astminer.parse.gumtree.GumTreeNode
import mu.KotlinLogging

private val logger = KotlinLogging.logger("Gumtree-Java-function-info")

class GumTreePythonFunctionInfo(
override val root: GumTreeNode,
override val filePath: String
) : FunctionInfo<GumTreeNode> {

override val nameNode: GumTreeNode = root
override val parameters: List<FunctionInfoParameter> = collectParameters()
override val enclosingElement: EnclosingElement<GumTreeNode>? = collectEnclosingClass()
override val returnType: String? = getElementType(root)?.typeLabel
override val parameters: List<FunctionInfoParameter>? =
try { collectParameters() } catch (e: IllegalStateException) {
logger.warn { e.message }
null
}

private fun getElementType(node: GumTreeNode): GumTreeNode? {
if (node.typeLabel == TypeLabels.arg) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,40 +70,40 @@ class JavaFunctionSplitterTest {
fun testNoParameters() {
val methodNoParameters = functionInfos.find { it.name == "functionWithNoParameters" }
assertNotNull(methodNoParameters)
assertEquals(0, methodNoParameters.parameters.size)
assertEquals(0, methodNoParameters.parameters?.size)
}

@Test
fun testOneParameter() {
val methodOneParameter = functionInfos.find { it.name == "functionWithOneParameter" }
assertNotNull(methodOneParameter)
assertEquals(1, methodOneParameter.parameters.size)
val parameter = methodOneParameter.parameters[0]
assertEquals("p1", parameter.name)
assertEquals("int", parameter.type)
assertEquals(1, methodOneParameter.parameters?.size)
val parameter = methodOneParameter.parameters?.get(0)
assertEquals("p1", parameter?.name)
assertEquals("int", parameter?.type)
}

@Test
fun testThreeParameters() {
val methodThreeParameters = functionInfos.find { it.name == "functionWithThreeParameters" }
assertNotNull(methodThreeParameters)
assertEquals(3, methodThreeParameters.parameters.size)
assertEquals(3, methodThreeParameters.parameters?.size)
val methodTypes = listOf("Class", "String[][]", "int[]")
for (i in 0 until 3) {
val parameter = methodThreeParameters.parameters[i]
assertEquals("p${i + 1}", parameter.name)
assertEquals(methodTypes[i], parameter.type)
val parameter = methodThreeParameters.parameters?.get(i)
assertEquals("p${i + 1}", parameter?.name)
assertEquals(methodTypes[i], parameter?.type)
}
}

@Test
fun testWeirdArrayParameter() {
val methodWeirdArrayParameter = functionInfos.find { it.name == "functionWithStrangeArrayParameter" }
assertNotNull(methodWeirdArrayParameter)
assertEquals(1, methodWeirdArrayParameter.parameters.size)
val weirdParameter = methodWeirdArrayParameter.parameters[0]
assertEquals(weirdParameter.name, "arr[]")
assertEquals(weirdParameter.type, "int")
assertEquals(1, methodWeirdArrayParameter.parameters?.size)
val weirdParameter = methodWeirdArrayParameter.parameters?.get(0)
assertEquals(weirdParameter?.name, "arr[]")
assertEquals(weirdParameter?.type, "int")
}

companion object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class JavaScriptFunctionSplitterTest {
fun FunctionInfo<AntlrNode>.getJsonInfo(): String {
return "info : {" +
"name : $name, " +
"args : ${parameters.joinToString(", ") { it.name }}, " +
"args : ${parameters?.joinToString(", ") { it.name }}, " +
"enclosing element : ${enclosingElement?.type?.getEnclosingElementType()}, " +
"enclosing element name : ${enclosingElement?.name}" +
"}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ internal class ANTLRPHPFunctionSplitterTest {
fun FunctionInfo<AntlrNode>.getJsonInfo(): String = listOf(
"info : {",
"name: $name, ",
"args: ${parameters.joinToString(", ") {
"args: ${parameters?.joinToString(", ") {
listOfNotNull(it.type, it.name).joinToString(" ")
}}, ",
"enclosing element: ${enclosingElement?.type?.getEnclosingElementType()}, ",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,44 +53,44 @@ class PythonFunctionSplitterTest {
fun testNoParameters() {
val functionNoParameters = functionInfos.find { it.name == "function_with_no_parameters" }
assertNotNull(functionNoParameters)
assertEquals(0, functionNoParameters.parameters.size)
assertEquals(0, functionNoParameters.parameters?.size)
}

@Test
fun testOneParameter() {
val functionOneParameter = functionInfos.find { it.name == "function_with_one_parameter" }
assertNotNull(functionOneParameter)
assertEquals(1, functionOneParameter.parameters.size)
val parameter = functionOneParameter.parameters[0]
assertEquals("p1", parameter.name)
assertEquals(1, functionOneParameter.parameters?.size)
val parameter = functionOneParameter.parameters?.get(0)
assertEquals("p1", parameter?.name)
}

@Test
fun testOneTypedParameter() {
val functionOneTypedParameter = functionInfos.find { it.name == "function_with_one_typed_parameter" }
assertNotNull(functionOneTypedParameter)
assertEquals(1, functionOneTypedParameter.parameters.size)
val parameter = functionOneTypedParameter.parameters[0]
assertEquals("p1", parameter.name)
assertEquals("int", parameter.type)
assertEquals(1, functionOneTypedParameter.parameters?.size)
val parameter = functionOneTypedParameter.parameters?.get(0)
assertEquals("p1", parameter?.name)
assertEquals("int", parameter?.type)
}

@Test
fun functionWithComplexParameter() {
val functionOneTypedParameter = functionInfos.find { it.name == "function_with_complex_parameter" }
assertNotNull(functionOneTypedParameter)
assertEquals(1, functionOneTypedParameter.parameters.size)
val parameter = functionOneTypedParameter.parameters[0]
assertEquals("p1", parameter.name)
assertEquals("List[int]", parameter.type)
assertEquals(1, functionOneTypedParameter.parameters?.size)
val parameter = functionOneTypedParameter.parameters?.get(0)
assertEquals("p1", parameter?.name)
assertEquals("List[int]", parameter?.type)
}

@Test
fun testThreeParameters() {
val functionThreeParameters = functionInfos.find { it.name == "function_with_three_parameters" }
assertNotNull(functionThreeParameters)
assertEquals(3, functionThreeParameters.parameters.size)
val parameters = functionThreeParameters.parameters
assertEquals(3, functionThreeParameters.parameters?.size)
val parameters = functionThreeParameters.parameters!!
assertEquals("p1", parameters[0].name)

assertEquals("p2", parameters[1].name)
Expand All @@ -103,19 +103,19 @@ class PythonFunctionSplitterTest {
fun testParameterInClass() {
val functionOneParameter = functionInfos.find { it.name == "fun_with_parameter_in_class" }
assertNotNull(functionOneParameter)
assertEquals(2, functionOneParameter.parameters.size)
val parameter = functionOneParameter.parameters[1]
assertEquals("p1", parameter.name)
assertEquals(2, functionOneParameter.parameters?.size)
val parameter = functionOneParameter.parameters?.get(1)
assertEquals("p1", parameter?.name)
}

@Test
fun testTypedParameterInClass() {
val functionOneTypedParameter = functionInfos.find { it.name == "fun_with_typed_parameter_in_class" }
assertNotNull(functionOneTypedParameter)
assertEquals(2, functionOneTypedParameter.parameters.size)
val parameter = functionOneTypedParameter.parameters[1]
assertEquals("p1", parameter.name)
assertEquals("int", parameter.type)
assertEquals(2, functionOneTypedParameter.parameters?.size)
val parameter = functionOneTypedParameter.parameters?.get(1)
assertEquals("p1", parameter?.name)
assertEquals("int", parameter?.type)
}

@Test
Expand Down
Loading