diff --git a/gradle.properties b/gradle.properties index b2b8d95..e557a67 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ pluginGroup = com.justai.jaicf.plugin pluginName = Jaicf Plugin -pluginVersion = 212-0.5.3 +pluginVersion = 212-0.5.4 pluginSinceBuild = 212 pluginUntilBuild = 212.* diff --git a/src/main/kotlin/com/justai/jaicf/plugin/contexts/StateContext.kt b/src/main/kotlin/com/justai/jaicf/plugin/contexts/StateContext.kt index 810b18e..edea2b2 100644 --- a/src/main/kotlin/com/justai/jaicf/plugin/contexts/StateContext.kt +++ b/src/main/kotlin/com/justai/jaicf/plugin/contexts/StateContext.kt @@ -3,12 +3,16 @@ package com.justai.jaicf.plugin.contexts import com.intellij.codeInsight.template.TemplateActionContext import com.intellij.codeInsight.template.TemplateContextType import com.justai.jaicf.plugin.scenarios.psi.builders.isStateDeclaration +import com.justai.jaicf.plugin.utils.VersionService import com.justai.jaicf.plugin.utils.boundedCallExpressionOrNull import com.justai.jaicf.plugin.utils.getBoundedLambdaArgumentOrNull +import com.justai.jaicf.plugin.utils.isJaicfInclude import org.jetbrains.kotlin.psi.KtCallExpression class StateContext : TemplateContextType("STATE", "State") { override fun isInContext(templateActionContext: TemplateActionContext): Boolean { + if (!VersionService.getInstance(templateActionContext.file.project).isJaicfInclude) return false + val probeElement = templateActionContext.file.findElementAt(templateActionContext.startOffset) val boundedLambda = probeElement?.getBoundedLambdaArgumentOrNull(KtCallExpression::class.java) ?: return false return boundedLambda.boundedCallExpressionOrNull?.isStateDeclaration == true diff --git a/src/main/kotlin/com/justai/jaicf/plugin/inspections/Visitors.kt b/src/main/kotlin/com/justai/jaicf/plugin/inspections/Visitors.kt index 3ec0ea7..d0ef51f 100644 --- a/src/main/kotlin/com/justai/jaicf/plugin/inspections/Visitors.kt +++ b/src/main/kotlin/com/justai/jaicf/plugin/inspections/Visitors.kt @@ -11,8 +11,10 @@ import com.justai.jaicf.plugin.notifications.checkEnvironmentAndNotify import com.justai.jaicf.plugin.scenarios.psi.ScenarioDataService import com.justai.jaicf.plugin.scenarios.psi.dto.State import com.justai.jaicf.plugin.utils.StatePathExpression +import com.justai.jaicf.plugin.utils.VersionService import com.justai.jaicf.plugin.utils.innerPathExpressions import com.justai.jaicf.plugin.utils.isExist +import com.justai.jaicf.plugin.utils.isJaicfInclude import org.jetbrains.kotlin.psi.KtAnnotated import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtCallExpression @@ -86,7 +88,9 @@ abstract class AnnotatedElementVisitor(holder: ProblemsHolder) : VisitorBase(hol abstract class VisitorBase(private val holder: ProblemsHolder) : PsiElementVisitor() { fun checkEnvironmentAndNotify(element: PsiElement): Boolean { + if (VersionService.getInstance(element)?.isJaicfInclude == false) return false val project = if (element.isExist) element.project else return false + return checkEnvironmentAndNotify(project) } diff --git a/src/main/kotlin/com/justai/jaicf/plugin/providers/LineMarkerProviders.kt b/src/main/kotlin/com/justai/jaicf/plugin/providers/LineMarkerProviders.kt index 03c6218..91b9639 100644 --- a/src/main/kotlin/com/justai/jaicf/plugin/providers/LineMarkerProviders.kt +++ b/src/main/kotlin/com/justai/jaicf/plugin/providers/LineMarkerProviders.kt @@ -16,10 +16,12 @@ import com.justai.jaicf.plugin.scenarios.psi.dto.name import com.justai.jaicf.plugin.scenarios.transition.absolutePath import com.justai.jaicf.plugin.scenarios.transition.statesOrSuggestions import com.justai.jaicf.plugin.scenarios.transition.transitToState +import com.justai.jaicf.plugin.utils.VersionService import com.justai.jaicf.plugin.utils.asLeaf import com.justai.jaicf.plugin.utils.findChildOfType import com.justai.jaicf.plugin.utils.getBoundedCallExpressionOrNull import com.justai.jaicf.plugin.utils.holderExpression +import com.justai.jaicf.plugin.utils.isJaicfInclude import com.justai.jaicf.plugin.utils.isRemoved import com.justai.jaicf.plugin.utils.pathExpressionsOfBoundedBlock import javax.swing.Icon @@ -34,6 +36,8 @@ class StatePathLineMarkerProvider : RelatedItemLineMarkerProvider() { element: PsiElement, result: MutableCollection>, ) { + if (VersionService.getInstance(element)?.isJaicfInclude == false) return + if (element.isRemoved || isNotLeafIdentifier(element)) return val pathExpressions = element.pathExpressionsOfBoundedBlock @@ -52,7 +56,7 @@ class StatePathLineMarkerProvider : RelatedItemLineMarkerProvider() { private fun buildLineMarker( expression: PsiElement, - markerHolderLeaf: LeafPsiElement + markerHolderLeaf: LeafPsiElement, ): RelatedItemLineMarkerInfo = NavigationGutterIconBuilder.create(GO_TO_STATES) .setAlignment(LEFT) @@ -68,6 +72,8 @@ class StateIdentifierLineMarkerProvider : RelatedItemLineMarkerProvider() { element: PsiElement, result: MutableCollection>, ) { + if (VersionService.getInstance(element)?.isJaicfInclude == false) return + if (element.isRemoved || isNotLeafIdentifier(element)) return val callExpression = element.getBoundedCallExpressionOrNull(KtValueArgument::class.java) ?: return diff --git a/src/main/kotlin/com/justai/jaicf/plugin/providers/StateIdentifierReferenceContributor.kt b/src/main/kotlin/com/justai/jaicf/plugin/providers/StateIdentifierReferenceContributor.kt index c4cc44e..81a7f95 100644 --- a/src/main/kotlin/com/justai/jaicf/plugin/providers/StateIdentifierReferenceContributor.kt +++ b/src/main/kotlin/com/justai/jaicf/plugin/providers/StateIdentifierReferenceContributor.kt @@ -17,10 +17,12 @@ import com.justai.jaicf.plugin.scenarios.linker.usages import com.justai.jaicf.plugin.scenarios.psi.builders.isStateDeclaration import com.justai.jaicf.plugin.utils.STATE_NAME_ARGUMENT_NAME import com.justai.jaicf.plugin.utils.StatePathExpression +import com.justai.jaicf.plugin.utils.VersionService import com.justai.jaicf.plugin.utils.boundedCallExpressionOrNull import com.justai.jaicf.plugin.utils.getBoundedValueArgumentOrNull import com.justai.jaicf.plugin.utils.holderExpression import com.justai.jaicf.plugin.utils.identifier +import com.justai.jaicf.plugin.utils.isJaicfInclude import com.justai.jaicf.plugin.utils.rangeToEndOf import org.jetbrains.kotlin.psi.KtStringTemplateExpression import org.jetbrains.kotlin.psi.KtValueArgument @@ -38,6 +40,7 @@ class StateIdentifierReferenceProvider : PsiReferenceProvider() { @ExperimentalStdlibApi override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array { + if (VersionService.getInstance(element)?.isJaicfInclude == false) return emptyArray() val argument = element.getBoundedValueArgumentOrNull() ?: return emptyArray() diff --git a/src/main/kotlin/com/justai/jaicf/plugin/providers/StatePathCompletionContributor.kt b/src/main/kotlin/com/justai/jaicf/plugin/providers/StatePathCompletionContributor.kt index a45318e..ed4b99f 100644 --- a/src/main/kotlin/com/justai/jaicf/plugin/providers/StatePathCompletionContributor.kt +++ b/src/main/kotlin/com/justai/jaicf/plugin/providers/StatePathCompletionContributor.kt @@ -9,8 +9,9 @@ import com.intellij.codeInsight.completion.CompletionResultSet import com.intellij.codeInsight.completion.CompletionType import com.intellij.codeInsight.completion.SkipAutopopupInStrings import com.intellij.codeInsight.editorActions.TypedHandlerDelegate +import com.intellij.codeInsight.editorActions.TypedHandlerDelegate.Result.CONTINUE +import com.intellij.codeInsight.editorActions.TypedHandlerDelegate.Result.STOP import com.intellij.codeInsight.lookup.LookupElementBuilder -import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project import com.intellij.patterns.PlatformPatterns @@ -18,6 +19,8 @@ import com.intellij.psi.PsiElement import com.intellij.psi.PsiFile import com.intellij.util.ProcessingContext import com.intellij.util.ThreeState +import com.intellij.util.ThreeState.NO +import com.intellij.util.ThreeState.UNSURE import com.justai.jaicf.plugin.scenarios.linker.allStates import com.justai.jaicf.plugin.scenarios.linker.framingState import com.justai.jaicf.plugin.scenarios.psi.dto.State @@ -28,8 +31,10 @@ import com.justai.jaicf.plugin.scenarios.transition.parent import com.justai.jaicf.plugin.scenarios.transition.statesOrSuggestions import com.justai.jaicf.plugin.scenarios.transition.transit import com.justai.jaicf.plugin.utils.StatePathExpression.Joined +import com.justai.jaicf.plugin.utils.VersionService import com.justai.jaicf.plugin.utils.boundedPathExpression import com.justai.jaicf.plugin.utils.isComplexStringTemplate +import com.justai.jaicf.plugin.utils.isJaicfInclude import com.justai.jaicf.plugin.utils.stringValueOrNull import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty @@ -47,6 +52,8 @@ class StatePathCompletionProvider : CompletionProvider() { context: ProcessingContext, resultSet: CompletionResultSet, ) { + if (!VersionService.getInstance(parameters.originalFile.project).isJaicfInclude) return + val statePathExpression = parameters.position.boundedPathExpression as? Joined ?: return val pathExpression = statePathExpression.declaration val pathBeforeCaret = pathExpression.stringValueOrNull?.substringBeforeCaret() ?: return @@ -89,10 +96,10 @@ class StatePathCompletionProvider : CompletionProvider() { private fun isLastTransitionFitIntoElement(path: StatePath, parameters: CompletionParameters) = !( - path.lexemes.isNotEmpty() && - path.lexemes.last() is Lexeme.Transition && - path.lexemes.last().identifier.length > parameters.position.text.substringBeforeCaret().length - ) + path.lexemes.isNotEmpty() && + path.lexemes.last() is Lexeme.Transition && + path.lexemes.last().identifier.length > parameters.position.text.substringBeforeCaret().length + ) private fun String.substringBeforeCaret() = substringBefore("IntellijIdeaRulezzz") @@ -108,10 +115,6 @@ class StatePathCompletionProvider : CompletionProvider() { else this } - - companion object { - private val logger = Logger.getInstance(StatePathCompletionProvider::class.java) - } } class StatePathAutoPopupHandler : TypedHandlerDelegate() { @@ -121,17 +124,19 @@ class StatePathAutoPopupHandler : TypedHandlerDelegate() { * @return [TypedHandlerDelegate.Result.STOP] if we can try suggest state completions * */ override fun checkAutoPopup(charTyped: Char, project: Project, editor: Editor, file: PsiFile): Result { + if (!VersionService.getInstance(project).isJaicfInclude) return CONTINUE + if (charTyped !in supportedCharsForPopup) { - return Result.CONTINUE + return CONTINUE } - val element = file.findElementAt(editor.caretModel.offset) ?: return Result.CONTINUE + val element = file.findElementAt(editor.caretModel.offset) ?: return CONTINUE if (element.boundedPathExpression != null) { AutoPopupController.getInstance(project).autoPopupMemberLookup(editor, null) - return Result.STOP + return STOP } - return Result.CONTINUE + return CONTINUE } } @@ -141,18 +146,20 @@ class StatePathCompletionConfidenceProvider : CompletionConfidence() { * Skips completion if given [contextElement] is not valid state path * */ override fun shouldSkipAutopopup(contextElement: PsiElement, psiFile: PsiFile, offset: Int): ThreeState { + if (!VersionService.getInstance(psiFile.project).isJaicfInclude) return UNSURE + return if (SkipAutopopupInStrings.isInStringLiteral(contextElement)) { val charTyped = psiFile.text[offset - 1] if (charTyped !in supportedCharsForPopup) { - return ThreeState.UNSURE + return UNSURE } return if (contextElement.boundedPathExpression != null) - ThreeState.NO + NO else - ThreeState.UNSURE + UNSURE } else - ThreeState.UNSURE + UNSURE } } diff --git a/src/main/kotlin/com/justai/jaicf/plugin/providers/StatePathReferenceContributor.kt b/src/main/kotlin/com/justai/jaicf/plugin/providers/StatePathReferenceContributor.kt index f241dcb..79bedb6 100644 --- a/src/main/kotlin/com/justai/jaicf/plugin/providers/StatePathReferenceContributor.kt +++ b/src/main/kotlin/com/justai/jaicf/plugin/providers/StatePathReferenceContributor.kt @@ -20,7 +20,9 @@ import com.justai.jaicf.plugin.scenarios.transition.statesOrSuggestions import com.justai.jaicf.plugin.scenarios.transition.transit import com.justai.jaicf.plugin.scenarios.transition.transitionsWithRanges import com.justai.jaicf.plugin.utils.StatePathExpression.Joined +import com.justai.jaicf.plugin.utils.VersionService import com.justai.jaicf.plugin.utils.boundedPathExpression +import com.justai.jaicf.plugin.utils.isJaicfInclude import com.justai.jaicf.plugin.utils.isSimpleStringTemplate import com.justai.jaicf.plugin.utils.rangeToEndOf import com.justai.jaicf.plugin.utils.stringValueOrNull @@ -38,6 +40,7 @@ class StatePathReferenceContributor : PsiReferenceContributor() { class StatePathReferenceProvider : PsiReferenceProvider() { override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array { + if (VersionService.getInstance(element)?.isJaicfInclude == false) return emptyArray() val statePathExpression = element.boundedPathExpression as? Joined ?: return emptyArray() val pathExpression = statePathExpression.declaration diff --git a/src/main/kotlin/com/justai/jaicf/plugin/scenarios/linker/ScenarioReferenceResolver.kt b/src/main/kotlin/com/justai/jaicf/plugin/scenarios/linker/ScenarioReferenceResolver.kt index 56819ad..c81b375 100644 --- a/src/main/kotlin/com/justai/jaicf/plugin/scenarios/linker/ScenarioReferenceResolver.kt +++ b/src/main/kotlin/com/justai/jaicf/plugin/scenarios/linker/ScenarioReferenceResolver.kt @@ -14,7 +14,7 @@ import com.justai.jaicf.plugin.utils.SCENARIO_MODEL_FIELD_NAME import com.justai.jaicf.plugin.utils.argumentExpressionOrDefaultValue import com.justai.jaicf.plugin.utils.isExist import com.justai.jaicf.plugin.utils.isRemoved -import org.jetbrains.kotlin.nj2k.postProcessing.resolve +import com.justai.jaicf.plugin.utils.safeResolve import org.jetbrains.kotlin.psi.KtCallExpression import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtDeclarationContainer @@ -53,7 +53,7 @@ class ScenarioReferenceResolver(project: Project) : JaicfService(project) { } private fun getScenarioBody(scenarioReference: KtReferenceExpression, boundedState: State? = null): KtExpression? { - when (val resolvedElement = scenarioReference.resolve()) { + when (val resolvedElement = scenarioReference.safeResolve()) { is KtObjectDeclaration -> { return resolvedElement.scenarioBody } @@ -87,7 +87,7 @@ class ScenarioReferenceResolver(project: Project) : JaicfService(project) { private fun getScenarioBody(callExpression: KtCallExpression): KtExpression? { if (callExpression.isStateDeclaration) return callExpression - return when (val resolved = callExpression.referenceExpression()?.resolve()) { + return when (val resolved = callExpression.referenceExpression()?.safeResolve()) { is KtNamedFunction -> (resolved.initializer as? KtCallExpression)?.let { if (it.isStateDeclaration) it else null } diff --git a/src/main/kotlin/com/justai/jaicf/plugin/utils/ConstantResolver.kt b/src/main/kotlin/com/justai/jaicf/plugin/utils/ConstantResolver.kt index 42dfae0..8afb737 100644 --- a/src/main/kotlin/com/justai/jaicf/plugin/utils/ConstantResolver.kt +++ b/src/main/kotlin/com/justai/jaicf/plugin/utils/ConstantResolver.kt @@ -4,7 +4,6 @@ import com.intellij.openapi.project.Project import com.intellij.psi.PsiElement import com.intellij.psi.util.PsiModificationTracker import org.jetbrains.kotlin.idea.inspections.AbstractPrimitiveRangeToInspection.Companion.constantValueOrNull -import org.jetbrains.kotlin.nj2k.postProcessing.resolve import org.jetbrains.kotlin.psi.KtBinaryExpression import org.jetbrains.kotlin.psi.KtBlockStringTemplateEntry import org.jetbrains.kotlin.psi.KtExpression @@ -56,7 +55,7 @@ class ConstantResolver(project: Project) { element.expression?.let { resolve(it) } element is KtNameReferenceExpression -> - (element.resolve() as? KtProperty)?.initializer?.let { resolve(it) } + (element.safeResolve() as? KtProperty)?.initializer?.let { resolve(it) } ?: element.constantValueOrNull()?.value?.toString() element is KtExpression -> diff --git a/src/main/kotlin/com/justai/jaicf/plugin/utils/PsiElementUtils.kt b/src/main/kotlin/com/justai/jaicf/plugin/utils/PsiElementUtils.kt index 7af1b84..573184f 100644 --- a/src/main/kotlin/com/justai/jaicf/plugin/utils/PsiElementUtils.kt +++ b/src/main/kotlin/com/justai/jaicf/plugin/utils/PsiElementUtils.kt @@ -1,5 +1,6 @@ package com.justai.jaicf.plugin.utils +import com.intellij.openapi.project.IndexNotReadyException import com.intellij.openapi.util.TextRange import com.intellij.psi.PsiElement import com.intellij.psi.impl.source.tree.LeafPsiElement @@ -31,6 +32,7 @@ import org.jetbrains.kotlin.types.AbbreviatedType import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.typeUtil.supertypes import org.jetbrains.kotlin.utils.ifEmpty +import java.lang.Integer.min fun KtCallElement.argumentConstantValue(identifier: String) = argumentExpression(identifier)?.stringValueOrNull @@ -115,11 +117,18 @@ val KtCallElement.referenceExpression: KtReferenceExpression? get() = findChildOfType() val KtReferenceExpression.resolveToSource: KtFunction? - get() = (resolve() as? KtFunction)?.let { + get() = (safeResolve() as? KtFunction)?.let { if (it.isBinary) it.source else it } +fun KtReferenceExpression.safeResolve() = + try { + resolve() + } catch (e: IndexNotReadyException) { + null + } + inline fun PsiElement.findChildOfType(): T? { return PsiTreeUtil.findChildOfType(this, T::class.java) } @@ -131,8 +140,8 @@ inline fun PsiElement.findChildrenOfType(): Collection< fun KtCallExpression.isOverride(receiver: FqName, funName: String, parameters: List? = null) = try { isExist && callName() == funName - && isReceiverInheritedOf(receiver) - && (parameters?.let { it == parametersTypes } ?: true) + && isReceiverInheritedOf(receiver) + && (parameters?.let { it == parametersTypes } ?: true) } catch (e: NullPointerException) { false } @@ -173,7 +182,7 @@ fun PsiElement.getBoundedLambdaArgumentOrNull(vararg stopAt: Class>, - allowedTypes: List>? = null + allowedTypes: List>? = null, ): PsiElement? { var currentParent = parent while (currentParent != null) { @@ -250,8 +259,8 @@ fun PsiElement.rangeToEndOf(parent: PsiElement): TextRange { val KtBinaryExpression.operands get() = left?.let { l -> right?.let { r -> listOf(l, r) } } val KtBinaryExpression.isStringConcatenationExpression - get() = (operationReference.resolve() as? KtFunction)?.let { declaration -> + get() = (operationReference.safeResolve() as? KtFunction)?.let { declaration -> declaration.name == "plus" && - declaration.receiverName == "kotlin.String" && - declaration.parametersTypes.singleOrNull() == "kotlin.Any" + declaration.receiverName == "kotlin.String" && + declaration.parametersTypes.singleOrNull() == "kotlin.Any" } ?: false diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 9f21d11..141dc8a 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -96,5 +96,7 @@ + +