Skip to content

Commit

Permalink
#23 Remove most caching calls, add todos for optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
veptechno committed Jun 9, 2022
1 parent 1885f4e commit 7698ce9
Show file tree
Hide file tree
Showing 35 changed files with 355 additions and 332 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ 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.scenarios.psi.builders.isStateDeclarationExperimental
import com.justai.jaicf.plugin.core.psi.builders.isStateDeclarationExperimental
import com.justai.jaicf.plugin.utils.VersionService
import com.justai.jaicf.plugin.utils.boundedCallExpressionOrNull
import com.justai.jaicf.plugin.utils.getBoundedLambdaArgumentOrNull
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.justai.jaicf.plugin.scenarios
package com.justai.jaicf.plugin.core

import com.intellij.openapi.project.Project
import com.justai.jaicf.plugin.trackers.JaicfVersionTracker
Expand Down
87 changes: 87 additions & 0 deletions src/main/kotlin/com/justai/jaicf/plugin/core/linker/Linker.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package com.justai.jaicf.plugin.core.linker

import com.intellij.openapi.project.Project
import com.justai.jaicf.plugin.core.psi.dto.NestedAppend
import com.justai.jaicf.plugin.core.psi.dto.Scenario
import com.justai.jaicf.plugin.core.psi.dto.State
import com.justai.jaicf.plugin.core.psi.dto.TopLevelAppend
import com.justai.jaicf.plugin.core.psi.dto.isRootState
import com.justai.jaicf.plugin.core.psi.dto.name
import com.justai.jaicf.plugin.core.psi.dto.nestedStates
import com.justai.jaicf.plugin.core.psi.dto.receiverExpression
import com.justai.jaicf.plugin.core.psi.pathValueExpressions
import com.justai.jaicf.plugin.core.psi.scenarios
import com.justai.jaicf.plugin.core.psi.topLevelAppends
import com.justai.jaicf.plugin.core.transition.statesOrSuggestions
import com.justai.jaicf.plugin.core.transition.transitToState
import com.justai.jaicf.plugin.utils.StatePathExpression
import com.justai.jaicf.plugin.utils.isExist
import com.justai.jaicf.plugin.utils.measure

val State.allStates
get() = project.measure({ "State($name).allStates" }) {
allStates().toList()
}

val State.sequenceAllStates
get() = project.measure({ "State($name).sequenceAllStates" }) {
allStates()
}

val State.usages: List<StatePathExpression>
get() = project.measure("State($name).usages") {
pathValueExpressions
.filter { this@usages in transitToState(it.usePoint, it.declaration).statesOrSuggestions() }
}

val Scenario.appendingStates: List<State>
get() = project.measure({ "Scenario($name).appendingStates" }) {
project.appends
.filter { it.scenario == this@appendingStates }
.mapNotNull { it.parentState }
}

val Project.rootScenarios: List<Scenario>
get() = measure("Project.rootScenarios") {
val appendedScenarios = appends.mapNotNull { it.scenario }.toSet()
return@measure scenarios - appendedScenarios
}

private val Project.appends
get() = measure("Project.rootScenarios") {
scenarios.flatMap { it.nestedAppends } + topLevelAppends
}

val Scenario.allAppends
get() = project.measure("Scenario($name).allAppends") {
nestedAppends + topLevelAppends
}

private fun State.allStates(previousStates: MutableSet<State> = mutableSetOf()): Sequence<State> {
if (this in previousStates) return emptySequence()

previousStates += this

var statesList = states.asSequence()
statesList += nestedAppends.asSequence()
.flatMap { it.scenario?.innerState?.allStates(previousStates) ?: emptySequence() }
if (this.isRootState) {
statesList += scenario.topLevelAppends.asSequence().filter { it.referenceToScenario?.isExist == true }
.flatMap { it.scenario?.innerState?.allStates(previousStates) ?: emptySequence() }
}

return statesList
}

val Scenario.topLevelAppends: List<TopLevelAppend>
get() = project.measure("Scenario.topLevelAppends") {
val resolver = ScenarioReferenceResolver.getInstance(project)
project.topLevelAppends.filter { append ->
append.receiverExpression?.let { resolver.resolve(it) } == this@topLevelAppends
}
}

val Scenario.nestedAppends: List<NestedAppend>
get() = project.measure("Scenario.nestedAppends") {
nestedStates.flatMap { state -> state.nestedAppends }
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.justai.jaicf.plugin.scenarios.linker
package com.justai.jaicf.plugin.core.linker

import com.intellij.psi.PsiElement
import com.justai.jaicf.plugin.scenarios.psi.ScenarioDataService
import com.justai.jaicf.plugin.scenarios.psi.dto.Scenario
import com.justai.jaicf.plugin.scenarios.psi.dto.State
import com.justai.jaicf.plugin.core.psi.ScenarioDataService
import com.justai.jaicf.plugin.core.psi.dto.Scenario
import com.justai.jaicf.plugin.core.psi.dto.State
import com.justai.jaicf.plugin.utils.isRemoved
import com.justai.jaicf.plugin.utils.measure
import org.jetbrains.kotlin.psi.KtFile

val PsiElement.framingState: State?
get() = measure({"${this.text.substringBefore('\n')}.framingState"}) {
get() = measure({ "PsiElement(${text.substringBefore('\n')}).framingState" }) {
if (isRemoved)
return@measure null

Expand All @@ -20,8 +20,10 @@ val PsiElement.framingState: State?
?.let { recursiveFindState(it.innerState, this@framingState) }
}

fun List<Scenario>.findBoundingScenario(element: PsiElement) = filter { contains(it.innerState, element) }
.minByOrNull { it.declarationElement.text.length }
fun List<Scenario>.findBoundingScenario(element: PsiElement) = element.measure("List<Scenario>.findBoundingScenario") {
filter { contains(it.innerState, element) }
.minByOrNull { it.declarationElement.text.length }
}

private fun contains(state: State, element: PsiElement) =
element.textRange.startOffset in state.stateExpression.textRange
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
package com.justai.jaicf.plugin.scenarios.linker
package com.justai.jaicf.plugin.core.linker

import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.util.PsiModificationTracker
import com.justai.jaicf.plugin.scenarios.JaicfService
import com.justai.jaicf.plugin.scenarios.psi.ScenarioDataService
import com.justai.jaicf.plugin.scenarios.psi.builders.isStateDeclaration
import com.justai.jaicf.plugin.scenarios.psi.dto.Append
import com.justai.jaicf.plugin.scenarios.psi.dto.NestedAppend
import com.justai.jaicf.plugin.scenarios.psi.dto.Scenario
import com.justai.jaicf.plugin.scenarios.psi.dto.State
import com.justai.jaicf.plugin.scenarios.psi.dto.TopLevelAppend
import com.justai.jaicf.plugin.core.JaicfService
import com.justai.jaicf.plugin.core.psi.ScenarioDataService
import com.justai.jaicf.plugin.core.psi.builders.isStateDeclaration
import com.justai.jaicf.plugin.core.psi.dto.Append
import com.justai.jaicf.plugin.core.psi.dto.NestedAppend
import com.justai.jaicf.plugin.core.psi.dto.Scenario
import com.justai.jaicf.plugin.core.psi.dto.State
import com.justai.jaicf.plugin.utils.SCENARIO_MODEL_FIELD_NAME
import com.justai.jaicf.plugin.utils.argumentExpressionOrDefaultValue
import com.justai.jaicf.plugin.utils.isExist
Expand All @@ -34,12 +33,15 @@ class ScenarioReferenceResolver(project: Project) : JaicfService(project) {

private val scenarioService = ScenarioDataService.getInstance(project)

// TODO optimize
private val resolvedReferences by cached(PsiModificationTracker.MODIFICATION_COUNT) {
mutableMapOf<Pair<KtReferenceExpression, State?>, Scenario?>()
}

fun resolve(scenarioReference: KtReferenceExpression, boundedState: State? = null) =
measure("resolve(${scenarioReference.text})") { tempResolve(scenarioReference, boundedState) }
measure("ScenarioReferenceResolver.resolve(${scenarioReference.text})") {
tempResolve(scenarioReference, boundedState)
}

private fun tempResolve(scenarioReference: KtReferenceExpression, boundedState: State? = null): Scenario? {
if (scenarioReference.isRemoved || !enabled) return null
Expand All @@ -52,10 +54,11 @@ class ScenarioReferenceResolver(project: Project) : JaicfService(project) {
}
}

private fun resolveScenario(scenarioBody: KtExpression): Scenario? {
val file = scenarioBody.containingFile as? KtFile ?: return null
return scenarioService.getScenarios(file)?.findBoundingScenario(scenarioBody)
}
private fun resolveScenario(scenarioBody: KtExpression): Scenario? =
measure("ScenarioReferenceResolver.resolveScenario(...)") {
val file = scenarioBody.containingFile as? KtFile ?: return@measure null
scenarioService.getScenarios(file)?.findBoundingScenario(scenarioBody)
}

private fun getScenarioBody(scenarioReference: KtReferenceExpression, boundedState: State? = null): KtExpression? {
when (val resolvedElement = scenarioReference.safeResolve()) {
Expand Down Expand Up @@ -107,11 +110,13 @@ class ScenarioReferenceResolver(project: Project) : JaicfService(project) {
}

private val KtDeclarationContainer.scenarioBody: KtExpression?
get() = declarations
.filter { it.name == SCENARIO_MODEL_FIELD_NAME && it is KtProperty }
.map { it as KtProperty }
.mapNotNull { it.delegateExpressionOrInitializer ?: it.getter?.initializer }
.firstOrNull()
get() = measure("KtDeclarationContainer.scenarioBody") {
declarations
.filter { it.name == SCENARIO_MODEL_FIELD_NAME && it is KtProperty }
.map { it as KtProperty }
.mapNotNull { it.delegateExpressionOrInitializer ?: it.getter?.initializer }
.firstOrNull()
}

companion object {
fun getInstance(element: PsiElement): ScenarioReferenceResolver? =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.justai.jaicf.plugin.scenarios.psi
package com.justai.jaicf.plugin.core.psi

import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.search.SearchScope
import com.justai.jaicf.plugin.scenarios.JaicfService
import com.justai.jaicf.plugin.core.JaicfService
import com.justai.jaicf.plugin.trackers.JaicfVersionTracker
import com.justai.jaicf.plugin.utils.LiveMapByFiles
import com.justai.jaicf.plugin.utils.PATH_ARGUMENT_ANNOTATION_NAME
Expand All @@ -12,8 +12,6 @@ import com.justai.jaicf.plugin.utils.findChildrenOfType
import com.justai.jaicf.plugin.utils.isExist
import com.justai.jaicf.plugin.utils.measure
import com.justai.jaicf.plugin.utils.pathExpressionsOfBoundedBlock
import java.util.concurrent.ConcurrentHashMap
import org.jetbrains.kotlin.idea.caches.project.LibraryModificationTracker
import org.jetbrains.kotlin.idea.search.allScope
import org.jetbrains.kotlin.idea.search.fileScope
import org.jetbrains.kotlin.idea.search.minus
Expand All @@ -22,17 +20,20 @@ import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
import org.jetbrains.kotlin.psi.KtOperationReferenceExpression
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import java.util.concurrent.ConcurrentHashMap

class PathValueExpressionsService(project: Project) : JaicfService(project) {

private val pathValueService = MethodsUsedPathValueService(project)

private val map = ConcurrentHashMap<KtFile, Set<PsiElement>>()

// TODO Optimize Использовать трекер psiReference в каждом файле
private val expressionsMap = LiveMapByFiles(project) { file ->
val children: Set<PsiElement> =
measure("children") { (file.findChildrenOfType<KtOperationReferenceExpression>() + file.findChildrenOfType<KtNameReferenceExpression>()).toSet() }
val children: Set<PsiElement> = measure("children") {
(file.findChildrenOfType<KtOperationReferenceExpression>() + file.findChildrenOfType<KtNameReferenceExpression>()).toSet()
}
val ktElements = map[file]
if (ktElements == children)
return@LiveMapByFiles ktElements.flatMap { it.pathExpressionsOfBoundedBlock }
Expand Down Expand Up @@ -65,29 +66,29 @@ class MethodsUsedPathValueService(project: Project) : JaicfService(project) {
val jaicfMethods
get() = (jaicfCoreMethods + jaicfProjectMethods.getNotNullValues().flatten()).filter { it.isExist }

val jaicfCoreMethods: List<KtFunction> by cached(LibraryModificationTracker.getInstance(project)) {
measure("jaicfCoreMethods") {
val jaicfCoreMethods: List<KtFunction> by cached(JaicfVersionTracker.getInstance(project)) {
measure("MethodsUsedPathValueService.jaicfCoreMethods") {
if (enabled) findUsages(project.allScope() - project.projectScope())
else emptyList()
}
}

// TODO Optimize Использовать трекер psiReference в каждом файле
private val jaicfProjectMethods = LiveMapByFiles(project) {
if (enabled) findUsages(it.fileScope())
if (enabled) measure("MethodsUsedPathValueService.jaicfProjectMethods") { findUsages(it.fileScope()) }
else emptyList()
}

private val annotationClass by cachedIfEnabled(JaicfVersionTracker.getInstance(project)) {
findClass(PLUGIN_PACKAGE, PATH_ARGUMENT_ANNOTATION_NAME, project)
}

private fun findUsages(scope: SearchScope): List<KtFunction> {
return measure("findUsages($scope)") {
private fun findUsages(scope: SearchScope): List<KtFunction> =
measure("MethodsUsedPathValueService.findUsages($scope)") {
annotationClass?.search(scope)
?.mapNotNull { it.element.getParentOfType<KtFunction>(true) }
?.distinct() ?: emptyList()
}
}

companion object {
fun getInstance(project: Project): MethodsUsedPathValueService =
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.justai.jaicf.plugin.scenarios.psi
package com.justai.jaicf.plugin.core.psi

import com.intellij.openapi.project.DumbService
import com.intellij.openapi.project.Project
Expand All @@ -13,9 +13,11 @@ import com.justai.jaicf.plugin.utils.measure
import org.jetbrains.kotlin.idea.search.projectScope
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade

fun PsiElement.search(scope: SearchScope = project.projectScope()): Collection<PsiReference> {
return measure("${text.replace("\n", "\\/")}?.search(${scope.javaClass.simpleName})") { psiReferences(scope) }
}
// TODO optimize maybe
fun PsiElement.search(scope: SearchScope = project.projectScope()): Collection<PsiReference> =
measure("${text.replace("\n", "\\/")}?.search(${scope.javaClass.simpleName})") {
psiReferences(scope)
}

private fun PsiElement.psiReferences(scope: SearchScope): Collection<PsiReference> {
if (DumbService.getInstance(project).isDumb)
Expand All @@ -39,5 +41,6 @@ fun findClass(packageFq: String, className: String, project: Project): PsiClass?
return kotlinPsiFacade.findPackage(packageFq, projectScope)?.classes?.firstOrNull { it.name == className }
}

fun PsiClass.getMethods(vararg methods: String) =
fun PsiClass.getMethods(vararg methods: String) = measure("PsiClass.getMethods") {
allMethods.filter { it.name in methods }
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.justai.jaicf.plugin.scenarios.psi
package com.justai.jaicf.plugin.core.psi

import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.justai.jaicf.plugin.scenarios.JaicfService
import com.justai.jaicf.plugin.scenarios.psi.ScenarioDataService.Companion.getInstance
import com.justai.jaicf.plugin.scenarios.psi.builders.buildScenario
import com.justai.jaicf.plugin.scenarios.psi.dto.Scenario
import com.justai.jaicf.plugin.core.JaicfService
import com.justai.jaicf.plugin.core.psi.ScenarioDataService.Companion.getInstance
import com.justai.jaicf.plugin.core.psi.builders.buildScenario
import com.justai.jaicf.plugin.core.psi.dto.Scenario
import com.justai.jaicf.plugin.trackers.JaicfVersionTracker
import com.justai.jaicf.plugin.utils.CREATE_MODEL_METHOD_NAME
import com.justai.jaicf.plugin.utils.LiveMapByFiles
Expand All @@ -25,6 +25,7 @@ class ScenarioDataService(project: Project) : JaicfService(project) {
?.getMethods(SCENARIO_METHOD_NAME, CREATE_MODEL_METHOD_NAME)
}

// TODO Optimize Использовать трекер psiReference в каждом файле
private val scenariosMap = LiveMapByFiles(project) { file ->
measure("Update scenario in ${file.name}") {
scenariosBuildMethods
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.justai.jaicf.plugin.scenarios.psi
package com.justai.jaicf.plugin.core.psi

import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.intellij.psi.search.GlobalSearchScope
import com.justai.jaicf.plugin.scenarios.JaicfService
import com.justai.jaicf.plugin.scenarios.psi.builders.buildTopLevelAppend
import com.justai.jaicf.plugin.core.JaicfService
import com.justai.jaicf.plugin.core.psi.builders.buildTopLevelAppend
import com.justai.jaicf.plugin.trackers.JaicfVersionTracker
import com.justai.jaicf.plugin.utils.APPEND_METHOD_NAME
import com.justai.jaicf.plugin.utils.LiveMapByFiles
Expand All @@ -23,6 +23,7 @@ class TopLevelAppendDataService(project: Project) : JaicfService(project) {
?.first { it.name == APPEND_METHOD_NAME }
}

// TODO Optimize Использовать трекер psiReference в каждом файле
private val appendsMap = LiveMapByFiles(project) { file ->
measure("TopLevelAppendDataService.getTopLevelAppendsUsages(${file.name}") {
getTopLevelAppendsUsages(file.fileScope()).mapNotNull { buildTopLevelAppend(it) }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.justai.jaicf.plugin.scenarios.psi.builders
package com.justai.jaicf.plugin.core.psi.builders

import com.justai.jaicf.plugin.scenarios.psi.dto.NestedAppend
import com.justai.jaicf.plugin.scenarios.psi.dto.State
import com.justai.jaicf.plugin.core.psi.dto.NestedAppend
import com.justai.jaicf.plugin.core.psi.dto.State
import com.justai.jaicf.plugin.utils.APPEND_CONTEXT_ARGUMENT_NAME
import com.justai.jaicf.plugin.utils.APPEND_METHOD_NAME
import com.justai.jaicf.plugin.utils.APPEND_OTHER_ARGUMENT_NAME
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.justai.jaicf.plugin.scenarios.psi.builders
package com.justai.jaicf.plugin.core.psi.builders

import com.justai.jaicf.plugin.scenarios.psi.dto.Scenario
import com.justai.jaicf.plugin.core.psi.dto.Scenario
import com.justai.jaicf.plugin.utils.isExist
import org.jetbrains.kotlin.psi.KtCallExpression

Expand Down
Loading

0 comments on commit 7698ce9

Please sign in to comment.