Skip to content
Open
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
4 changes: 3 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,13 @@ dependencies {
testImplementation("junit:junit:4.13.2")

intellijPlatform {
intellijIdeaCommunity("2025.1.4.1")
intellijIdeaCommunity("2025.2")

bundledPlugin("com.intellij.java")
bundledPlugin("org.jetbrains.kotlin")
plugin("PythonCore", "252.23892.409")
plugin("org.jetbrains.plugins.go", "252.23892.360")
testPlugin("org.jetbrains.plugins.go", "252.23892.360")

instrumentationTools()
pluginVerifier()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import com.intellij.psi.PsiElement
val PLUGIN_EP_NAME: ExtensionPointName<ComplexityInfoProvider> = ExtensionPointName("com.github.nikolaikopernik.codecomplexity.languageInfoProvider")
val PLUGIN_HINT_KEY = SettingsKey<NoSettings>("code.complexity.hint")

val SUPPORTED_LANGUAGES = setOf("java", "kotlin", "python")
val SUPPORTED_LANGUAGES = setOf("java", "kotlin", "python", "go")

/**
* Main interface to calculate complexity for different languages.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package com.github.nikolaikopernik.codecomplexity.go

import com.github.nikolaikopernik.codecomplexity.core.ComplexityInfoProvider
import com.github.nikolaikopernik.codecomplexity.core.ComplexitySink
import com.github.nikolaikopernik.codecomplexity.core.ElementVisitor
import com.github.nikolaikopernik.codecomplexity.go.GoLanguageVisitor.Companion.isMemberFunction
import com.github.nikolaikopernik.codecomplexity.go.GoLanguageVisitor.Companion.isToplevelVarDeclFunction
import com.goide.GoLanguage
import com.goide.psi.GoElement
import com.goide.psi.GoFieldName
import com.goide.psi.GoFunctionLit
import com.goide.psi.GoFunctionOrMethodDeclaration
import com.goide.psi.GoKey
import com.goide.psi.GoValue
import com.goide.psi.GoVarDefinition
import com.goide.psi.GoVarSpec
import com.intellij.lang.Language
import com.intellij.psi.PsiElement

class GoComplexityInfoProvider(override val language: Language = GoLanguage.INSTANCE) : ComplexityInfoProvider {

override fun getVisitor(sink: ComplexitySink): ElementVisitor = GoLanguageVisitor(sink)

override fun isComplexitySuitableMember(element: PsiElement): Boolean {
return element is GoFunctionOrMethodDeclaration || element is GoFunctionLit
}

override fun isClassWithBody(element: PsiElement): Boolean {
return false
}

override fun getNameElementFor(element: PsiElement): PsiElement {
return when (element) {
is GoFunctionOrMethodDeclaration -> element.nameIdentifier ?: element
is GoFunctionLit -> when {
element.isMemberFunction() -> element.memberFieldName ?: element
element.isToplevelVarDeclFunction() -> element.varDefinition ?: element
else -> element
}
else -> element
}
}
}

/**
* Retrieves the field name of a member function's associated field.
*
* This property is used to extract a field name corresponding to a member function within Go code.
* It navigates the PSI (Program Structure Interface) tree, analyzing the parent hierarchy of the
* `GoFunctionLit` instance and extracts the field name from the related `GoElement`.
*
* [GoFunctionLit] -<parent>-> [GoValue] -<parent>-> [GoElement] -<getKey>-> [GoKey] -<fieldName>-> [GoFieldName]
*
* If the field name cannot be resolved (e.g., the structure doesn't match the expected hierarchy),
* the property returns `null`.
*
* @return The trimmed field name of the associated field, or `null` if unavailable.
*/
val GoFunctionLit.memberFieldName: GoFieldName?
get() {
val goElement = this.parent?.parent as? GoElement ?: return null
return goElement.key?.fieldName
}

val GoFunctionLit.memberFunctionFieldName: String?
get() {
val fieldName = this.memberFieldName ?: return null
return fieldName.text
}


/**
* Retrieves the variable name associated with a Go function literal
* if it is used in the context of a variable declaration.
*
* This property queries the parent element of the function literal to determine if it is
* part of a `GoVarSpec`. If the parent is a variable specification, it extracts the first
* variable name from the list of variable definitions.
*
* [GoFunctionLit] -<parent>-> [GoVarSpec]
*
* @return The name of the variable associated with the function literal, or `null` if
* no variable declaration is found or the name cannot be determined.
*/
val GoFunctionLit.varDefinition: GoVarDefinition?
get() {
val goVarSpec = this.parent as? GoVarSpec ?: return null
return goVarSpec.varDefinitionList.firstOrNull()
}

val GoFunctionLit.varFunctionVariableName: String?
get() {
val first = this.varDefinition ?: return null
return first.name
}
Loading
Loading