Skip to content
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
1 change: 1 addition & 0 deletions analysis/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/)
- UnifiedParser now automatically uses `.gitignore` files for file exclusion [#4254](https://github.com/MaibornWolff/codecharta/issues/4254)
- RawTextParser now automatically uses `.gitignore` files for file exclusion [#4273](https://github.com/MaibornWolff/codecharta/issues/4273)
- Add swift support to unifiedparser [#4335](https://github.com/MaibornWolff/codecharta/issues/4335)
- Add Objective-C support to unifiedparser [#4361](https://github.com/MaibornWolff/codecharta/issues/4361)
- GitLogParser is now able to find commits that contain the word hotfixes
- Add four code smell metrics to unifiedparser [#4315](https://github.com/MaibornWolff/codecharta/issues/4315) and [#4353](https://github.com/MaibornWolff/codecharta/issues/4353)
- long function
Expand Down
32 changes: 17 additions & 15 deletions analysis/analysers/parsers/UnifiedParser/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,22 @@ The Unified Parser is parser to generate code metrics from a source code file or

## Supported Languages

| Language | Supported file extensions |
|------------|----------------------------------------|
| Javascript | .js, .cjs, .mjs |
| Typescript | .ts, .cts, .mts |
| Java | .java |
| Kotlin | .kt |
| C# | .cs |
| C++ | .cpp, .cc, .cxx, .c++, .hh, .hpp, .hxx |
| C | .c, .h |
| Python | .py |
| Go | .go |
| PHP | .php |
| Ruby | .rb |
| Swift | .swift |
| Bash | .sh |
| Language | Supported file extensions |
|--------------|----------------------------------------|
| Javascript | .js, .cjs, .mjs |
| Typescript | .ts, .cts, .mts |
| Java | .java |
| Kotlin | .kt |
| C# | .cs |
| C++ | .cpp, .cc, .cxx, .c++, .hh, .hpp, .hxx |
| C | .c, .h |
| Objective-C | .m |
| Python | .py |
| Go | .go |
| PHP | .php |
| Ruby | .rb |
| Swift | .swift |
| Bash | .sh |

## Supported Metrics

Expand Down Expand Up @@ -101,6 +102,7 @@ cat pipeInput.cc.json | ccsh unifiedparser src/test/resources - -o merged.cc.jso
## Known issues

- In ruby the 'lambda' keyword is not counted correctly for complexity and number of functions
- In C/C++/ObjectiveC the using `void` as a parameter counts as 1 for parameters per function

## Extending the UnifiedParser

Expand Down
1 change: 1 addition & 0 deletions analysis/analysers/parsers/UnifiedParser/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ dependencies {
implementation(libs.treesitter.php)
implementation(libs.treesitter.ruby)
implementation(libs.treesitter.swift)
implementation(libs.treesitter.objc)
implementation(libs.treesitter.bash)

testImplementation(libs.jsonassert)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ enum class AvailableCollectors(
TYPESCRIPT(FileExtension.TYPESCRIPT, ::TypescriptCollector),
JAVASCRIPT(FileExtension.JAVASCRIPT, ::JavascriptCollector),
KOTLIN(FileExtension.KOTLIN, ::KotlinCollector),
OBJECTIVE_C(FileExtension.OBJECTIVE_C, ::ObjectiveCCollector),
JAVA(FileExtension.JAVA, ::JavaCollector),
CSHARP(FileExtension.CSHARP, ::CSharpCollector),
CPP(FileExtension.CPP, ::CppCollector),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package de.maibornwolff.codecharta.analysers.parsers.unified.metriccollectors

import de.maibornwolff.codecharta.analysers.parsers.unified.metricnodetypes.ObjectiveCNodeTypes
import org.treesitter.TreeSitterObjc

class ObjectiveCCollector : MetricCollector(
treeSitterLanguage = TreeSitterObjc(),
nodeTypeProvider = ObjectiveCNodeTypes()
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package de.maibornwolff.codecharta.analysers.parsers.unified.metricnodetypes

class ObjectiveCNodeTypes : MetricNodeTypes {
override val logicComplexityNodeTypes = TreeNodeTypes(
simpleNodeTypes = setOf(
// if
"if_statement",
// loop
"for_statement",
"while_statement",
"do_statement",
// case
"case_statement",
// catch
"@catch",
// ternary
"conditional_expression"
),
nestedNodeTypes = setOf(
// logical operators (&&, ||)
NestedNodeType(
baseNodeType = "binary_expression",
childNodeFieldName = "operator",
childNodeTypes = setOf("&&", "||")
)
)
)

override val functionComplexityNodeTypes = TreeNodeTypes(
simpleNodeTypes = setOf(
// C functions
"function_definition",
// Blocks (Objective-C closures)
"block_expression"
)
)

override val commentLineNodeTypes = TreeNodeTypes(
simpleNodeTypes = setOf(
"comment"
)
)

override val numberOfFunctionsNodeTypes = TreeNodeTypes(
simpleNodeTypes = setOf(
// C functions
"function_definition",
// Objective-C methods
"method_definition"
)
)

override val functionBodyNodeTypes = TreeNodeTypes(
simpleNodeTypes = setOf(
"compound_statement"
)
)

override val functionParameterNodeTypes = TreeNodeTypes(
simpleNodeTypes = setOf(
// C function parameters
"parameter_declaration",
// Objective-C method parameters
"keyword_declarator"
)
)

override val messageChainsNodeTypes = TreeNodeTypes(
simpleNodeTypes = setOf(
// C-style function calls and field access
"call_expression",
"field_expression",
// Objective-C message sends
"message_expression"
)
)

override val messageChainsCallNodeTypes = TreeNodeTypes(
simpleNodeTypes = setOf(
// C-style function calls
"call_expression",
// Objective-C message sends
"message_expression"
)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class UnifiedParserTest {
Arguments.of("java", ".java"),
Arguments.of("javascript", ".js"),
Arguments.of("kotlin", ".kt"),
Arguments.of("objectiveC", ".m"),
Arguments.of("php", ".php"),
Arguments.of("python", ".py"),
Arguments.of("ruby", ".rb"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,13 @@ class CCollectorTest {
fun `should count set except clause for complexity`() {
// given
val fileContent = """
int main() {
__try
{
TestExceptions();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
printf("Executing SEH __except block\\n");
}
__try
{
TestExceptions();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
printf("Executing SEH __except block\\n");
}
""".trimIndent()
val input = createTestFile(fileContent)
Expand All @@ -114,7 +112,7 @@ class CCollectorTest {
val result = collector.collectMetricsForFile(input)

// then
Assertions.assertThat(result.attributes[AvailableFileMetrics.COMPLEXITY.metricName]).isEqualTo(2.0)
Assertions.assertThat(result.attributes[AvailableFileMetrics.COMPLEXITY.metricName]).isEqualTo(1.0)
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,13 @@ class CppCollectorTest {
fun `should count seh-except clause for complexity`() {
// given
val fileContent = """
int main() {
__try
{
TestExceptions();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
printf("Executing SEH __except block\n");
}
__try
{
TestExceptions();
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
printf("Executing SEH __except block\n");
}
""".trimIndent()
val input = createTestFile(fileContent)
Expand All @@ -161,7 +159,7 @@ class CppCollectorTest {
val result = collector.collectMetricsForFile(input)

// then
Assertions.assertThat(result.attributes[AvailableFileMetrics.COMPLEXITY.metricName]).isEqualTo(2.0)
Assertions.assertThat(result.attributes[AvailableFileMetrics.COMPLEXITY.metricName]).isEqualTo(1.0)
}

@Test
Expand Down
Loading