Skip to content

Commit 98ef74f

Browse files
committed
feat(scala): add ScalaClassContextBuilder and test case
- Added `ScalaClassContextBuilder` class to handle building class context for Scala classes. - Added a test case `ScalaClassContextBuilderTest` to test the functionality of `ScalaClassContextBuilder`. - The test case verifies that the `getClassContext` method correctly retrieves the class name from a Scala file. - The `ScalaClassContextBuilder` class extracts information such as functions, fields, superclass, and annotations from the Scala class. - The class context is used for further processing and analysis in the plugin.
1 parent 73b83e9 commit 98ef74f

File tree

8 files changed

+126
-2
lines changed

8 files changed

+126
-2
lines changed

build.gradle.kts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ val cppPlugins = listOf(
7272
"com.intellij.cidr.lang",
7373
"com.intellij.clion",
7474
"com.intellij.cidr.base",
75-
"com.intellij.nativeDebug",
75+
// "com.intellij.nativeDebug",
7676
"org.jetbrains.plugins.clion.test.google",
7777
"org.jetbrains.plugins.clion.test.catch"
7878
)
@@ -83,6 +83,7 @@ val rustPlugins = listOf(
8383

8484
val riderVersion = prop("riderVersion")
8585
val riderPlugins: List<String> = listOf()
86+
val scalaPlugin = prop("scalaPlugin")
8687

8788
val pluginProjects: List<Project> get() = rootProject.allprojects.toList()
8889
val ideaPlugins =
@@ -224,6 +225,9 @@ project(":plugin") {
224225
"idea" -> {
225226
pluginList += javaPlugins
226227
}
228+
"scala" -> {
229+
pluginList += javaPlugins + scalaPlugin
230+
}
227231

228232
"python" -> {
229233
pluginList += pycharmPlugins
@@ -424,6 +428,7 @@ project(":") {
424428
kover(project(":kotlin"))
425429
kover(project(":pycharm"))
426430
kover(project(":rust"))
431+
kover(project(":scala"))
427432
}
428433

429434
task("resolveDependencies") {
@@ -478,6 +483,17 @@ project(":kotlin") {
478483
}
479484
}
480485

486+
project(":scala") {
487+
intellij {
488+
version.set(ideaVersion)
489+
plugins.set(ideaPlugins + scalaPlugin)
490+
}
491+
dependencies {
492+
implementation(project(":"))
493+
implementation(project(":java"))
494+
}
495+
}
496+
481497
project(":rust") {
482498
intellij {
483499
version.set(ideaVersion)

gradle-222.properties

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ pluginUntilBuild = 232.*
99

1010
clionVersion=CL-2022.2.4
1111

12+
# check latest available version here https://plugins.jetbrains.com/plugin/1347-scala/versions
13+
scalaPlugin=org.intellij.scala:2022.3.2
14+
1215
# https://plugins.jetbrains.com/plugin/9568-go/versions
1316
goPlugin=org.jetbrains.plugins.go:222.4459.24
1417

gradle-233.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pluginUntilBuild=241.*
1010
clionVersion=CL-2023.3
1111

1212
# check latest available version here https://plugins.jetbrains.com/plugin/1347-scala/versions
13-
#scalaPlugin=org.intellij.scala:2023.3.19
13+
scalaPlugin=org.intellij.scala:2023.3.19
1414

1515
# check latest available version here https://plugins.jetbrains.com/plugin/22407-rust/versions
1616
rustPlugin=com.jetbrains.rust:233.21799.284

plugin/src/main/resources/META-INF/plugin.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,6 @@
2828
<module name="cc.unitmesh.go"/>
2929
<module name="cc.unitmesh.rust"/>
3030
<module name="cc.unitmesh.cpp"/>
31+
<module name="cc.unitmesh.scala"/>
3132
</content>
3233
</idea-plugin>
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package cc.unitmesh.scala.context
2+
3+
import cc.unitmesh.devti.context.ClassContext
4+
import cc.unitmesh.devti.context.builder.ClassContextBuilder
5+
import com.intellij.psi.PsiElement
6+
import com.intellij.psi.PsiMethod
7+
import com.intellij.psi.PsiNameIdentifierOwner
8+
import com.intellij.psi.PsiReference
9+
import com.intellij.psi.search.GlobalSearchScope
10+
import com.intellij.psi.search.SearchScope
11+
import com.intellij.psi.search.searches.MethodReferencesSearch
12+
import com.intellij.psi.search.searches.ReferencesSearch
13+
import org.jetbrains.plugins.scala.lang.psi.api.toplevel.typedef.ScClass
14+
15+
class ScalaClassContextBuilder : ClassContextBuilder {
16+
override fun getClassContext(psiElement: PsiElement, gatherUsages: Boolean): ClassContext? {
17+
if (psiElement !is ScClass) return null
18+
19+
val name = psiElement.name ?: return null
20+
21+
val functions = psiElement.methods.toList()
22+
val allFields = psiElement.fields.toList()
23+
val superClass = psiElement.supers.mapNotNull { it.qualifiedName }.toList()
24+
val usages = findUsages(psiElement as PsiNameIdentifierOwner)
25+
26+
val annotations = psiElement.annotations.mapNotNull {
27+
it.text
28+
}
29+
30+
val displayName = psiElement.qualifiedName ?: psiElement.name ?: ""
31+
return ClassContext(
32+
psiElement,
33+
psiElement.text,
34+
name,
35+
functions,
36+
allFields,
37+
superClass,
38+
usages,
39+
displayName = displayName,
40+
annotations
41+
)
42+
}
43+
}
44+
45+
fun findUsages(nameIdentifierOwner: PsiNameIdentifierOwner): List<PsiReference> {
46+
val project = nameIdentifierOwner.project
47+
val searchScope = GlobalSearchScope.allScope(project) as SearchScope
48+
49+
return when (nameIdentifierOwner) {
50+
is PsiMethod -> {
51+
MethodReferencesSearch.search(nameIdentifierOwner, searchScope, true)
52+
}
53+
54+
else -> {
55+
ReferencesSearch.search((nameIdentifierOwner as PsiElement), searchScope, true)
56+
}
57+
}.findAll().map { it as PsiReference }
58+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<idea-plugin package="cc.unitmesh.scala">
2+
<!--suppress PluginXmlValidity -->
3+
<dependencies>
4+
<!--suppress PluginXmlValidity -->
5+
<module name="jvm-core"/>
6+
<plugin id="org.intellij.scala"/>
7+
<!-- <plugin id="org.jetbrains.plugins.gradle"/>-->
8+
</dependencies>
9+
10+
<extensions defaultExtensionNs="cc.unitmesh">
11+
<classContextBuilder
12+
language="Scala"
13+
implementationClass="cc.unitmesh.scala.context.ScalaClassContextBuilder"
14+
/>
15+
</extensions>
16+
</idea-plugin>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package cc.unitmesh.scala.context
2+
3+
import com.intellij.psi.PsiFileFactory
4+
import com.intellij.testFramework.LightPlatformTestCase
5+
6+
class ScalaClassContextBuilderTest: LightPlatformTestCase() {
7+
fun testShouldGetClassName() {
8+
val fileFactory: PsiFileFactory = PsiFileFactory.getInstance(project)
9+
10+
val classCode = """
11+
class Point(var x: Int, var y: Int):
12+
def move(dx: Int, dy: Int): Unit =
13+
x = x + dx
14+
y = y + dy
15+
16+
override def toString: String =
17+
s"(${'$'}x, ${'$'}y)"
18+
end Point
19+
""".trimIndent()
20+
21+
val psiFile = fileFactory.createFileFromText("Point.scala", classCode)
22+
val psiElement = psiFile.children[0]
23+
val classContext = ScalaClassContextBuilder().getClassContext(psiElement, false)!!
24+
25+
assertEquals(classContext.name, "Point")
26+
// TestCase.assertEquals(classContext.methods.size, 2)
27+
// TestCase.assertEquals(classContext.format(), """""")
28+
}
29+
}

settings.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ include(
1414
"rust",
1515
"csharp",
1616
"cpp",
17+
"scala",
1718
)

0 commit comments

Comments
 (0)