Skip to content

Commit

Permalink
Fix "Create procedure" placement of script
Browse files Browse the repository at this point in the history
  • Loading branch information
waleedyaseen committed Oct 6, 2023
1 parent 370ac1a commit e5d0c69
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 95 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
### Fixed
- Fix regular expressions not being allowed in hook transmits list.
- Fix invalid symbol file inspection reporting an error for "commands.sym".
- Fix "Create procedure" placement of script.

### Changed
- Inspections that require symbols will no longer run on files outside the project.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.runescript.plugin.ide.inspections

import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.editor.ScrollType
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.fileEditor.OpenFileDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.util.findParentOfType
import io.runescript.plugin.lang.psi.RsElementGenerator
import io.runescript.plugin.lang.psi.RsScript

class RsCreateScriptQuickFix(private val trigger: String, private val functionName: String) : LocalQuickFix {

override fun getName(): String {
return "Create script ('${functionName}')"
}

override fun getFamilyName(): String {
return "Create script"
}

override fun generatePreview(project: Project, previewDescriptor: ProblemDescriptor): IntentionPreviewInfo =
IntentionPreviewInfo.EMPTY

override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val newScript = RsScriptBuilder(trigger, functionName)
.statement("error(\"Not yet implemented\");")
.build(project)
val parentScript = descriptor.psiElement.findParentOfType<RsScript>()!!
val parentFile = parentScript.parent
parentFile.addAfter(newScript, parentScript)
parentFile.addAfter(RsElementGenerator.createNewLine(project), parentScript)
openAndSelect(project, newScript)
}

private fun openAndSelect(project: Project, script: RsScript) {
val containingFile = script.containingFile.virtualFile ?: return
val openDescriptor = OpenFileDescriptor(project, containingFile)
val textEditor = FileEditorManager.getInstance(project).openTextEditor(openDescriptor, true) ?: return
textEditor.selectionModel.removeSelection()
val endOffset = script.textRange.endOffset
textEditor.caretModel.moveToOffset(endOffset + 1)
val manager = PsiDocumentManager.getInstance(project)
manager.doPostponedOperationsAndUnblockDocument(textEditor.document)
textEditor.scrollingModel.scrollToCaret(ScrollType.RELATIVE)
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
package io.runescript.plugin.ide.inspections

import com.intellij.codeInspection.*
import com.intellij.openapi.editor.EditorModificationUtilEx
import com.intellij.openapi.editor.ScrollType
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.fileEditor.OpenFileDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiDocumentManager
import com.intellij.codeInspection.LocalInspectionTool
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.util.findParentOfType
import io.runescript.plugin.ide.RsBundle
import io.runescript.plugin.lang.psi.RsHookFragment
import io.runescript.plugin.lang.psi.RsScript
import io.runescript.plugin.lang.psi.RsVisitor
import io.runescript.plugin.lang.psi.isSourceFile

Expand All @@ -23,46 +17,13 @@ class RuneScriptUnresolvedClientscriptInspection : LocalInspectionTool() {
if (!o.isSourceFile()) return
val resolvedClientScript = o.reference!!.resolve()
if (resolvedClientScript == null) {
holder.registerProblem(o.nameLiteral,
holder.registerProblem(
o.nameLiteral,
RsBundle.message("inspection.error.unresolved.clientscript", o.nameLiteral.text),
ProblemHighlightType.LIKE_UNKNOWN_SYMBOL,
RsUnresolvedClientscriptQuickFix(o.nameLiteral.text)
ProblemHighlightType.LIKE_UNKNOWN_SYMBOL
)
}
}
}
}

class RsUnresolvedClientscriptQuickFix(private val functionName: String) : LocalQuickFix {

override fun getName(): String {
return "Create clientscript ('${functionName}')"
}

override fun getFamilyName(): String {
return "Create clientscript"
}

override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val newScript = RsScriptBuilder("clientscript", functionName)
.statement("error(\"Not yet implemented\");")
.build(project)
val parentScript = descriptor.psiElement.findParentOfType<RsScript>()!!
val parentFile = parentScript.parent!!
parentFile.addAfter(newScript, parentScript)
openAndSelect(project, newScript)
}

private fun openAndSelect(project: Project, script: RsScript) {
val openDescriptor = OpenFileDescriptor(project, script.containingFile.virtualFile)
val textEditor = FileEditorManager.getInstance(project).openTextEditor(openDescriptor, true)!!
textEditor.selectionModel.removeSelection()
val endOffset = script.textRange.endOffset
textEditor.caretModel.moveToOffset(endOffset + 1)
val manager = PsiDocumentManager.getInstance(project)
manager.doPostponedOperationsAndUnblockDocument(textEditor.document)
EditorModificationUtilEx.insertStringAtCaret(textEditor, "\n", false, false)
textEditor.scrollingModel.scrollToCaret(ScrollType.RELATIVE)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
package io.runescript.plugin.ide.inspections

import com.intellij.codeInspection.*
import com.intellij.openapi.editor.EditorModificationUtilEx
import com.intellij.openapi.editor.ScrollType
import com.intellij.openapi.fileEditor.FileEditorManager
import com.intellij.openapi.fileEditor.OpenFileDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiDocumentManager
import com.intellij.codeInspection.LocalInspectionTool
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.util.findParentOfType
import io.runescript.plugin.ide.RsBundle
import io.runescript.plugin.lang.psi.RsGosubExpression
import io.runescript.plugin.lang.psi.RsScript
import io.runescript.plugin.lang.psi.RsVisitor
import io.runescript.plugin.lang.psi.isSourceFile

Expand All @@ -23,46 +17,14 @@ class RuneScriptUnresolvedProcedureInspection : LocalInspectionTool() {
if (!o.isSourceFile()) return
val resolvedGosub = o.reference!!.resolve()
if (resolvedGosub == null) {
holder.registerProblem(o.nameLiteral,
RsBundle.message("inspection.error.unresolved.procedure", o.nameLiteral.text),
ProblemHighlightType.LIKE_UNKNOWN_SYMBOL,
RsUnresolvedReferenceQuickFix(o.nameLiteral.text)
holder.registerProblem(
o.nameLiteral,
RsBundle.message("inspection.error.unresolved.procedure", o.nameLiteral.text),
ProblemHighlightType.LIKE_UNKNOWN_SYMBOL,
RsCreateScriptQuickFix("proc", o.nameLiteral.text)
)
}
}
}
}

class RsUnresolvedReferenceQuickFix(private val functionName: String) : LocalQuickFix {

override fun getName(): String {
return "Create procedure ('${functionName}')"
}

override fun getFamilyName(): String {
return "Create procedure"
}

override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val newScript = RsScriptBuilder("proc", functionName)
.statement("error(\"Not yet implemented\");")
.build(project)
val parentScript = descriptor.psiElement.findParentOfType<RsScript>()!!
val parentFile = parentScript.parent!!
parentFile.addAfter(newScript, parentScript)
openAndSelect(project, newScript)
}

private fun openAndSelect(project: Project, script: RsScript) {
val openDescriptor = OpenFileDescriptor(project, script.containingFile.virtualFile)
val textEditor = FileEditorManager.getInstance(project).openTextEditor(openDescriptor, true)!!
textEditor.selectionModel.removeSelection()
val endOffset = script.textRange.endOffset
textEditor.caretModel.moveToOffset(endOffset + 1)
val manager = PsiDocumentManager.getInstance(project)
manager.doPostponedOperationsAndUnblockDocument(textEditor.document)
EditorModificationUtilEx.insertStringAtCaret(textEditor, "\n", false, false)
textEditor.scrollingModel.scrollToCaret(ScrollType.RELATIVE)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package io.runescript.plugin.lang.psi

import com.intellij.openapi.project.Project
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiFileFactory
import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.TokenType
import com.intellij.psi.impl.PsiFileFactoryImpl
import com.intellij.psi.tree.TokenSet
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.psi.util.childrenOfType
import com.intellij.testFramework.LightVirtualFile
import io.runescript.plugin.ide.filetypes.RsFileType
import io.runescript.plugin.lang.RuneScript
Expand All @@ -17,15 +22,18 @@ object RsElementGenerator {
return PsiTreeUtil.findChildOfType(element, RsExpression::class.java) as RsExpression

}

fun createIntegerLiteral(project: Project, replacement: String): PsiElement {
val element = createDummyFile(project, "[proc,dummy]()()$replacement;")
val literal = PsiTreeUtil.findChildOfType(element, RsIntegerLiteralExpression::class.java) as RsIntegerLiteralExpression
val literal =
PsiTreeUtil.findChildOfType(element, RsIntegerLiteralExpression::class.java) as RsIntegerLiteralExpression
return literal.node.firstChildNode.psi!!
}

fun createColorTag(project: Project, color: Int, tagName: String = "col"): PsiElement {
val element = createDummyFile(project, "[proc,dummy]()()\"<$tagName=%06x>\";".format(color and 0xffffff))
val literal = PsiTreeUtil.findChildOfType(element, RsStringLiteralExpression::class.java) as RsStringLiteralExpression
val literal =
PsiTreeUtil.findChildOfType(element, RsStringLiteralExpression::class.java) as RsStringLiteralExpression
return literal.node.findChildByType(RsElementTypes.STRING_TAG)!!.psi
}

Expand All @@ -41,14 +49,19 @@ object RsElementGenerator {

fun createStringLiteralContent(project: Project, content: String): RsStringLiteralContent {
val element = createDummyFile(project, "[proc,dummy]()()\"$content\";")
val literal = PsiTreeUtil.findChildOfType(element, RsStringLiteralExpression::class.java) as RsStringLiteralExpression
val literal =
PsiTreeUtil.findChildOfType(element, RsStringLiteralExpression::class.java) as RsStringLiteralExpression
return PsiTreeUtil.findChildOfType(literal, RsStringLiteralContent::class.java) as RsStringLiteralContent
}

private fun createDummyFile(project: Project, text: String): PsiFile {
val factory = PsiFileFactory.getInstance(project) as PsiFileFactoryImpl
val name = "dummy.${RsFileType.defaultExtension}"
val virtualFile = LightVirtualFile(name, RsFileType, text)
val virtualFile = LightVirtualFile(name, RsFileType, StringUtil.convertLineSeparators(text))
return factory.trySetupPsiForFile(virtualFile, RuneScript, false, true)!!
}

fun createNewLine(project: Project): PsiElement {
return createDummyFile(project, "\n").firstChild
}
}

0 comments on commit e5d0c69

Please sign in to comment.