Skip to content

Commit

Permalink
Support for IntelliJ 2022.3
Browse files Browse the repository at this point in the history
  • Loading branch information
mvilliger committed Oct 26, 2022
1 parent f7912e9 commit b2b6ef0
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 150 deletions.
4 changes: 2 additions & 2 deletions org.eclipse.scout.sdk.s2e.releng/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@
<plugin>
<groupId>com.googlecode.maven-download-plugin</groupId>
<artifactId>download-maven-plugin</artifactId>
<version>1.6.7</version>
<version>1.6.8</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.0.0-M1</version>
<version>3.0.0</version>
<configuration>
<url>${forgeSnapshotUrl}</url>
<repositoryId>${forgeSnapshotId}</repositoryId>
Expand Down
8 changes: 4 additions & 4 deletions org.eclipse.scout.sdk.s2i/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ plugins {
id("java")
id("maven-publish")
id("idea")
id("org.jetbrains.intellij") version "1.6.0"
id("org.jetbrains.intellij") version "1.9.0"
kotlin("jvm") version "1.5.32"
id("net.linguica.maven-settings") version "0.5" // for maven settings
}
Expand All @@ -62,10 +62,10 @@ repositories {
dependencies {
api("org.eclipse.scout.sdk", "org.eclipse.scout.sdk.core.s", scoutSdkVersion)
api("org.eclipse.scout.sdk", "org.eclipse.scout.sdk.core.ecj", scoutSdkVersion)
api("org.apache.poi", "poi-ooxml", "5.2.2")
api("org.apache.poi", "poi-ooxml", "5.2.3")
implementation(kotlin("stdlib-jdk8"))
implementation(kotlin("reflect"))
testImplementation("org.mockito", "mockito-core", "4.6.1")
testImplementation("org.mockito", "mockito-core", "4.8.1")
testImplementation("org.eclipse.scout.rt", "org.eclipse.scout.rt.client", scoutRtVersion)
testImplementation("org.eclipse.scout.sdk", "org.eclipse.scout.sdk.core.test", scoutSdkVersion)
}
Expand All @@ -91,7 +91,7 @@ tasks {
}

runPluginVerifier {
ideVersions.set(listOf("IU-2021.2.4", "IU-2021.3.3", "IU-2022.1.2", "IU-2022.2"))
ideVersions.set(listOf("IU-2021.2.4", "IU-2021.3.3", "IU-2022.1.4", "IU-2022.2.3", "IU-2022.3"))
subsystemsToCheck.set("without-android")
failureLevel.set(FailureLevel.ALL)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
#
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
131 changes: 63 additions & 68 deletions org.eclipse.scout.sdk.s2i/org.eclipse.scout.sdk.s2i.iml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.actionSystem.LangDataKeys
import com.intellij.openapi.project.DumbService
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.PackageIndex
import com.intellij.openapi.roots.ProjectFileIndex
import com.intellij.openapi.ui.popup.JBPopup
import com.intellij.openapi.util.text.StringUtil
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiDirectory
import com.intellij.psi.PsiNameHelper
Expand All @@ -38,6 +40,7 @@ import org.eclipse.scout.sdk.core.util.Strings.capitalize
import org.eclipse.scout.sdk.s2i.EclipseScoutBundle
import org.eclipse.scout.sdk.s2i.environment.IdeaEnvironment
import org.eclipse.scout.sdk.s2i.util.SourceFolderHelper
import org.eclipse.scout.sdk.s2i.util.compat.CompatibilityMethodCaller
import java.util.*
import java.util.concurrent.TimeUnit
import java.util.function.BiConsumer
Expand Down Expand Up @@ -129,7 +132,7 @@ abstract class CreateElementAction<OP : BiConsumer<IEnvironment, IProgress>>(val
return@callInIdeaEnvironment null
}

var pkg = fileIndex.getPackageNameByDirectory(dir.virtualFile)
var pkg = getPackageNameByDirectory(dir.virtualFile, fileIndex, project)
val lastIndexOf = name.lastIndexOf(".")
if (lastIndexOf > 0) pkg += "." + name.substring(0, lastIndexOf)
val elementName = capitalize(name.substring(lastIndexOf + 1, name.length)).toString()
Expand All @@ -153,6 +156,19 @@ abstract class CreateElementAction<OP : BiConsumer<IEnvironment, IProgress>>(val
}
}

protected fun getPackageNameByDirectory(dir: VirtualFile, fileIndex: ProjectFileIndex, project: Project): String? {
// can be removed as soon as IJ 2022.3 is the latest supported version
return CompatibilityMethodCaller<String?>()
.withCandidate(PackageIndex::class.java.name, "getPackageNameByDirectory", VirtualFile::class.java.name) {
// for IJ >= 2022.3: use PackageIndex
it.invoke(PackageIndex.getInstance(project), dir)
}
.withCandidate(ProjectFileIndex::class.java.name, "getPackageNameByDirectory", VirtualFile::class.java.name) {
// for IJ <= 2022.2 use ProjectFileIndex
it.invoke(fileIndex, dir)
}.invoke()
}

protected open fun openPsiInEditorLater(project: Project, psiSupplier: () -> PsiClass?) {
AppExecutorUtil.getAppScheduledExecutorService().schedule({
DumbService.getInstance(project).smartInvokeLater {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2021 BSI Business Systems Integration AG.
* Copyright (c) 2010-2022 BSI Business Systems Integration AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
Expand All @@ -14,7 +14,6 @@ import com.intellij.openapi.module.Module
import com.intellij.openapi.project.DumbAware
import com.intellij.openapi.project.Project
import com.intellij.openapi.project.rootManager
import com.intellij.openapi.roots.OrderRootType
import com.intellij.openapi.startup.StartupActivity
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.PsiClass
Expand Down Expand Up @@ -44,10 +43,10 @@ import kotlin.streams.asStream
open class IdeaTranslationStoreSupplier : ITranslationStoreSupplier, StartupActivity, DumbAware {

override fun visibleStoresForJavaModule(modulePath: Path, env: IEnvironment, progress: IProgress): Stream<ITranslationStore> = modulePath
.toVirtualFile()
?.containingModule(env.toIdea().project)
?.let { findJavaTranslationStoresVisibleIn(it, env.toIdea(), progress.toIdea()) }
?: Stream.empty()
.toVirtualFile()
?.containingModule(env.toIdea().project)
?.let { findJavaTranslationStoresVisibleIn(it, env.toIdea(), progress.toIdea()) }
?: Stream.empty()

override fun createStoreForService(textService: IType, progress: IProgress): Optional<ITranslationStore> {
val psi = textService.resolvePsi() ?: return Optional.empty()
Expand All @@ -74,58 +73,56 @@ open class IdeaTranslationStoreSupplier : ITranslationStoreSupplier, StartupActi
}

override fun visibleTextContributorsForJavaModule(modulePath: Path, env: IEnvironment, progress: IProgress): Stream<IType> = modulePath
.toVirtualFile()
?.containingModule(env.toIdea().project)
?.let {
resolveSubClasses(it, env.toIdea(), IScoutApi::IUiTextContributor)
.mapNotNull { mapping -> mapping.scoutType }
}
?.asStream()
?: Stream.empty()
.toVirtualFile()
?.containingModule(env.toIdea().project)
?.let {
resolveSubClasses(it, env.toIdea(), IScoutApi::IUiTextContributor)
.mapNotNull { mapping -> mapping.scoutType }
}
?.asStream()
?: Stream.empty()

private fun resolveSubClasses(module: Module, env: IdeaEnvironment, nameFunction: (IScoutApi) -> ITypeNameSupplier): Sequence<TypeMapping> {
val javaEnv = env.toScoutJavaEnvironment(module) ?: return emptySequence()
return javaEnv.api(IScoutApi::class.java)
.map { nameFunction(it).fqn() }
.map { resolveSubClasses(module, it, javaEnv) }
.orElseGet { emptySequence() }
.map { nameFunction(it).fqn() }
.map { resolveSubClasses(module, it, javaEnv) }
.orElseGet { emptySequence() }
}

private fun resolveSubClasses(module: Module, fqn: String, javaEnv: IJavaEnvironment): Sequence<TypeMapping> = computeInReadAction(module.project) {
val moduleScope = module.getModuleWithDependenciesAndLibrariesScope(false)
val project = module.project
project.findTypesByName(fqn, moduleScope)
.flatMap { it.newSubTypeHierarchy(moduleScope, checkDeep = true, includeAnonymous = false, includeRoot = false).asSequence() }
.filter { !it.isEnum }
.filter { it.hasModifierProperty(PsiModifier.PUBLIC) }
.filter { !it.hasModifierProperty(PsiModifier.ABSTRACT) }
.filter { it.canNavigateToSource() }
.map { TypeMapping(it.toScoutType(javaEnv), it, project) }
.filter { it.scoutType != null }
.flatMap { it.newSubTypeHierarchy(moduleScope, checkDeep = true, includeAnonymous = false, includeRoot = false).asSequence() }
.filter { !it.isEnum }
.filter { it.hasModifierProperty(PsiModifier.PUBLIC) }
.filter { !it.hasModifierProperty(PsiModifier.ABSTRACT) }
.filter { it.canNavigateToSource() }
.map { TypeMapping(it.toScoutType(javaEnv), it, project) }
.filter { it.scoutType != null }
}

protected fun createTranslationStore(textService: IType, psiClass: PsiClass, progress: IProgress): Optional<ITranslationStore> {
return PropertiesTextProviderService.create(textService)
.map { svc -> PropertiesTranslationStore(svc) }
.filter { store -> loadTranslationFiles(psiClass, store, progress) }
.map { store -> store }
.map { svc -> PropertiesTranslationStore(svc) }
.filter { store -> loadTranslationFiles(psiClass, store, progress) }
.map { store -> store }
}

protected fun loadTranslationFiles(psiClass: PsiClass, store: PropertiesTranslationStore, progress: IProgress): Boolean {
val rootType = if (psiClass.isWritable) OrderRootType.SOURCES else OrderRootType.CLASSES
val roots = findRootDirectories(psiClass, rootType) ?: return false
val roots = findRootDirectories(psiClass) ?: return false
val prefix = store.service().filePrefix()
val folder = store.service().folder()
val translationFiles = roots
.asSequence()
.mapNotNull { it.findFileByRelativePath(folder) }
.filter { it.isValid }
.filter { it.isDirectory }
.flatMap { it.children.asSequence() }
.filter { it.isValid }
.filter { !it.isDirectory }
.mapNotNull { toTranslationPropertiesFile(it, prefix) }
.toList()
.mapNotNull { it.findFileByRelativePath(folder) }
.filter { it.isValid }
.filter { it.isDirectory }
.flatMap { it.children.asSequence() }
.filter { it.isValid }
.filter { !it.isDirectory }
.mapNotNull { toTranslationPropertiesFile(it, prefix) }
.toList()
if (translationFiles.isEmpty()) {
SdkLog.warning("Skipping TextProviderService '{}' because no properties files could be found.", store.service().type().name())
return false
Expand All @@ -136,15 +133,19 @@ open class IdeaTranslationStoreSupplier : ITranslationStoreSupplier, StartupActi

/**
* @param psiClass The [PsiClass] for which the roots should be returned (the TextProviderService)
* @param rootType The root type. One of the OrderRootType constants. E.g. OrderRootType.SOURCES or OrderRootType.CLASSES
* @return the source or class roots of the module containing the PsiClass specified
*/
protected fun findRootDirectories(psiClass: PsiClass, rootType: OrderRootType): Array<VirtualFile>? {
protected fun findRootDirectories(psiClass: PsiClass): Sequence<VirtualFile>? {
val module = psiClass.containingModule() ?: return null
return module.rootManager
.fileIndex
.getOrderEntryForFile(psiClass.containingFile.virtualFile)
?.getFiles(rootType)
val orderEnumerator = module.rootManager
.orderEntries()
.withoutSdk()
val sources = orderEnumerator.allSourceRoots.filter { !it.name.endsWith(".jar") }
val binaries = orderEnumerator.allLibrariesAndSdkClassesRoots

val sourcesAndLibraries = sources.toMutableList()
sourcesAndLibraries.addAll(binaries)
return sourcesAndLibraries.asSequence()
}

protected fun toTranslationPropertiesFile(file: VirtualFile, prefix: String): ITranslationPropertiesFile? {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2021 BSI Business Systems Integration AG.
* Copyright (c) 2010-2022 BSI Business Systems Integration AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
Expand All @@ -13,16 +13,13 @@ package org.eclipse.scout.sdk.s2i.template.js
import com.intellij.codeInsight.completion.*
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.codeInsight.lookup.LookupElementBuilder
import com.intellij.lang.ecmascript6.actions.ES6AddImportExecutor
import com.intellij.lang.ecmascript6.psi.impl.ES6ImportPsiUtil
import com.intellij.lang.ecmascript6.psi.impl.ES6ImportPsiUtil.CreateImportExportInfo
import com.intellij.lang.javascript.patterns.JSPatterns.jsProperty
import com.intellij.lang.javascript.psi.JSArrayLiteralExpression
import com.intellij.openapi.vfs.VfsUtilCore
import com.intellij.patterns.PlatformPatterns.psiElement
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiManager
import com.intellij.util.ProcessingContext
import org.eclipse.scout.sdk.core.s.IWebConstants
import org.eclipse.scout.sdk.s2i.model.js.JsModel
import org.eclipse.scout.sdk.s2i.model.js.JsModelProperty
import org.eclipse.scout.sdk.s2i.template.js.JsModelCompletionHelper.PropertyCompletionInfo
Expand All @@ -37,7 +34,7 @@ class JsModelValueCompletionContributor : CompletionContributor() {
// normal value completion
extend(CompletionType.BASIC, propertyElementPattern(), JsModelValueCompletionProvider())

// value completion when within an array (to add an additional array element)
// value completion when within an array (to add an array element)
extend(CompletionType.BASIC, psiElement().withSuperParent(2, psiElement(JSArrayLiteralExpression::class.java).withParent(jsProperty())), JsModelValueCompletionProvider())
}

Expand Down Expand Up @@ -69,14 +66,14 @@ class JsModelValueCompletionContributor : CompletionContributor() {
return jsModel.valuesForProperty(jsProperty).map {
val lookupElement = createLookupElement(it.displayText, it.element, jsProperty, completionInfo)
if (!completionInfo.isInLiteral) {
withJsImportIfNecessary(lookupElement, completionInfo.property.containingFile.originalFile, jsModel, jsProperty)
withJsImportIfNecessary(lookupElement, completionInfo.property.containingFile.originalFile, jsProperty)
} else {
lookupElement
}
}
}

private fun withJsImportIfNecessary(lookupElement: LookupElementBuilder, place: PsiElement, thisJsModel: JsModel, jsProperty: JsModelProperty): LookupElementBuilder {
private fun withJsImportIfNecessary(lookupElement: LookupElementBuilder, place: PsiElement, jsProperty: JsModelProperty): LookupElementBuilder {
val targetScoutJsModule = jsProperty.scoutJsModule
if (!jsProperty.dataType.isCustomType() && (!targetScoutJsModule.useClassReference || (jsProperty.dataType != JsModelProperty.JsPropertyDataType.WIDGET && jsProperty.name != JsModel.OBJECT_TYPE_PROPERTY_NAME))) return lookupElement
val targetJsModel = targetScoutJsModule.jsModel
Expand All @@ -85,26 +82,16 @@ class JsModelValueCompletionContributor : CompletionContributor() {
} else {
targetJsModel.element(jsProperty.dataType.type)
} ?: return lookupElement
val containingFile = place.containingFile.virtualFile
val thisModule = thisJsModel.containingModule(containingFile) ?: return lookupElement
val targetModule = type.scoutJsModule
val originalHandler = lookupElement.insertHandler
var importName = type.name
val firstDot = importName.indexOf('.')
if (firstDot > 0) importName = importName.take(firstDot)

return lookupElement.withInsertHandler { context, item ->
originalHandler?.handleInsert(context, item)
val moduleOrNamespaceName = if (thisModule == targetModule) {
val relPath = VfsUtilCore.findRelativePath(containingFile, thisModule.mainFile, VfsUtilCore.VFS_SEPARATOR_CHAR) ?: targetModule.name
relPath.removeSuffix(IWebConstants.JS_FILE_SUFFIX)
} else {
targetModule.name
}
var importName = type.name
val firstDot = importName.indexOf('.')
if (firstDot > 0) importName = importName.take(firstDot)
val executor = ES6AddImportExecutor(context.editor, place)

val info = CreateImportExportInfo(importName, ES6ImportPsiUtil.ImportExportType.SPECIFIER)
executor.createImportOrUseExisting(info, null, moduleOrNamespaceName)
val targetModuleMainFile = PsiManager.getInstance(context.project).findFile(targetScoutJsModule.mainFile) ?: return@withInsertHandler
ES6ImportPsiUtil.insertJSImport(place, importName, ES6ImportPsiUtil.ImportExportType.SPECIFIER, targetModuleMainFile, context.editor)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2021 BSI Business Systems Integration AG.
* Copyright (c) 2010-2022 BSI Business Systems Integration AG.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
Expand Down Expand Up @@ -38,12 +38,12 @@ class CompatibilityMethodCaller<T> {
fun withCandidate(declaringClassFqn: String, methodName: String, vararg parameterTypesFqn: String, handler: (ResolvedMethod<T>) -> T) =
withCandidate(MethodDescriptor(declaringClassFqn, methodName, parameterTypesFqn, handler))

fun invoke(vararg arguments: Any?): T {
fun invoke(): T {
val (selectedDescriptor, methodCallable) = m_selectedDescriptorWithCallable
return selectedDescriptor.handler(ResolvedMethod(selectedDescriptor, methodCallable, *arguments))
return selectedDescriptor.handler(ResolvedMethod(selectedDescriptor, methodCallable))
}

class ResolvedMethod<R>(val descriptor: MethodDescriptor<R>, private val callable: (Any?, Array<out Any?>) -> R, vararg val args: Any?) {
class ResolvedMethod<R>(val descriptor: MethodDescriptor<R>, private val callable: (Any?, Array<out Any?>) -> R) {

fun invoke(obj: Any?, vararg parameters: Any?) = try {
callable(obj, parameters)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
]]></change-notes>

<!-- please see https://jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
<idea-version since-build="212.4746.92"/>
<idea-version since-build="212.4746.92" until-build="223.*"/>

<depends>com.intellij.modules.platform</depends>
<depends>com.intellij.modules.lang</depends>
Expand Down
Loading

0 comments on commit b2b6ef0

Please sign in to comment.