override fun invoke()

in gdscript/src/main/kotlin/gdscript/action/GdPropageTraitChangesAction.kt [43:84]


    override fun invoke(project: Project, editor: Editor?, file: PsiFile?) {
        if (editor === null || file === null) return
        val extendsRegex = "extends .+\n*".toRegex()

        var fromSource = true
        val source: String
        var sourceFile = file.originalFile.virtualFile

        if (isTraitFile(file)) {
            source = file.containingFile.text.replace(extendsRegex, "")
        } else {
            val header = traitRegionLabel(editor, file) ?: return
            val footer = GdCommentUtil.endTraitComment(header) ?: return
            source = editor.document.getText(TextRange.create(header.endOffset + 1, footer.startOffset - 1))

            val traitFile = header.text.substring(GdTraitLineMarkerContributor.PREFIX.length).trim()
            sourceFile = GdFileResIndex.getFiles("res://$traitFile", project)
                .firstOrNull() ?: return
            fromSource = false
        }
        val usages = GdCommentUtil.listUsages(sourceFile.resourcePath().substring("res://".length), project)

        val dm = PsiDocumentManager.getInstance(project)
        val runner = runner@{
            if (!fromSource) {
                val sourceDocument = FileDocumentManager.getInstance().getDocument(sourceFile) ?: return@runner
                val prefix = extendsRegex.find(sourceDocument.text)?.value ?: ""
                FileDocumentManager.getInstance().getDocument(sourceFile)?.setText(prefix + source)
            }

            usages.forEach { header ->
                val f = header.containingFile
                val footer = GdCommentUtil.endTraitComment(header)
                val doc = dm.getDocument(f)
                if (footer != null && doc != null) {
                    doc.replaceString(header.endOffset, footer.startOffset, "\n$source\n")
                }
            }
        }

        ApplicationManager.getApplication().runWriteAction(runner)
    }