From cbffc3d8412d98f83e629868ac9be12768e79b9f Mon Sep 17 00:00:00 2001 From: chrisly42 Date: Sun, 3 Oct 2021 18:55:42 +0200 Subject: [PATCH] Label documentation now also works for local labels and includes end-of-line comment for label, too. Symbol definition documentation now also includes comments in the same way as the label documentation does. Refactored some code. --- README.md | 15 ++++-- build.gradle | 12 ++--- .../AbstractM68kDocumentationProvider.kt | 32 +++++++++++++ .../M68kGlobalLabelDocumentationProvider.kt | 47 ------------------- .../M68kLabelDocumentationProvider.kt | 34 ++++++++++++++ .../M68kRegisterFlowDocumentationProvider.kt | 5 +- ...8kSymbolDefinitionDocumentationProvider.kt | 15 +++--- .../plugins/m68k/psi/M68kPsiWalkUtil.kt | 24 ++++++++++ src/main/resources/META-INF/plugin.xml | 2 +- ... => M68KLabelDocumentationProviderTest.kt} | 10 ++-- ...mbolDefinitionDocumentationProviderTest.kt | 4 +- 11 files changed, 122 insertions(+), 78 deletions(-) create mode 100644 src/main/java/de/platon42/intellij/plugins/m68k/documentation/AbstractM68kDocumentationProvider.kt delete mode 100644 src/main/java/de/platon42/intellij/plugins/m68k/documentation/M68kGlobalLabelDocumentationProvider.kt create mode 100644 src/main/java/de/platon42/intellij/plugins/m68k/documentation/M68kLabelDocumentationProvider.kt create mode 100644 src/main/java/de/platon42/intellij/plugins/m68k/psi/M68kPsiWalkUtil.kt rename src/test/java/de/platon42/intellij/plugins/m68k/documentation/{M68kGlobalLabelDocumentationProviderTest.kt => M68KLabelDocumentationProviderTest.kt} (63%) diff --git a/README.md b/README.md index 615d87b..ee524bc 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,9 @@ I'm an Amiga retro democoder (among other things), and the lack of a plugin for plugins has a steep learning curve. When I started the plugin in July 2021, I was unaware of the [M68k plugin efforts by Jetbrains employee Yann Cébron](https://github.com/YannCebron/m68kplugin) -who has been working on the same topic for quite some time. *On 01-Oct-21, he released his first public version.* Check it out. You can install both plugins at -the same time and see what suits you more. +who has been working on the same topic for quite some time. *On 01-Oct-21, he released +his [first public version](https://plugins.jetbrains.com/plugin/17712-motorola-68000-series-assembler).* Check it out. You can install both plugins at the same +time and see what suits you more. Big kudos to Yann -- a few features were _inspired_ by his code. @@ -89,9 +90,10 @@ weak warnings as missing macro evaluation will not resolve symbols defined via ` Provides the assigned value of a `=`, `set` or `equ` symbol definition when hovering over a symbol. -#### M68kGlobalLabel +#### M68kLabel -Shows the comments above the label and if the first statement after the label is a directive like `include` or `dc.b`, shows it, too. +Shows the comments above the label (local or global) and an end-of-line comment, if available. If the first statement after the label is a directive +like `include` or `dc.b`, it will be shown, too. #### M68kRegisterFlow @@ -154,6 +156,11 @@ are appreciated. It really is keeping me motivated to continue development. ## Changelog +### V0.8 (unreleased) + +- Enhancement: Label documentation now also works for local labels and includes end-of-line comment for label, too. +- Enhancement: Symbol definition documentation now also includes comments in the same way as the label documentation does. + ### V0.7 (26-Sep-21) - Bugfix: `btst` with pc-relative and weird immediate mode was missing (courtesy of Yann). diff --git a/build.gradle b/build.gradle index ee763a6..41a97ac 100644 --- a/build.gradle +++ b/build.gradle @@ -58,16 +58,10 @@ runPluginVerifier { patchPluginXml { setChangeNotes("""

I still got zero feedback and zero ratings :-(

-

V0.7 (26-Sep-21)

+

V0.8 (unreleased)

Full changelog available at Github project site.

""") diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/documentation/AbstractM68kDocumentationProvider.kt b/src/main/java/de/platon42/intellij/plugins/m68k/documentation/AbstractM68kDocumentationProvider.kt new file mode 100644 index 0000000..032cf3f --- /dev/null +++ b/src/main/java/de/platon42/intellij/plugins/m68k/documentation/AbstractM68kDocumentationProvider.kt @@ -0,0 +1,32 @@ +package de.platon42.intellij.plugins.m68k.documentation + +import com.intellij.lang.documentation.AbstractDocumentationProvider +import com.intellij.lang.documentation.DocumentationMarkup +import com.intellij.openapi.util.text.HtmlBuilder +import com.intellij.openapi.util.text.HtmlChunk +import com.intellij.psi.PsiElement +import de.platon42.intellij.plugins.m68k.psi.M68kNamedElement +import de.platon42.intellij.plugins.m68k.psi.M68kPsiWalkUtil + +abstract class AbstractM68kDocumentationProvider : AbstractDocumentationProvider() { + + fun getComments(element: PsiElement): HtmlChunk { + val builder = HtmlBuilder() + val comments = M68kPsiWalkUtil.collectRelatedComments(element).map { HtmlChunk.text(it.text) } + builder.appendWithSeparators(HtmlChunk.br(), comments) + return if (comments.isNotEmpty()) builder.wrapWith(HtmlChunk.span().attr("class", "grayed")) else HtmlChunk.empty() + } + + fun getDefinition(element: M68kNamedElement) = getDefinition(HtmlChunk.text(element.name!!).code()) + + fun getDefinition(value: String) = getDefinition(HtmlChunk.text(value)) + + fun getDefinition(chunk: HtmlChunk) = + HtmlBuilder().append(chunk).wrapWith(DocumentationMarkup.DEFINITION_ELEMENT) + + fun getContent(element: PsiElement) = + HtmlBuilder().append(HtmlChunk.text(element.text).code()).wrapWith(DocumentationMarkup.CONTENT_ELEMENT) + + fun getContent(value: String) = + HtmlBuilder().append(value).wrapWith(DocumentationMarkup.CONTENT_ELEMENT) +} \ No newline at end of file diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/documentation/M68kGlobalLabelDocumentationProvider.kt b/src/main/java/de/platon42/intellij/plugins/m68k/documentation/M68kGlobalLabelDocumentationProvider.kt deleted file mode 100644 index bc94919..0000000 --- a/src/main/java/de/platon42/intellij/plugins/m68k/documentation/M68kGlobalLabelDocumentationProvider.kt +++ /dev/null @@ -1,47 +0,0 @@ -package de.platon42.intellij.plugins.m68k.documentation - -import com.intellij.lang.documentation.AbstractDocumentationProvider -import com.intellij.lang.documentation.DocumentationMarkup -import com.intellij.openapi.util.text.StringUtil -import com.intellij.psi.PsiComment -import com.intellij.psi.PsiElement -import com.intellij.psi.util.PsiTreeUtil -import com.intellij.util.SmartList -import de.platon42.intellij.plugins.m68k.psi.M68kGlobalLabel -import de.platon42.intellij.plugins.m68k.psi.M68kStatement - -class M68kGlobalLabelDocumentationProvider : AbstractDocumentationProvider() { - - override fun getQuickNavigateInfo(element: PsiElement, originalElement: PsiElement?): String? { - return generateDoc(element, originalElement) - } - - override fun generateDoc(element: PsiElement, originalElement: PsiElement?): String? { - return if (element is M68kGlobalLabel) { - // TODO find out how we can generate inner links for more symbol references inside the expression (DocumentationManagerUtil) - val statement = element.parent as M68kStatement - var preprocessorDirective = statement.preprocessorDirective - if ((preprocessorDirective == null) && (statement.asmInstruction == null) && (statement.macroCall == null)) { - val nextLineStatement = PsiTreeUtil.skipWhitespacesAndCommentsForward(PsiTreeUtil.skipWhitespacesAndCommentsForward(statement)) - as? M68kStatement - preprocessorDirective = nextLineStatement?.preprocessorDirective - } - val content = if (preprocessorDirective != null) - DocumentationMarkup.CONTENT_START + StringUtil.escapeXmlEntities(preprocessorDirective.text) + DocumentationMarkup.CONTENT_END - else "" - val comments = SmartList() - var prevToken: PsiElement? = statement - do { - prevToken = PsiTreeUtil.skipWhitespacesBackward(prevToken) - if (prevToken !is PsiComment) break - comments.add(prevToken.text) - } while (true) - val commentpart = - if (comments.isNotEmpty()) comments.asReversed().joinToString("
", DocumentationMarkup.GRAYED_START, DocumentationMarkup.GRAYED_END) else "" - - commentpart + - DocumentationMarkup.DEFINITION_START + StringUtil.escapeXmlEntities(element.name!!) + DocumentationMarkup.DEFINITION_END + - content - } else null - } -} \ No newline at end of file diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/documentation/M68kLabelDocumentationProvider.kt b/src/main/java/de/platon42/intellij/plugins/m68k/documentation/M68kLabelDocumentationProvider.kt new file mode 100644 index 0000000..384c6ed --- /dev/null +++ b/src/main/java/de/platon42/intellij/plugins/m68k/documentation/M68kLabelDocumentationProvider.kt @@ -0,0 +1,34 @@ +package de.platon42.intellij.plugins.m68k.documentation + +import com.intellij.openapi.util.text.HtmlBuilder +import com.intellij.psi.PsiElement +import com.intellij.psi.util.PsiTreeUtil +import de.platon42.intellij.plugins.m68k.psi.M68kGlobalLabel +import de.platon42.intellij.plugins.m68k.psi.M68kLocalLabel +import de.platon42.intellij.plugins.m68k.psi.M68kNamedElement +import de.platon42.intellij.plugins.m68k.psi.M68kStatement + +class M68kLabelDocumentationProvider : AbstractM68kDocumentationProvider() { + + override fun getQuickNavigateInfo(element: PsiElement, originalElement: PsiElement?): String? { + return generateDoc(element, originalElement) + } + + override fun generateDoc(element: PsiElement, originalElement: PsiElement?): String? { + return if (element is M68kGlobalLabel || element is M68kLocalLabel) { + // TODO find out how we can generate inner links for more symbol references inside the expression (DocumentationManagerUtil) + val statement = element.parent as M68kStatement + var preprocessorDirective = statement.preprocessorDirective + if ((preprocessorDirective == null) && (statement.asmInstruction == null) && (statement.macroCall == null)) { + val nextLineStatement = PsiTreeUtil.skipWhitespacesAndCommentsForward(PsiTreeUtil.skipWhitespacesAndCommentsForward(statement)) + as? M68kStatement + preprocessorDirective = nextLineStatement?.preprocessorDirective + } + val builder = HtmlBuilder() + builder.append(getComments(statement)) + builder.append(getDefinition(element as M68kNamedElement)) + if (preprocessorDirective != null) builder.append(getContent(preprocessorDirective)) + builder.toString() + } else null + } +} \ No newline at end of file diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/documentation/M68kRegisterFlowDocumentationProvider.kt b/src/main/java/de/platon42/intellij/plugins/m68k/documentation/M68kRegisterFlowDocumentationProvider.kt index 10fd9f6..b4c5e63 100644 --- a/src/main/java/de/platon42/intellij/plugins/m68k/documentation/M68kRegisterFlowDocumentationProvider.kt +++ b/src/main/java/de/platon42/intellij/plugins/m68k/documentation/M68kRegisterFlowDocumentationProvider.kt @@ -1,6 +1,5 @@ package de.platon42.intellij.plugins.m68k.documentation -import com.intellij.lang.documentation.AbstractDocumentationProvider import com.intellij.lang.documentation.DocumentationMarkup import com.intellij.openapi.editor.Editor import com.intellij.openapi.util.text.HtmlBuilder @@ -19,7 +18,7 @@ import de.platon42.intellij.plugins.m68k.utils.M68kIsaUtil.findExactIsaDataAndAl import de.platon42.intellij.plugins.m68k.utils.M68kIsaUtil.getOpSizeOrDefault import de.platon42.intellij.plugins.m68k.utils.M68kIsaUtil.modifyRwmWithOpsize -class M68kRegisterFlowDocumentationProvider : AbstractDocumentationProvider() { +class M68kRegisterFlowDocumentationProvider : AbstractM68kDocumentationProvider() { override fun generateDoc(element: PsiElement, originalElement: PsiElement?): String? { if (element is M68kDataRegister || element is M68kAddressRegister) { @@ -90,7 +89,7 @@ class M68kRegisterFlowDocumentationProvider : AbstractDocumentationProvider() { val statementRows = HtmlBuilder() backtrace.forEach(statementRows::append) val builder = HtmlBuilder() - builder.append(HtmlChunk.text(thisInfo).wrapWith(DocumentationMarkup.DEFINITION_ELEMENT)) + builder.append(getDefinition(thisInfo)) builder.append(statementRows.wrapWith(DocumentationMarkup.SECTIONS_TABLE.style("padding-left: 8pt; padding-right: 8pt"))) return builder.toString() } diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/documentation/M68kSymbolDefinitionDocumentationProvider.kt b/src/main/java/de/platon42/intellij/plugins/m68k/documentation/M68kSymbolDefinitionDocumentationProvider.kt index a38f473..70fd413 100644 --- a/src/main/java/de/platon42/intellij/plugins/m68k/documentation/M68kSymbolDefinitionDocumentationProvider.kt +++ b/src/main/java/de/platon42/intellij/plugins/m68k/documentation/M68kSymbolDefinitionDocumentationProvider.kt @@ -1,13 +1,11 @@ package de.platon42.intellij.plugins.m68k.documentation -import com.intellij.lang.documentation.AbstractDocumentationProvider -import com.intellij.lang.documentation.DocumentationMarkup -import com.intellij.openapi.util.text.StringUtil +import com.intellij.openapi.util.text.HtmlBuilder import com.intellij.psi.PsiElement import de.platon42.intellij.plugins.m68k.psi.M68kAssignment import de.platon42.intellij.plugins.m68k.psi.M68kSymbolDefinition -class M68kSymbolDefinitionDocumentationProvider : AbstractDocumentationProvider() { +class M68kSymbolDefinitionDocumentationProvider : AbstractM68kDocumentationProvider() { override fun getQuickNavigateInfo(element: PsiElement, originalElement: PsiElement?): String? { return generateDoc(element, originalElement) @@ -16,9 +14,12 @@ class M68kSymbolDefinitionDocumentationProvider : AbstractDocumentationProvider( override fun generateDoc(element: PsiElement, originalElement: PsiElement?): String? { return if (element is M68kSymbolDefinition) { // TODO find out how we can generate inner links for more symbol references inside the expression (DocumentationManagerUtil) - val value = (element.parent as M68kAssignment).expr.text - DocumentationMarkup.DEFINITION_START + StringUtil.escapeXmlEntities(element.name!!) + DocumentationMarkup.DEFINITION_END + - DocumentationMarkup.CONTENT_START + StringUtil.escapeXmlEntities(value) + DocumentationMarkup.CONTENT_END + val assignment = element.parent as M68kAssignment + HtmlBuilder() + .append(getComments(assignment.parent)) + .append(getDefinition(element)) + .append(getContent(assignment.expr)) + .toString() } else null } } \ No newline at end of file diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/psi/M68kPsiWalkUtil.kt b/src/main/java/de/platon42/intellij/plugins/m68k/psi/M68kPsiWalkUtil.kt new file mode 100644 index 0000000..093a12b --- /dev/null +++ b/src/main/java/de/platon42/intellij/plugins/m68k/psi/M68kPsiWalkUtil.kt @@ -0,0 +1,24 @@ +package de.platon42.intellij.plugins.m68k.psi + +import com.intellij.psi.PsiComment +import com.intellij.psi.PsiElement +import com.intellij.psi.util.PsiTreeUtil +import com.intellij.util.SmartList +import com.intellij.util.containers.addIfNotNull + +object M68kPsiWalkUtil { + + fun collectRelatedComments(element: PsiElement): List { + val comments = SmartList() + val eolComment = PsiTreeUtil.skipWhitespacesForward(element) as? PsiComment + comments.addIfNotNull(eolComment) + var prevToken: PsiElement? = element + do { + prevToken = PsiTreeUtil.skipWhitespacesBackward(prevToken) + if (prevToken !is PsiComment) break + comments.add(prevToken) + } while (true) + + return comments.reversed() + } +} \ No newline at end of file diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index dc874d9..4512213 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -40,7 +40,7 @@ + implementationClass="de.platon42.intellij.plugins.m68k.documentation.M68kLabelDocumentationProvider"/> cool! rts bsr squareme """ ) assertThat(generateDocumentation(myFixture)) - .isEqualTo("; inputs: d0 = number
; output: d0 = square
squareme
include "fancysquarecode.asm"
") + .isEqualTo("; inputs: d0 = number
; output: d0 = square
; code -> cool!
squareme
include "fancysquarecode.asm"
") } @Test @@ -32,12 +32,12 @@ squareme: include "fancysquarecode.asm" myFixture.configureByText( "documentme.asm", """ ; output: d0 = square -squareme: +.squareme: ; oh man include "fancysquarecode.asm" """ ) assertThat(generateDocumentation(myFixture)) - .isEqualTo("; output: d0 = square
squareme
include "fancysquarecode.asm"
") + .isEqualTo("; output: d0 = square
.squareme
include "fancysquarecode.asm"
") } } \ No newline at end of file diff --git a/src/test/java/de/platon42/intellij/plugins/m68k/documentation/M68kSymbolDefinitionDocumentationProviderTest.kt b/src/test/java/de/platon42/intellij/plugins/m68k/documentation/M68kSymbolDefinitionDocumentationProviderTest.kt index 2d4b3da..08d3bbc 100644 --- a/src/test/java/de/platon42/intellij/plugins/m68k/documentation/M68kSymbolDefinitionDocumentationProviderTest.kt +++ b/src/test/java/de/platon42/intellij/plugins/m68k/documentation/M68kSymbolDefinitionDocumentationProviderTest.kt @@ -14,11 +14,11 @@ internal class M68kSymbolDefinitionDocumentationProviderTest : AbstractDocumenta internal fun check_documentation_for_a_symbol_definition(@MyFixture myFixture: CodeInsightTestFixture) { myFixture.configureByText( "documentme.asm", """ -PIC_WIDTH = 320 +PIC_WIDTH = 320 ; width of picture move.w #PIC_WIDTH,d0 """ ) assertThat(generateDocumentation(myFixture)) - .isEqualTo("
PIC_WIDTH
320
") + .isEqualTo("; width of picture
PIC_WIDTH
320
") } } \ No newline at end of file