Skip to content

Commit

Permalink
Fix in extension behaviour.
Browse files Browse the repository at this point in the history
Resolved: #277
  • Loading branch information
Dmitry committed Dec 16, 2021
1 parent 088bdbc commit 754511f
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class SmkUnresolvedReferenceInspectionExtension : PyUnresolvedReferenceQuickFixP
return
}
val name = fileReference.path
existing.add(CreateMissedFile(section, name, sectionName))
existing.add(CreateMissedFile(section, name, sectionName, fileReference.searchRelativelyToCurrentFolder))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import com.intellij.openapi.application.ModalityState
import com.intellij.openapi.command.undo.*
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ProjectRootManager
import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VfsUtil
import com.intellij.openapi.vfs.VirtualFileManager
Expand All @@ -26,6 +27,7 @@ class CreateMissedFile(
element: PsiElement,
private val fileName: String,
private val sectionName: String,
private val searchRelativelyToCurrentFolder: Boolean
) : LocalQuickFixAndIntentionActionOnPsiElement(element) {
companion object {
private val condaDefaultContext = """
Expand Down Expand Up @@ -57,7 +59,11 @@ class CreateMissedFile(
startElement: PsiElement,
endElement: PsiElement
) {
val targetFilePath = Paths.get(file.virtualFile.parent.path, fileName)
val dir =
if (searchRelativelyToCurrentFolder) file.virtualFile.parent else ProjectRootManager.getInstance(project).fileIndex.getContentRootForFile(
file.virtualFile
) ?: return
val targetFilePath = Paths.get(dir.path, fileName)
var firstAffectedFile = targetFilePath
while (firstAffectedFile.parent.notExists()) {
firstAffectedFile = firstAffectedFile.parent ?: break
Expand All @@ -70,7 +76,7 @@ class CreateMissedFile(
} else {
Files.delete(firstAffectedFile)
}
VirtualFileManager.getInstance().syncRefresh()
VirtualFileManager.getInstance().asyncRefresh { }
}
val redo = Runnable {
if (!supportedSections.containsKey(sectionName)) {
Expand All @@ -80,7 +86,7 @@ class CreateMissedFile(
val directoryPath = Files.createDirectories(targetFilePath.parent)
val directoryVirtualFile = VfsUtil.findFile(directoryPath, true) ?: return@Runnable
LocalFileSystem.getInstance().createChildFile(this, directoryVirtualFile, targetFilePath.name)
VirtualFileManager.getInstance().syncRefresh()
VirtualFileManager.getInstance().asyncRefresh { }
val context = supportedSections[sectionName]
if (context != null) {
// We don't use the result of 'createChildFile()' because it has inappropriate type (and throw UnsupportedOperationException)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ open class SmkFileReference(
private val textRange: TextRange,
private val stringLiteralExpression: PyStringLiteralExpression,
val path: String,
private val searchRelativelyToCurrentFolder: Boolean = true,
val searchRelativelyToCurrentFolder: Boolean = true,
) : PsiReferenceBase<SmkArgsSection>(element, textRange), PsiReferenceEx {
// Reference caching can be implemented with the 'ResolveCache' class if needed

Expand Down Expand Up @@ -159,7 +159,7 @@ open class SmkFileReference(

override fun getUnresolvedDescription(): String? = null

open fun hasAppropriateSuffix():Boolean = false
open fun hasAppropriateSuffix(): Boolean = false
}

/**
Expand All @@ -176,7 +176,8 @@ class SmkIncludeReference(
it is SmkFile && it.originalFile != element.containingFile.originalFile
}

override fun hasAppropriateSuffix() = (path.endsWith(".smk") || path == "Snakemake") && element.containingFile.virtualFile.path != path
override fun hasAppropriateSuffix() =
(path.endsWith(".smk") || path == "Snakemake") && element.containingFile.virtualFile.path != path
}

/**
Expand Down Expand Up @@ -277,6 +278,8 @@ class SmkNotebookReference(
val name = it.name.lowercase()
name.endsWith(".ipynb")
}

override fun hasAppropriateSuffix() = path.endsWith(".ipynb")
}

/**
Expand All @@ -291,10 +294,13 @@ class SmkScriptReference(
) : SmkFileReference(element, textRange, stringLiteralExpression, path) {
override fun getVariants() = collectFileSystemItemLike {
val name = it.name.lowercase()
name.endsWith(".py") or name.endsWith(".r") or name.endsWith(".rmd") or name.endsWith(".jl") or name.endsWith(".rs")
hasCorrectEnding(name)
}

override fun hasAppropriateSuffix() = path.endsWith(".ipynb")
override fun hasAppropriateSuffix() = hasCorrectEnding(path.lowercase())

private fun hasCorrectEnding(name: String) =
name.endsWith(".py") or name.endsWith(".r") or name.endsWith(".rmd") or name.endsWith(".jl") or name.endsWith(".rs")
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,38 +1,6 @@
Feature: Inspection: SmkUnresolvedReferenceInspectionExtension
Checks, that extension + inspection work

Scenario Outline: Unresolved conda file
Given a snakemake project
Given I open a file "foo.smk" with text
"""
rule NAME:
conda:
"<path>"
"""
And PyUnresolvedReferencesInspection inspection is enabled
Then I expect inspection error on <<path>> with message
"""
Unresolved reference '<path>'
"""
When I check highlighting warnings
And I invoke quick fix Create '<path>' and see text:
"""
rule NAME:
conda:
"<path>"
"""
Then the file "<path>" should have text
"""
channels:
dependencies:
"""
Examples:
| path |
| NAME.yaml |
| envs/NAME.yaml |
| ../envs/NAME.yaml |

Scenario Outline: other unresolved sections
Scenario Outline: Quick fix fot missed files
Given a snakemake project
Given I open a file "foo.smk" with text
"""
Expand All @@ -49,10 +17,18 @@ Feature: Inspection: SmkUnresolvedReferenceInspectionExtension
<section>: "<path>"
"""
Examples:
| path | section |
| NAME.py.ipynb | rule NAME: notebook |
| NAME.py | rule NAME: script |
| boo.smk | module NAME: snakefile |
| NAME.yaml | configfile |
| NAME.yaml | pepfile |
| NAME.yml | pepschema |
| path | section |
| NAME.yaml | rule NAME: conda |
| envs/NAME.yaml | rule NAME: conda |
| ../envs/NAME.yaml | rule NAME: conda |
| NAME.py.ipynb | rule NAME: notebook |
| NAME.py | rule NAME: script |
| boo.smk | module NAME: snakefile |
| NAME.yaml | configfile |
| NAME.yaml | pepfile |
| NAME.yml | pepschema |

# Impossible to check whether the file has been created because:
# 1) It is being creating asynchronously
# 2) So, we may need async refresh() (see LightTempDirTestFixtureImpl.java:137)
# It leads to Exception: "Do not perform a synchronous refresh under read lock ..."

0 comments on commit 754511f

Please sign in to comment.