KT-32366: Refactor scratchUtils to use mostly ScratchFile

- it is done to remove dependency from the UI component `ScratchTopPanel`
- occasional use of `ScratchTopPanel` is still left (for tests mostly)
This commit is contained in:
Roman Golyshev
2019-08-16 16:54:59 +03:00
committed by Roman Golyshev
parent 6c35c40bb9
commit 70e6f738eb
12 changed files with 66 additions and 70 deletions
@@ -19,12 +19,11 @@ import com.intellij.util.Alarm
import org.jetbrains.kotlin.idea.scratch.actions.RunScratchAction import org.jetbrains.kotlin.idea.scratch.actions.RunScratchAction
import org.jetbrains.kotlin.idea.scratch.actions.RunScratchFromHereAction import org.jetbrains.kotlin.idea.scratch.actions.RunScratchFromHereAction
import org.jetbrains.kotlin.idea.scratch.actions.ScratchCompilationSupport import org.jetbrains.kotlin.idea.scratch.actions.ScratchCompilationSupport
import org.jetbrains.kotlin.idea.scratch.ui.ScratchTopPanel
class ScratchFileAutoRunner(private val project: Project) : DocumentListener { class ScratchFileAutoRunner(private val project: Project) : DocumentListener {
companion object { companion object {
fun addListener(project: Project, editor: TextEditor) { fun addListener(project: Project, editor: TextEditor) {
if (editor.getScratchPanel() != null) { if (editor.getScratchFile() != null) {
editor.editor.document.addDocumentListener(getInstance(project)) editor.editor.document.addDocumentListener(getInstance(project))
Disposer.register(editor, Disposable { Disposer.register(editor, Disposable {
editor.editor.document.removeDocumentListener(getInstance(project)) editor.editor.document.removeDocumentListener(getInstance(project))
@@ -43,11 +42,11 @@ class ScratchFileAutoRunner(private val project: Project) : DocumentListener {
val file = FileDocumentManager.getInstance().getFile(event.document) ?: return val file = FileDocumentManager.getInstance().getFile(event.document) ?: return
if (project.isDisposed) return if (project.isDisposed) return
val panel = getScratchPanel(file, project) ?: return val scratchFile = getScratchFile(file, project) ?: return
if (!panel.scratchFile.options.isInteractiveMode) return if (!scratchFile.options.isInteractiveMode) return
if (!event.newFragment.isBlank()) { if (!event.newFragment.isBlank()) {
runScratch(panel.scratchFile) runScratch(scratchFile)
} }
} }
@@ -72,7 +71,7 @@ class ScratchFileAutoRunner(private val project: Project) : DocumentListener {
) )
} }
private fun getScratchPanel(file: VirtualFile, project: Project): ScratchTopPanel? { private fun getScratchFile(file: VirtualFile, project: Project): ScratchFile? {
return getEditorWithScratchPanel(FileEditorManager.getInstance(project), file)?.second return getScratchFileFromEditorSelectedForFile(FileEditorManager.getInstance(project), file)
} }
} }
@@ -20,7 +20,7 @@ import com.intellij.icons.AllIcons
import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.AnActionEvent
import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.scratch.ScratchFileLanguageProvider import org.jetbrains.kotlin.idea.scratch.ScratchFileLanguageProvider
import org.jetbrains.kotlin.idea.scratch.getScratchPanelFromSelectedEditor import org.jetbrains.kotlin.idea.scratch.getScratchFileFromSelectedEditor
class ClearScratchAction : ScratchAction( class ClearScratchAction : ScratchAction(
KotlinBundle.message("scratch.clear.button"), KotlinBundle.message("scratch.clear.button"),
@@ -28,7 +28,7 @@ class ClearScratchAction : ScratchAction(
) { ) {
override fun actionPerformed(e: AnActionEvent) { override fun actionPerformed(e: AnActionEvent) {
val project = e.project ?: return val project = e.project ?: return
val scratchFile = getScratchPanelFromSelectedEditor(project)?.scratchFile ?: return val scratchFile = getScratchFileFromSelectedEditor(project) ?: return
val psiFile = scratchFile.getPsiFile() ?: return val psiFile = scratchFile.getPsiFile() ?: return
ScratchFileLanguageProvider.get(psiFile.language)?.getOutputHandler()?.clear(scratchFile) ScratchFileLanguageProvider.get(psiFile.language)?.getOutputHandler()?.clear(scratchFile)
@@ -23,9 +23,7 @@ import com.intellij.openapi.keymap.KeymapUtil
import com.intellij.openapi.project.DumbService import com.intellij.openapi.project.DumbService
import com.intellij.task.ProjectTaskManager import com.intellij.task.ProjectTaskManager
import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.scratch.ScratchFile import org.jetbrains.kotlin.idea.scratch.*
import org.jetbrains.kotlin.idea.scratch.SequentialScratchExecutor
import org.jetbrains.kotlin.idea.scratch.getScratchPanelFromSelectedEditor
import org.jetbrains.kotlin.idea.scratch.printDebugMessage import org.jetbrains.kotlin.idea.scratch.printDebugMessage
import org.jetbrains.kotlin.idea.scratch.LOG as log import org.jetbrains.kotlin.idea.scratch.LOG as log
@@ -42,9 +40,9 @@ class RunScratchAction : ScratchAction(
override fun actionPerformed(e: AnActionEvent) { override fun actionPerformed(e: AnActionEvent) {
val project = e.project ?: return val project = e.project ?: return
val scratchPanel = getScratchPanelFromSelectedEditor(project) ?: return val scratchFile = getScratchFileFromSelectedEditor(project) ?: return
doAction(scratchPanel.scratchFile, false) doAction(scratchFile, false)
} }
companion object { companion object {
@@ -105,8 +103,8 @@ class RunScratchAction : ScratchAction(
} }
val project = e.project ?: return val project = e.project ?: return
val panel = getScratchPanelFromSelectedEditor(project) ?: return val scratchFile = getScratchFileFromSelectedEditor(project) ?: return
e.presentation.isVisible = !ScratchCompilationSupport.isInProgress(panel.scratchFile) e.presentation.isVisible = !ScratchCompilationSupport.isInProgress(scratchFile)
} }
} }
@@ -9,7 +9,7 @@ import com.intellij.icons.AllIcons
import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.AnActionEvent
import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.scratch.ScratchFile import org.jetbrains.kotlin.idea.scratch.ScratchFile
import org.jetbrains.kotlin.idea.scratch.getScratchPanelFromSelectedEditor import org.jetbrains.kotlin.idea.scratch.getScratchFileFromSelectedEditor
class RunScratchFromHereAction : ScratchAction( class RunScratchFromHereAction : ScratchAction(
KotlinBundle.message("scratch.run.from.here.button"), KotlinBundle.message("scratch.run.from.here.button"),
@@ -18,9 +18,9 @@ class RunScratchFromHereAction : ScratchAction(
override fun actionPerformed(e: AnActionEvent) { override fun actionPerformed(e: AnActionEvent) {
val project = e.project ?: return val project = e.project ?: return
val scratchPanel = getScratchPanelFromSelectedEditor(project) ?: return val scratchFile = getScratchFileFromSelectedEditor(project) ?: return
doAction(scratchPanel.scratchFile) doAction(scratchFile)
} }
companion object { companion object {
@@ -9,16 +9,16 @@ import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider
import org.jetbrains.kotlin.idea.scratch.getScratchPanel import org.jetbrains.kotlin.idea.scratch.getScratchFile
import org.jetbrains.kotlin.idea.scratch.getScratchPanelFromSelectedEditor import org.jetbrains.kotlin.idea.scratch.getScratchFileFromSelectedEditor
import javax.swing.Icon import javax.swing.Icon
abstract class ScratchAction(message: String, icon: Icon) : AnAction(message, message, icon) { abstract class ScratchAction(message: String, icon: Icon) : AnAction(message, message, icon) {
override fun update(e: AnActionEvent) { override fun update(e: AnActionEvent) {
val scratchPanel = e.getData(CommonDataKeys.EDITOR) val scratchFile = e.getData(CommonDataKeys.EDITOR)
?.let { TextEditorProvider.getInstance().getTextEditor(it).getScratchPanel() } ?.let { TextEditorProvider.getInstance().getTextEditor(it).getScratchFile() }
?: e.project?.let { getScratchPanelFromSelectedEditor(it) } ?: e.project?.let { getScratchFileFromSelectedEditor(it) }
e.presentation.isVisible = scratchPanel != null e.presentation.isVisible = scratchFile != null
} }
} }
@@ -17,10 +17,7 @@ import com.intellij.psi.impl.source.tree.LeafPsiElement
import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.idea.core.util.getLineCount import org.jetbrains.kotlin.idea.core.util.getLineCount
import org.jetbrains.kotlin.idea.refactoring.getLineNumber import org.jetbrains.kotlin.idea.refactoring.getLineNumber
import org.jetbrains.kotlin.idea.scratch.ScratchExpression import org.jetbrains.kotlin.idea.scratch.*
import org.jetbrains.kotlin.idea.scratch.getScratchPanel
import org.jetbrains.kotlin.idea.scratch.isKotlinScratch
import org.jetbrains.kotlin.idea.scratch.isKotlinWorksheet
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType import org.jetbrains.kotlin.psi.psiUtil.findDescendantOfType
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
@@ -72,9 +69,7 @@ class ScratchRunLineMarkerContributor : RunLineMarkerContributor() {
} }
private fun getLastExecutedExpression(element: PsiElement): ScratchExpression? { private fun getLastExecutedExpression(element: PsiElement): ScratchExpression? {
val panel = getSingleOpenedTextEditor(element.containingFile)?.getScratchPanel() ?: return null val scratchFile = getSingleOpenedTextEditor(element.containingFile)?.getScratchFile() ?: return null
val scratchFile = panel.scratchFile
if (!scratchFile.options.isRepl) return null if (!scratchFile.options.isRepl) return null
val replExecutor = scratchFile.replScratchExecutor ?: return null val replExecutor = scratchFile.replScratchExecutor ?: return null
return replExecutor.getFirstNewExpression() return replExecutor.getFirstNewExpression()
@@ -8,8 +8,7 @@ package org.jetbrains.kotlin.idea.scratch.actions
import com.intellij.icons.AllIcons import com.intellij.icons.AllIcons
import com.intellij.openapi.actionSystem.AnActionEvent import com.intellij.openapi.actionSystem.AnActionEvent
import org.jetbrains.kotlin.idea.KotlinBundle import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.idea.scratch.getScratchPanelFromSelectedEditor import org.jetbrains.kotlin.idea.scratch.getScratchFileFromSelectedEditor
import org.jetbrains.kotlin.idea.scratch.LOG as log
class StopScratchAction : ScratchAction( class StopScratchAction : ScratchAction(
KotlinBundle.message("scratch.stop.button"), KotlinBundle.message("scratch.stop.button"),
@@ -24,8 +23,8 @@ class StopScratchAction : ScratchAction(
super.update(e) super.update(e)
val project = e.project ?: return val project = e.project ?: return
val panel = getScratchPanelFromSelectedEditor(project) ?: return val scratchFile = getScratchFileFromSelectedEditor(project) ?: return
e.presentation.isEnabledAndVisible = ScratchCompilationSupport.isInProgress(panel.scratchFile) e.presentation.isEnabledAndVisible = ScratchCompilationSupport.isInProgress(scratchFile)
} }
} }
@@ -15,6 +15,7 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Disposer import com.intellij.openapi.util.Disposer
import com.intellij.openapi.util.Key import com.intellij.openapi.util.Key
import com.intellij.openapi.vfs.VirtualFile import com.intellij.openapi.vfs.VirtualFile
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.idea.actions.KOTLIN_WORKSHEET_EXTENSION import org.jetbrains.kotlin.idea.actions.KOTLIN_WORKSHEET_EXTENSION
import org.jetbrains.kotlin.idea.scratch.ui.ScratchPanelListener import org.jetbrains.kotlin.idea.scratch.ui.ScratchPanelListener
import org.jetbrains.kotlin.idea.scratch.ui.ScratchTopPanel import org.jetbrains.kotlin.idea.scratch.ui.ScratchTopPanel
@@ -32,31 +33,35 @@ val VirtualFile.isKotlinWorksheet: Boolean
val VirtualFile.isKotlinScratch: Boolean val VirtualFile.isKotlinScratch: Boolean
get() = ScratchFileService.getInstance().getRootType(this) is ScratchRootType get() = ScratchFileService.getInstance().getRootType(this) is ScratchRootType
fun getEditorWithoutScratchPanel(fileManager: FileEditorManager, virtualFile: VirtualFile): TextEditor? { fun getEditorWithoutScratchFile(fileManager: FileEditorManager, virtualFile: VirtualFile): TextEditor? {
val editor = fileManager.getSelectedEditor(virtualFile) as? TextEditor val editor = fileManager.getSelectedEditor(virtualFile) as? TextEditor
if (editor?.scratchTopPanel != null) return null if (editor?.getScratchFile() != null) return null
return editor return editor
} }
fun getEditorWithScratchPanel(fileManager: FileEditorManager, virtualFile: VirtualFile): Pair<TextEditor, ScratchTopPanel>? { @TestOnly
fun getScratchPanelFromEditorSelectedForFile(fileManager: FileEditorManager, virtualFile: VirtualFile): ScratchTopPanel? {
val editor = fileManager.getSelectedEditor(virtualFile) as? TextEditor ?: return null val editor = fileManager.getSelectedEditor(virtualFile) as? TextEditor ?: return null
val scratchTopPanel = editor.scratchTopPanel ?: return null return editor.scratchTopPanel
return editor to scratchTopPanel
} }
fun getAllEditorsWithScratchPanel(project: Project): List<Pair<TextEditor, ScratchTopPanel>> = fun getScratchFileFromEditorSelectedForFile(fileManager: FileEditorManager, virtualFile: VirtualFile): ScratchFile? {
FileEditorManager.getInstance(project).allEditors.filterIsInstance<TextEditor>().mapNotNull { val editor = fileManager.getSelectedEditor(virtualFile) as? TextEditor ?: return null
val panel = it.scratchTopPanel return editor.getScratchFile()
if (panel != null) it to panel else null }
}
fun getScratchPanelFromSelectedEditor(project: Project): ScratchTopPanel? { fun getAllEditorsWithScratchFiles(project: Project): List<TextEditor> =
FileEditorManager.getInstance(project).allEditors
.filterIsInstance<TextEditor>()
.filter { it.getScratchFile() != null }
fun getScratchFileFromSelectedEditor(project: Project): ScratchFile? {
val editor = FileEditorManager.getInstance(project).selectedTextEditor ?: return null val editor = FileEditorManager.getInstance(project).selectedTextEditor ?: return null
return TextEditorProvider.getInstance().getTextEditor(editor).getScratchPanel() return TextEditorProvider.getInstance().getTextEditor(editor).getScratchFile()
} }
fun TextEditor.getScratchPanel(): ScratchTopPanel? { fun TextEditor.getScratchFile(): ScratchFile? {
return scratchTopPanel return scratchTopPanel?.scratchFile
} }
fun TextEditor.addScratchPanel(panel: ScratchTopPanel) { fun TextEditor.addScratchPanel(panel: ScratchTopPanel) {
@@ -31,14 +31,14 @@ class ScratchFileHook(val project: Project) : ProjectComponent {
} }
override fun projectClosed() { override fun projectClosed() {
getAllEditorsWithScratchPanel(project).forEach { (editor, _) -> editor.removeScratchPanel() } getAllEditorsWithScratchFiles(project).forEach { editor -> editor.removeScratchPanel() }
} }
private inner class ScratchEditorListener : FileEditorManagerListener { private inner class ScratchEditorListener : FileEditorManagerListener {
override fun fileOpened(source: FileEditorManager, file: VirtualFile) { override fun fileOpened(source: FileEditorManager, file: VirtualFile) {
if (!isPluggable(file)) return if (!isPluggable(file)) return
val editor = getEditorWithoutScratchPanel(source, file) ?: return val editor = getEditorWithoutScratchFile(source, file) ?: return
ScratchTopPanel.createPanel(project, file, editor) ScratchTopPanel.createPanel(project, file, editor)
@@ -176,10 +176,10 @@ abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() {
ScriptDependenciesManager.updateScriptDependenciesSynchronously(scratchFile, project) ScriptDependenciesManager.updateScriptDependenciesSynchronously(scratchFile, project)
val (_, scratchPanel) = getEditorWithScratchPanel(myManager, myFixture.file.virtualFile) val scratchPanel= getScratchPanelFromEditorSelectedForFile(myManager, myFixture.file.virtualFile)
?: error("Couldn't find scratch panel") ?: error("Couldn't find scratch panel")
configureOptions(scratchPanel, text, myFixture.module) configureOptions(scratchPanel.scratchFile, text, myFixture.module)
return scratchPanel return scratchPanel
} }
@@ -189,12 +189,12 @@ abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() {
ScriptDependenciesManager.updateScriptDependenciesSynchronously(worksheetFile, project) ScriptDependenciesManager.updateScriptDependenciesSynchronously(worksheetFile, project)
val (_, scratchPanel) = getEditorWithScratchPanel(myManager, myFixture.file.virtualFile) val scratchPanel = getScratchPanelFromEditorSelectedForFile(myManager, myFixture.file.virtualFile)
?: error("Couldn't find scratch panel") ?: error("Couldn't find scratch panel")
// We want to check that correct module is selected automatically, // We want to check that correct module is selected automatically,
// that's why we set `module` to null so it wouldn't be changed // that's why we set `module` to null so it wouldn't be changed
configureOptions(scratchPanel, text, null) configureOptions(scratchPanel.scratchFile, text, null)
return scratchPanel return scratchPanel
} }
@@ -234,9 +234,9 @@ abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() {
protected fun stopReplProcess() { protected fun stopReplProcess() {
if (myFixture.file != null) { if (myFixture.file != null) {
val (_, scratchPanel) = getEditorWithScratchPanel(myManager, myFixture.file.virtualFile) val scratchFile = getScratchFileFromEditorSelectedForFile(myManager, myFixture.file.virtualFile)
?: error("Couldn't find scratch panel") ?: error("Couldn't find scratch panel")
scratchPanel.scratchFile.replScratchExecutor?.stopAndWait() scratchFile.replScratchExecutor?.stopAndWait()
} }
UIUtil.dispatchAllInvocationEvents() UIUtil.dispatchAllInvocationEvents()
@@ -310,20 +310,20 @@ abstract class AbstractScratchRunActionTest : FileEditorManagerTestCase() {
} }
fun configureOptions( fun configureOptions(
scratchPanel: ScratchTopPanel, scratchFile: ScratchFile,
fileText: String, fileText: String,
module: Module? module: Module?
) { ) {
if (InTextDirectivesUtils.getPrefixedBoolean(fileText, "// INTERACTIVE_MODE: ") != true) { if (InTextDirectivesUtils.getPrefixedBoolean(fileText, "// INTERACTIVE_MODE: ") != true) {
scratchPanel.setInteractiveMode(false) scratchFile.saveOptions { copy(isInteractiveMode = false) }
} }
if (InTextDirectivesUtils.getPrefixedBoolean(fileText, "// REPL_MODE: ") == true) { if (InTextDirectivesUtils.getPrefixedBoolean(fileText, "// REPL_MODE: ") == true) {
scratchPanel.setReplMode(true) scratchFile.saveOptions { copy(isRepl = true) }
} }
if (module != null && !InTextDirectivesUtils.isDirectiveDefined(fileText, "// NO_MODULE")) { if (module != null && !InTextDirectivesUtils.isDirectiveDefined(fileText, "// NO_MODULE")) {
scratchPanel.scratchFile.setModule(module) scratchFile.setModule(module)
} }
} }
@@ -23,7 +23,7 @@ abstract class AbstractScratchLineMarkersTest : AbstractLineMarkersTest() {
fun doScratchTest(path: String) { fun doScratchTest(path: String) {
val fileText = FileUtil.loadFile(File(path)) val fileText = FileUtil.loadFile(File(path))
val scratchFile = ScratchRootType.getInstance().createScratchFile( val scratchVirtualFile = ScratchRootType.getInstance().createScratchFile(
project, project,
"scratch.kts", "scratch.kts",
KotlinLanguage.INSTANCE, KotlinLanguage.INSTANCE,
@@ -31,14 +31,14 @@ abstract class AbstractScratchLineMarkersTest : AbstractLineMarkersTest() {
ScratchFileService.Option.create_if_missing ScratchFileService.Option.create_if_missing
) ?: error("Couldn't create scratch file") ) ?: error("Couldn't create scratch file")
myFixture.openFileInEditor(scratchFile) myFixture.openFileInEditor(scratchVirtualFile)
ScriptDependenciesManager.updateScriptDependenciesSynchronously(scratchFile, project) ScriptDependenciesManager.updateScriptDependenciesSynchronously(scratchVirtualFile, project)
val (_, scratchPanel) = getEditorWithScratchPanel(FileEditorManager.getInstance(project), myFixture.file.virtualFile) val scratchFile = getScratchFileFromEditorSelectedForFile(FileEditorManager.getInstance(project), myFixture.file.virtualFile)
?: error("Couldn't find scratch panel") ?: error("Couldn't find scratch panel")
configureOptions(scratchPanel, fileText, null) configureOptions(scratchFile, fileText, null)
val project = myFixture.project val project = myFixture.project
val document = myFixture.editor.document val document = myFixture.editor.document
@@ -27,7 +27,7 @@ class ScratchOptionsTest : AbstractScratchRunActionTest() {
myManager.closeFile(myFixture.file.virtualFile) myManager.closeFile(myFixture.file.virtualFile)
myManager.openFile(myFixture.file.virtualFile, true) myManager.openFile(myFixture.file.virtualFile, true)
val (_, scratchPanelAfterClosingFile) = getEditorWithScratchPanel(myManager, myFixture.file.virtualFile) ?: error("Couldn't find scratch panel") val scratchPanelAfterClosingFile = getScratchPanelFromEditorSelectedForFile(myManager, myFixture.file.virtualFile) ?: error("Couldn't find scratch panel")
Assert.assertEquals("Wrong value for isRepl checkbox", newIsReplValue, scratchPanelAfterClosingFile.scratchFile.options.isRepl) Assert.assertEquals("Wrong value for isRepl checkbox", newIsReplValue, scratchPanelAfterClosingFile.scratchFile.options.isRepl)
Assert.assertEquals( Assert.assertEquals(
@@ -55,12 +55,12 @@ class ScratchOptionsTest : AbstractScratchRunActionTest() {
} }
fun testCurrentModuleIsAutomaticallySelectedForWorksheetFile() { fun testCurrentModuleIsAutomaticallySelectedForWorksheetFile() {
val scratchTopPanel = configureWorksheetByText("worksheet.ws.kts", testScratchText()) val scratchFile = configureWorksheetByText("worksheet.ws.kts", testScratchText()).scratchFile
Assert.assertEquals( Assert.assertEquals(
"Selected module should be equal to current project module for worksheets", "Selected module should be equal to current project module for worksheets",
myFixture.module, myFixture.module,
scratchTopPanel.scratchFile.module scratchFile.module
) )
} }