Skip to content

Commit

Permalink
IDEA 2024.2 support
Browse files Browse the repository at this point in the history
  • Loading branch information
hmemcpy committed Jul 19, 2024
1 parent e8547c8 commit d1ad220
Show file tree
Hide file tree
Showing 7 changed files with 177 additions and 54 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ on:
- idea232.x
- idea233.x
- idea241.x
- idea242.x
pull_request:

jobs:
Expand Down
8 changes: 4 additions & 4 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import org.jetbrains.sbtidea.{AutoJbr, JbrPlatform}

lazy val scala213 = "2.13.12"
lazy val scalaPluginVersion = "2024.1.25"
lazy val scalaPluginVersion = "2024.2.5"
lazy val minorVersion = "0"
lazy val buildVersion = sys.env.getOrElse("ZIO_INTELLIJ_BUILD_NUMBER", minorVersion)
lazy val pluginVersion = s"2024.1.34.$buildVersion"
lazy val pluginVersion = s"2024.2.34.$buildVersion"

ThisBuild / intellijPluginName := "zio-intellij"
ThisBuild / intellijBuild := "241"
ThisBuild / intellijBuild := "242.16677.21"
ThisBuild / jbrInfo := AutoJbr(explicitPlatform = Some(JbrPlatform.osx_aarch64))

Global / intellijAttachSources := true
Expand Down Expand Up @@ -42,7 +42,7 @@ lazy val root =
s"""<![CDATA[
<b>What's new?</b>
<ul>
<li>Implemented the new Project Wizard API for ZIO <a href="https://github.com/zio/zio-intellij/pull/471">(#471)</a></li>
<li>IntelliJ IDEA 2024.2 support!</li>
</ul>
]]>"""
)
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

<change-notes>replaced-by-build</change-notes>

<idea-version since-build="241.14494" until-build="241.*"/>
<idea-version since-build="242.15523" until-build="242.*"/>

<depends>org.intellij.scala</depends>
<depends>com.intellij.modules.java</depends>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import zio.intellij.project.npw.template.wizard.ZioProjectBuilder
import zio.intellij.utils.ZioVersion
import zio.intellij.utils.ZioVersion.ZIO

import java.lang
import javax.swing.JLabel
import scala.annotation.nowarn

Expand Down Expand Up @@ -269,4 +270,6 @@ final class ZioNewProjectWizardStep(parent: ScalaNewProjectWizardStep)
null
}
}

override private[project] def setGenerateOnboardingTips(value: lang.Boolean): Unit = ()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package org.jetbrains.plugins.scala.base

import com.intellij.openapi.editor.Editor
import com.intellij.openapi.fileTypes.FileType
import com.intellij.psi.PsiFile
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture
import org.jetbrains.plugins.scala.ScalaFileType
import org.jetbrains.plugins.scala.extensions.StringExt
import org.junit.Assert.assertNotNull

//NOTE: for now we intentionally inherit any base text feature (e.g. JavaCodeInsightTestFixture) and use composition instead.
//This is done "for simplicity" of transition from inheritance to fixture usage in tests
//Once it's stabilised we might consider using the inheritance, but we need to ensure it will beneficial at all
final class ScalaCodeInsightTestFixture(
val javaFixture: JavaCodeInsightTestFixture
) {
private var fileTextPatcher: String => String = identity
private var defaultFileType: FileType = ScalaFileType.INSTANCE
private var customCheckResultByTextFunction: Option[(String, Boolean) => Unit] = None

def setFileTextPatcher(patcher: String => String): Unit =
fileTextPatcher = patcher

def setDefaultFileType(fileType: FileType): Unit = {
defaultFileType = fileType
}

def setCustomCheckResultByTextFunction(f: (String, Boolean) => Unit): Unit = {
customCheckResultByTextFunction = Some(f)
}

/////////////////////////////////////////////////////////
// Section start: helper setup methods
/////////////////////////////////////////////////////////
//TODO: do not trim expected text here, trim it at usage place
def checkResultByText(expectedFileText: String, ignoreTrailingSpaces: Boolean = true): Unit = {
val expectedPatched = fileTextPatcher(expectedFileText.withNormalizedSeparator.trim)
customCheckResultByTextFunction match {
case Some(customCheck) =>
customCheck(expectedPatched, ignoreTrailingSpaces)
case _ =>
javaFixture.checkResult(expectedPatched, ignoreTrailingSpaces)
}
}

def configureFromFileText(fileText: String): PsiFile =
configureFromFileText(defaultFileType, fileText)

//TODO 1: do not trim expected text here, trim it at usage place
def configureFromFileText(fileType: FileType, fileText: String): PsiFile = {
val fileTextPatched = fileTextPatcher(fileText.withNormalizedSeparator.trim)
val file = javaFixture.configureByText(fileType, fileTextPatched)
assertNotNull(file)
file
}

def configureFromFileTextWithSomeName(fileType: String, fileText: String): PsiFile = {
val fileTextPatched = fileTextPatcher(fileText.withNormalizedSeparator)
val file = javaFixture.configureByText("Test." + fileType, fileTextPatched)
assertNotNull(file)
file
}

def configureFromFileText(fileName: String, fileText: String): PsiFile = {
val fileTextPatched = fileTextPatcher(fileText.withNormalizedSeparator)
val file = javaFixture.configureByText(fileName: String, fileTextPatched)
assertNotNull(file)
file
}

def openEditorAtOffset(startOffset: Int): Editor = {
import com.intellij.openapi.fileEditor.{FileEditorManager, OpenFileDescriptor}
val project = javaFixture.getProject
val editorManager = FileEditorManager.getInstance(project)
val vFile = javaFixture.getFile.getVirtualFile
val editor = editorManager.openTextEditor(new OpenFileDescriptor(project, vFile, startOffset), false)
editor
}
/////////////////////////////////////////////////////////
// Section end: helper setup methods
/////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////
// Section start: assertion methods
/////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////
// Section end: assertion methods
/////////////////////////////////////////////////////////
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package org.jetbrains.plugins.scala.base

import com.intellij.application.options.CodeStyle
import com.intellij.codeInsight.daemon.impl.HighlightInfo
import com.intellij.codeInsight.folding.CodeFoldingManager
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.fileTypes.FileType
import com.intellij.openapi.module.Module
Expand All @@ -16,13 +15,16 @@ import com.intellij.psi.PsiFile
import com.intellij.psi.codeStyle.{CodeStyleSettings, CommonCodeStyleSettings}
import com.intellij.testFramework.fixtures.{JavaCodeInsightTestFixture, LightJavaCodeInsightFixtureTestCase}
import com.intellij.testFramework.{EditorTestUtil, LightProjectDescriptor}
import org.intellij.lang.annotations.Language
import org.jetbrains.jps.model.java.JavaSourceRootType
import org.jetbrains.plugins.scala.base.libraryLoaders.{LibraryLoader, ScalaSDKLoader, SmartJDKLoader, SourcesLoader}
import org.jetbrains.plugins.scala.extensions.StringExt
import org.jetbrains.plugins.scala.lang.formatting.settings.ScalaCodeStyleSettings
import org.jetbrains.plugins.scala.project.settings.ScalaCompilerConfiguration
import org.jetbrains.plugins.scala.util.TestUtils
import org.jetbrains.plugins.scala.{ScalaFileType, ScalaLanguage}
import org.junit.Assert.assertNotNull
import org.junit.Assert
import org.junit.Assert.fail

import scala.jdk.CollectionConverters._

Expand All @@ -37,6 +39,8 @@ abstract class ScalaLightCodeInsightFixtureTestCase
protected val START = EditorTestUtil.SELECTION_START_TAG
protected val END = EditorTestUtil.SELECTION_END_TAG

protected lazy val scalaFixture: ScalaCodeInsightTestFixture = new ScalaCodeInsightTestFixture(getFixture)

override def getTestDataPath: String = TestUtils.getTestDataPath + "/"

protected def sourceRootPath: String = null
Expand All @@ -61,7 +65,8 @@ abstract class ScalaLightCodeInsightFixtureTestCase
//end section: project libraries configuration

//start section: project descriptor
protected def sharedProjectToken: SharedTestProjectToken = SharedTestProjectToken.DoNotShare
protected def sharedProjectToken: SharedTestProjectToken =
SharedTestProjectToken.ByTestClassAndScalaSdkAndProjectLibraries(this)

override protected def getProjectDescriptor: LightProjectDescriptor = new ScalaLightProjectDescriptor(sharedProjectToken) {
override def tuneModule(module: Module, project: Project): Unit = {
Expand All @@ -79,6 +84,10 @@ abstract class ScalaLightCodeInsightFixtureTestCase

protected def placeSourceFilesInTestContentRoot: Boolean = false

/**
* @note If you are overriding this method, most likely, the light project cannot be shared between subsequent
* test invocations. Look into also overriding [[sharedProjectToken]].
*/
protected def afterSetUpProject(project: Project, module: Module): Unit = {
Registry.get("ast.loading.filter").setValue(true, getTestRootDisposable)

Expand All @@ -89,13 +98,35 @@ abstract class ScalaLightCodeInsightFixtureTestCase
if (loadScalaLibrary) {
myFixture.allowTreeAccessForAllFiles()
super.setUpLibraries(module)

val compilerOptions = additionalCompilerOptions
if (compilerOptions.nonEmpty) {
addCompilerOptions(module, compilerOptions)
}
}
}

protected def additionalCompilerOptions: Seq[String] = Nil

private def addCompilerOptions(module: Module, options: Seq[String]): Unit = {
val compilerConfiguration = ScalaCompilerConfiguration.instanceIn(module.getProject)

val settings = compilerConfiguration.settingsForHighlighting(module) match {
case Seq(s) => s
case _ =>
Assert.fail("expected single settings for module").asInstanceOf[Nothing]
}

val newSettings =
if (options.forall(settings.additionalCompilerOptions.contains)) settings
else settings.copy(additionalCompilerOptions = settings.additionalCompilerOptions ++ options)
compilerConfiguration.configureSettingsForModule(module, "unit tests", newSettings)
}
//end section: project descriptor

override protected def setUp(): Unit = {
TestUtils.optimizeSearchingForIndexableFiles()
super.setUp()
scalaFixture //init fixture lazy val
TestUtils.disableTimerThread()
}

Expand All @@ -105,37 +136,19 @@ abstract class ScalaLightCodeInsightFixtureTestCase
}

//start section: helper methods
protected def configureFromFileText(fileText: String): PsiFile =
configureFromFileText(ScalaFileType.INSTANCE, fileText)

protected def configureFromFileText(fileType: FileType, fileText: String): PsiFile = {
val file = myFixture.configureByText(fileType, fileText.stripMargin.withNormalizedSeparator.trim)
assertNotNull(file)
file
}

protected def configureFromFileTextWithSomeName(fileType: String, fileText: String): PsiFile = {
val file = myFixture.configureByText("Test." + fileType, fileText.withNormalizedSeparator)
assertNotNull(file)
file
}

protected def configureFromFileText(fileName: String, fileText: String): PsiFile = {
val file = myFixture.configureByText(fileName: String, fileText.withNormalizedSeparator)
assertNotNull(file)
file
}

protected def openEditorAtOffset(startOffset: Int): Editor = {
import com.intellij.openapi.fileEditor.{FileEditorManager, OpenFileDescriptor}
val project = getProject
val editorManager = FileEditorManager.getInstance(project)
val vFile = getFile.getVirtualFile
val editor = editorManager.openTextEditor(new OpenFileDescriptor(project, vFile, startOffset), false)
editor
}
protected final def configureFromFileText(fileText: String): PsiFile = scalaFixture.configureFromFileText(fileText)
protected final def configureFromFileText(fileType: FileType, fileText: String): PsiFile = scalaFixture.configureFromFileText(fileType, fileText)
protected final def configureFromFileTextWithSomeName(fileType: String, fileText: String): PsiFile = scalaFixture.configureFromFileTextWithSomeName(fileType, fileText)
protected final def configureFromFileText(fileName: String, fileText: String): PsiFile = scalaFixture.configureFromFileText(fileName, fileText)
protected final def openEditorAtOffset(startOffset: Int): Editor = scalaFixture.openEditorAtOffset(startOffset)

protected final def configureScalaFromFileText(@Language("Scala") fileText: String): PsiFile = scalaFixture.configureFromFileText(fileText)
protected final def configureScala3FromFileText(@Language("Scala 3") fileText: String): PsiFile = scalaFixture.configureFromFileText(fileText)
protected final def addScalaFileToProject(relativePath: String, @Language("Scala") fileText: String): PsiFile = myFixture.addFileToProject(relativePath, fileText)
//end section: helper methods

//TODO: consider extracting implementation body to ScalaCodeInsightTestFixture
// or crete a similar fixture which would be more specific for highlighting
//start section: check errors
protected def checkTextHasNoErrors(text: String): Unit = {
myFixture.configureByText(ScalaFileType.INSTANCE, text)
Expand Down Expand Up @@ -171,7 +184,12 @@ abstract class ScalaLightCodeInsightFixtureTestCase
val warnings = infos.filter(i => StringUtil.isNotEmpty(i.getDescription) && isAroundCaret(i))

if (shouldPass) {
assert(warnings.nonEmpty, "No highlightings found")
if (warnings.isEmpty) {
val message =
if (infos.isEmpty) "No highlightings found"
else s"No matching highlightings found. All highlightings:\n${infos.map(_.toString).mkString("\n")}"
fail(message)
}
} else if (warnings.nonEmpty) {
throw new RuntimeException(failingPassed)
}
Expand Down
Loading

0 comments on commit d1ad220

Please sign in to comment.