diff --git a/README.md b/README.md index 9e022b5..11184bf 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# MC68000 Assembly Language Plugin [![Build Status](https://app.travis-ci.com/chrisly42/mc68000-asm-plugin.svg?branch=master)](https://app.travis-ci.com/chrisly42/mc68000-asm-plugin) [![Coverage Status](https://coveralls.io/repos/github/chrisly42/mc68000-asm-plugin/badge.svg?branch=main)](https://coveralls.io/github/chrisly42/mc68000-asm-plugin?branch=main) +# MC68000 Assembly Language Plugin [![Build Status](https://app.travis-ci.com/chrisly42/mc68000-asm-plugin.svg?branch=main)](https://app.travis-ci.com/chrisly42/mc68000-asm-plugin) [![Coverage Status](https://coveralls.io/repos/github/chrisly42/mc68000-asm-plugin/badge.svg?branch=main)](https://coveralls.io/github/chrisly42/mc68000-asm-plugin?branch=main) _MC68000 Assembly Language Plugin_ is plugin for Jetbrains IDEs (CLion, IntelliJ, etc.). @@ -149,7 +149,7 @@ to highlight the same address and data registers while editing (see new `View -> ## Development notice -This plugin has been written in Kotlin 1.5 using Grammar-Kit. +This plugin has been written in Kotlin 1.7 using Grammar-Kit. It is probably the only plugin (besides [Cajon](https://github.com/chrisly42/cajon-plugin) from the same author) that uses JUnit 5 Jupiter for unit testing so far (or at least the only one I'm aware of ;) ). The IntelliJ framework actually uses the JUnit 3 TestCase for plugin testing, and it took me quite a while to diff --git a/build.gradle b/build.gradle index 426bb63..416b100 100644 --- a/build.gradle +++ b/build.gradle @@ -1,15 +1,15 @@ plugins { id 'java' - id 'org.jetbrains.intellij' version '1.9.0' - id 'org.jetbrains.kotlin.jvm' version '1.7.20' + id 'org.jetbrains.intellij' version '1.11.0' + id 'org.jetbrains.kotlin.jvm' version '1.8.0-RC2' id 'jacoco' id 'com.github.kt3k.coveralls' version '2.12.0' } group = 'de.platon42' version = '0.10' -sourceCompatibility = "1.8" -targetCompatibility = "1.8" +sourceCompatibility = 17 +targetCompatibility = 17 repositories { mavenCentral() @@ -23,39 +23,29 @@ repositories { dependencies { implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' testImplementation 'org.assertj:assertj-core:3.23.1' - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0' - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.1' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.1' testImplementation "org.jetbrains.kotlin:kotlin-test" testImplementation "org.jetbrains.kotlin:kotlin-reflect" - testImplementation 'org.junit.platform:junit-platform-launcher:1.9.0' + testImplementation 'org.junit.platform:junit-platform-launcher:1.9.1' // testImplementation "org.jetbrains.kotlin:kotlin-test-junit" } -compileKotlin { - kotlinOptions { - jvmTarget = "1.8" - freeCompilerArgs += "-Xjvm-default=all" - } -} - -compileTestKotlin { - kotlinOptions.jvmTarget = "1.8" -} - intellij { - setVersion("2022.2.3") // LATEST-EAP-SNAPSHOT + setVersion("2022.3") // LATEST-EAP-SNAPSHOT setUpdateSinceUntilBuild(false) // setPlugins(["com.intellij.java"]) } runPluginVerifier { - ideVersions = ["IC-203.6682.168", "IC-222.4345.14", // 2020.3 - 2022.2.3 + ideVersions = ["IC-203.6682.168", "IC-223.7571.182", // 2020.3 - 2022.3 "CL-203.8084.11", // 2020.3 "CL-211.7628.27", // 2021.1 "CL-212.5712.21", // 2021.2 "CL-213.7172.20", // 2021.3.4 "CL-221.5921.22", // 2022.1.3 - "CL-222.4345.21"] // 2022.2.4 + "CL-222.4345.21", // 2022.2.4 + "CL-223.7571.171"] // 2022.3 downloadDir = System.getProperty("user.home") + "/.gradle/caches/modules-2/files-2.1/com.jetbrains.intellij.idea/verifier" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ae04661..070cb70 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/plans.txt b/plans.txt new file mode 100644 index 0000000..b9e889c --- /dev/null +++ b/plans.txt @@ -0,0 +1,17 @@ + +Formatting: +- dc.w statements: Pressing return will automatically add dc.w in next line (plus tabs) + +Showing of used registers in selection + +Actions: +- Replace constant by symbol (with suggestion) +- Converting of hex values into decimal values and vice versa +- convert new style to old style +- convert old style to new style +- simplify explicit mnemonics (e.g. movea) + +Marker: +- go to source register setter +- go to target register setter +- Can we add "find declaration to go for registers" \ No newline at end of file diff --git a/src/main/gen/de/platon42/intellij/plugins/m68k/parser/M68kParser.java b/src/main/gen/de/platon42/intellij/plugins/m68k/parser/M68kParser.java index cf75ba2..a47c0d8 100644 --- a/src/main/gen/de/platon42/intellij/plugins/m68k/parser/M68kParser.java +++ b/src/main/gen/de/platon42/intellij/plugins/m68k/parser/M68kParser.java @@ -649,22 +649,12 @@ public class M68kParser implements PsiParser, LightPsiParser { } /* ********************************************************** */ - // AsmInstruction | MacroCall + // AsmInstruction | MacroCall | PreprocessorDirective static boolean Instruction(PsiBuilder b, int l) { if (!recursion_guard_(b, l, "Instruction")) return false; - if (!nextTokenIs(b, "", MACRO_INVOCATION, MNEMONIC)) return false; boolean r; r = AsmInstruction(b, l + 1); if (!r) r = MacroCall(b, l + 1); - return r; - } - - /* ********************************************************** */ - // Instruction|PreprocessorDirective - static boolean InstructionOnly(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "InstructionOnly")) return false; - boolean r; - r = Instruction(b, l + 1); if (!r) r = PreprocessorDirective(b, l + 1); return r; } @@ -681,13 +671,13 @@ public class M68kParser implements PsiParser, LightPsiParser { } /* ********************************************************** */ - // LabelWithInstruction | LabelOnly | InstructionOnly + // LabelWithInstruction | LabelOnly | Instruction static boolean LabelInsts(PsiBuilder b, int l) { if (!recursion_guard_(b, l, "LabelInsts")) return false; boolean r; r = LabelWithInstruction(b, l + 1); if (!r) r = LabelOnly(b, l + 1); - if (!r) r = InstructionOnly(b, l + 1); + if (!r) r = Instruction(b, l + 1); return r; } @@ -698,27 +688,18 @@ public class M68kParser implements PsiParser, LightPsiParser { } /* ********************************************************** */ - // Label (Instruction|PreprocessorDirective) + // Label Instruction static boolean LabelWithInstruction(PsiBuilder b, int l) { if (!recursion_guard_(b, l, "LabelWithInstruction")) return false; if (!nextTokenIs(b, "", GLOBAL_LABEL_DEF, LOCAL_LABEL_DEF)) return false; boolean r; Marker m = enter_section_(b); r = Label(b, l + 1); - r = r && LabelWithInstruction_1(b, l + 1); + r = r && Instruction(b, l + 1); exit_section_(b, m, null, r); return r; } - // Instruction|PreprocessorDirective - private static boolean LabelWithInstruction_1(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "LabelWithInstruction_1")) return false; - boolean r; - r = Instruction(b, l + 1); - if (!r) r = PreprocessorDirective(b, l + 1); - return r; - } - /* ********************************************************** */ // LOCAL_LABEL_DEF COLON? public static boolean LocalLabel(PsiBuilder b, int l) { diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/M68kFileElementType.kt b/src/main/java/de/platon42/intellij/plugins/m68k/M68kFileElementType.kt index f69907b..896f05d 100644 --- a/src/main/java/de/platon42/intellij/plugins/m68k/M68kFileElementType.kt +++ b/src/main/java/de/platon42/intellij/plugins/m68k/M68kFileElementType.kt @@ -10,7 +10,7 @@ class M68kFileElementType private constructor() : ILightStubFileElementType { + val subBlocks = ArrayList() + var child = myNode.firstChildNode + var newColumn = column + while (child != null) { + if (child.elementType != TokenType.WHITE_SPACE) { + subBlocks.add( + M68kAsmBlock( + child, + Wrap.createWrap(WrapType.NONE, false), + Alignment.createAlignment(), + newColumn, + codeStyleSettings + ) + ) + if (child.elementType == M68kTypes.ASM_OP) { + newColumn++ + } + } + child = child.treeNext + } + return subBlocks + } +} \ No newline at end of file diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmCodeStyleSettings.kt b/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmCodeStyleSettings.kt new file mode 100644 index 0000000..fb1c6ad --- /dev/null +++ b/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmCodeStyleSettings.kt @@ -0,0 +1,7 @@ +package de.platon42.intellij.plugins.m68k.formatter + +import com.intellij.psi.codeStyle.CodeStyleSettings +import com.intellij.psi.codeStyle.CustomCodeStyleSettings + +class M68kAsmCodeStyleSettings(container: CodeStyleSettings) : CustomCodeStyleSettings("MC68000AsmCodeStyleSettings", container) { +} \ No newline at end of file diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmCodeStyleSettingsProvider.kt b/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmCodeStyleSettingsProvider.kt new file mode 100644 index 0000000..45f71c9 --- /dev/null +++ b/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmCodeStyleSettingsProvider.kt @@ -0,0 +1,31 @@ +package de.platon42.intellij.plugins.m68k.formatter + +import com.intellij.application.options.CodeStyleAbstractConfigurable +import com.intellij.application.options.CodeStyleAbstractPanel +import com.intellij.application.options.TabbedLanguageCodeStylePanel +import com.intellij.psi.codeStyle.CodeStyleConfigurable +import com.intellij.psi.codeStyle.CodeStyleSettings +import com.intellij.psi.codeStyle.CodeStyleSettingsProvider +import com.intellij.psi.codeStyle.CustomCodeStyleSettings +import de.platon42.intellij.plugins.m68k.MC68000Language + + +class M68kAsmCodeStyleSettingsProvider : CodeStyleSettingsProvider() { + + override fun createCustomSettings(settings: CodeStyleSettings): CustomCodeStyleSettings { + return M68kAsmCodeStyleSettings(settings) + } + + override fun createConfigurable(settings: CodeStyleSettings, modelSettings: CodeStyleSettings): CodeStyleConfigurable { + return object : CodeStyleAbstractConfigurable(settings, modelSettings, configurableDisplayName) { + override fun createPanel(settings: CodeStyleSettings): CodeStyleAbstractPanel { + return M68kAsmCodeStyleMainPanel(currentSettings, settings) + } + } + } + + override fun getConfigurableDisplayName() = "M68k" + + private class M68kAsmCodeStyleMainPanel(currentSettings: CodeStyleSettings, settings: CodeStyleSettings) : + TabbedLanguageCodeStylePanel(MC68000Language.INSTANCE, currentSettings, settings) +} \ No newline at end of file diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmEolBlock.kt b/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmEolBlock.kt new file mode 100644 index 0000000..f97d340 --- /dev/null +++ b/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmEolBlock.kt @@ -0,0 +1,19 @@ +package de.platon42.intellij.plugins.m68k.formatter + +import com.intellij.formatting.* +import com.intellij.lang.ASTNode +import com.intellij.psi.formatter.common.AbstractBlock + +class M68kAsmEolBlock(node: ASTNode) : AbstractBlock( + node, Wrap.createWrap(WrapType.NONE, false), + Alignment.createAlignment() +) { + + override fun getIndent() = Indent.getNoneIndent() + + override fun getSpacing(child1: Block?, child2: Block) = null + + override fun isLeaf() = true + + override fun buildChildren() = emptyList() +} \ No newline at end of file diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmFormattingModelBuilder.kt b/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmFormattingModelBuilder.kt new file mode 100644 index 0000000..946aa22 --- /dev/null +++ b/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmFormattingModelBuilder.kt @@ -0,0 +1,19 @@ +package de.platon42.intellij.plugins.m68k.formatter + +import com.intellij.formatting.FormattingContext +import com.intellij.formatting.FormattingModel +import com.intellij.formatting.FormattingModelBuilder +import com.intellij.formatting.FormattingModelProvider + +class M68kAsmFormattingModelBuilder : FormattingModelBuilder { + + override fun createModel(formattingContext: FormattingContext): FormattingModel { + val codeStyleSettings = formattingContext.codeStyleSettings + + return FormattingModelProvider.createFormattingModelForPsiFile( + formattingContext.containingFile, + M68kAsmRootBlock(formattingContext.node, codeStyleSettings), + codeStyleSettings + ) + } +} \ No newline at end of file diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmLabelBlock.kt b/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmLabelBlock.kt new file mode 100644 index 0000000..96e9886 --- /dev/null +++ b/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmLabelBlock.kt @@ -0,0 +1,24 @@ +package de.platon42.intellij.plugins.m68k.formatter + +import com.intellij.formatting.* +import com.intellij.lang.ASTNode +import com.intellij.psi.codeStyle.CodeStyleSettings +import com.intellij.psi.formatter.common.AbstractBlock + +class M68kAsmLabelBlock( + node: ASTNode, wrap: Wrap?, alignment: Alignment?, + private val codeStyleSettings: CodeStyleSettings +) : AbstractBlock(node, wrap, alignment) { + + override fun getIndent(): Indent? { + return Indent.getAbsoluteNoneIndent() + } + + override fun getSpacing(child1: Block?, child2: Block): Spacing? { + return Spacing.getReadOnlySpacing() + } + + override fun isLeaf() = true + + override fun buildChildren() = emptyList() +} \ No newline at end of file diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmRootBlock.kt b/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmRootBlock.kt new file mode 100644 index 0000000..a6ff075 --- /dev/null +++ b/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmRootBlock.kt @@ -0,0 +1,56 @@ +package de.platon42.intellij.plugins.m68k.formatter + +import com.intellij.formatting.* +import com.intellij.lang.ASTNode +import com.intellij.psi.TokenType +import com.intellij.psi.codeStyle.CodeStyleSettings +import com.intellij.psi.formatter.common.AbstractBlock +import de.platon42.intellij.plugins.m68k.psi.M68kStatement +import de.platon42.intellij.plugins.m68k.psi.M68kTypes + +class M68kAsmRootBlock(node: ASTNode, private val codeStyleSettings: CodeStyleSettings) : AbstractBlock(node, null, null) { + + override fun getIndent(): Indent? { + return Indent.getNoneIndent() + } + + override fun getSpacing(child1: Block?, child2: Block): Spacing? { + if (child2 is M68kAsmEolBlock) { + return Spacing.createSpacing(0, 0, 0, false, 0) + } + if (child2.subBlocks.isNotEmpty()) { + return child2.getSpacing(child1, child2.subBlocks.first()) + } + return null + } + + override fun isLeaf(): Boolean { + return false + } + + override fun buildChildren(): List { + val subBlocks = ArrayList() + var child = myNode.firstChildNode + while (child != null) { + if (child.elementType == M68kTypes.EOL) { + subBlocks.add(M68kAsmEolBlock(child)) + } else if (child.elementType != TokenType.WHITE_SPACE) { + if (child.psi is M68kStatement) { + subBlocks.add(M68kAsmStatementBlock(child, codeStyleSettings)) + } else { + subBlocks.add( + M68kAsmBlock( + child, + Wrap.createWrap(WrapType.NONE, false), + Alignment.createAlignment(), + 0, codeStyleSettings + ) + ) + } + } + + child = child.treeNext + } + return subBlocks + } +} \ No newline at end of file diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmStatementBlock.kt b/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmStatementBlock.kt new file mode 100644 index 0000000..13b7464 --- /dev/null +++ b/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmStatementBlock.kt @@ -0,0 +1,106 @@ +package de.platon42.intellij.plugins.m68k.formatter + +import com.intellij.formatting.* +import com.intellij.lang.ASTNode +import com.intellij.psi.TokenType +import com.intellij.psi.codeStyle.CodeStyleSettings +import com.intellij.psi.formatter.common.AbstractBlock +import de.platon42.intellij.plugins.m68k.psi.* + +class M68kAsmStatementBlock(node: ASTNode, private val codeStyleSettings: CodeStyleSettings) : + AbstractBlock(node, Wrap.createWrap(WrapType.NONE, false), Alignment.createAlignment()) { + + override fun getIndent(): Indent { + val statement = myNode.psi as M68kStatement + if (((statement.asmInstruction != null) || (statement.preprocessorDirective != null) + || (statement.macroCall != null)) + && ((statement.localLabel == null) && (statement.globalLabel == null)) + ) { + return IndentImpl(Indent.Type.SPACES, true, codeStyleSettings.indentOptions.INDENT_SIZE, false, false) + } else { + return Indent.getAbsoluteNoneIndent() + } + } + + override fun getSpacing(child1: Block?, child2: Block): Spacing? { + if (child2 is M68kAsmBlock) { + val indentSize = codeStyleSettings.indentOptions.INDENT_SIZE + if (child1 is M68kAsmEolBlock) { + return Spacing.createSpacing(1, indentSize, 0, true, 0) + } + if (child1 is M68kAsmLabelBlock) { + val spacesLeft = indentSize - child1.node.textLength + if (spacesLeft <= 0) { + return Spacing.createSpacing(1, indentSize, 1, false, 0) + } else { + return Spacing.createSpacing(1, spacesLeft, 0, false, 0) + } + } + return Spacing.createSpacing(1, indentSize, 0, false, 0) + } + if (child2 is M68kAsmLabelBlock) { + return Spacing.createSpacing(0, 0, 0, false, 0) + } + return null + } + + override fun isLeaf() = false + + override fun buildChildren(): List { + val subBlocks = ArrayList() + var child = myNode.firstChildNode + while (child != null) { + if (child.elementType != TokenType.WHITE_SPACE) { + val element = child.psi + when (element) { + is M68kAssignment -> + subBlocks.add( + M68kAsmBlock( + child, + Wrap.createWrap(WrapType.NORMAL, false), + Alignment.createAlignment(), + 0, + codeStyleSettings + ) + ) + + is M68kAsmInstruction, is M68kPreprocessorDirective, is M68kMacroCall -> + subBlocks.add( + M68kAsmBlock( + child, + Wrap.createWrap(WrapType.NORMAL, false), + Alignment.createAlignment(), + 1, + codeStyleSettings + ) + ) + + is M68kGlobalLabel, is M68kLocalLabel -> + subBlocks.add( + M68kAsmLabelBlock( + child, + Wrap.createWrap(WrapType.NONE, false), + Alignment.createAlignment(), + codeStyleSettings + ) + ) + + + else -> + subBlocks.add( + M68kAsmBlock( + child, + Wrap.createWrap(WrapType.NONE, false), + Alignment.createAlignment(), + 1, + codeStyleSettings + ) + ) + } + } + + child = child.treeNext + } + return subBlocks + } +} \ No newline at end of file diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kLanguageCodeStyleSettingsProvider.kt b/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kLanguageCodeStyleSettingsProvider.kt new file mode 100644 index 0000000..6b7fd80 --- /dev/null +++ b/src/main/java/de/platon42/intellij/plugins/m68k/formatter/M68kLanguageCodeStyleSettingsProvider.kt @@ -0,0 +1,41 @@ +package de.platon42.intellij.plugins.m68k.formatter + +import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider +import de.platon42.intellij.plugins.m68k.MC68000Language + +class M68kLanguageCodeStyleSettingsProvider : LanguageCodeStyleSettingsProvider() { + override fun getLanguage() = MC68000Language.INSTANCE + + override fun getCodeSample(settingsType: SettingsType) = """; This is an example assembly language program +PIC_HEIGHT = 256 + + include "../includes/hardware/custom.i" + +BLTHOGON MACRO ; macro definition + move.w #DMAF_SETCLR|DMAF_BLITHOG,dmacon(a5) ; hog! + ENDM + +demo_init ; global label + tst.w d1 + beq.s .skip + PUSHM d0-d7/a0-a6 ; this is a macro call + lea hello(pc),a1 + lea pd_ModViewTable(a4,d1.w),a0 + moveq.l #0,d0 + move.w #PIC_HEIGHT-1,d7 +.loop move.l d0,(a0)+ ; local label + dbra d7,.loop + POPM +.skip rts + +irq: move.l a0,-(sp) + move usp,a0 + move.l a0,${'$'}400.w + move.l (sp)+,a0 + rte + +hello: dc.b 'Hello World!',10,0 + even + dc.w *-hello ; length of string +""" +} \ No newline at end of file diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/m68k.bnf b/src/main/java/de/platon42/intellij/plugins/m68k/m68k.bnf index caa3c09..3eab412 100644 --- a/src/main/java/de/platon42/intellij/plugins/m68k/m68k.bnf +++ b/src/main/java/de/platon42/intellij/plugins/m68k/m68k.bnf @@ -136,11 +136,10 @@ SymbolDefinition ::= SYMBOLDEF { Assignment ::= SymbolDefinition COLON? (OP_ASSIGN|EQU) expr -private LabelInsts ::= LabelWithInstruction | LabelOnly | InstructionOnly +private LabelInsts ::= LabelWithInstruction | LabelOnly | Instruction private LabelOnly ::= Label -private LabelWithInstruction ::= Label (Instruction|PreprocessorDirective) -private InstructionOnly ::= (Instruction|PreprocessorDirective) +private LabelWithInstruction ::= Label Instruction LocalLabel ::= LOCAL_LABEL_DEF COLON? { name = "local label" @@ -199,7 +198,7 @@ MacroCall ::= MACRO_INVOCATION PlainOperands? { } AsmInstruction ::= AsmOp AsmOperands? -private Instruction ::= AsmInstruction | MacroCall +private Instruction ::= AsmInstruction | MacroCall | PreprocessorDirective //external Instruction ::= parseMacroCallOrAsmInstruction private AsmOperands ::= AddressingMode (SEPARATOR AddressingMode)? diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 61cde09..3d33a85 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -21,9 +21,12 @@ implementationClass="de.platon42.intellij.plugins.m68k.parser.M68kParserDefinition"/> - + + + + diff --git a/src/test/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmFormatterTest.kt b/src/test/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmFormatterTest.kt new file mode 100644 index 0000000..4bc4bd1 --- /dev/null +++ b/src/test/java/de/platon42/intellij/plugins/m68k/formatter/M68kAsmFormatterTest.kt @@ -0,0 +1,52 @@ +package de.platon42.intellij.plugins.m68k.formatter + +import com.intellij.application.options.CodeStyle +import com.intellij.openapi.command.WriteCommandAction +import com.intellij.psi.codeStyle.CodeStyleManager +import com.intellij.testFramework.fixtures.CodeInsightTestFixture +import com.intellij.util.containers.ContainerUtil +import de.platon42.intellij.jupiter.LightCodeInsightExtension +import de.platon42.intellij.jupiter.MyFixture +import de.platon42.intellij.jupiter.TestDataPath +import org.junit.jupiter.api.Assertions.* +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.ExtendWith + + +@TestDataPath("src/test/resources/formatting") +@ExtendWith(LightCodeInsightExtension::class) +internal class M68kAsmFormatterTest { + + @Test + @Disabled + internal fun check_if_formatting_works_as_expected(@MyFixture myFixture: CodeInsightTestFixture) { + myFixture.configureByFile("basic_before.asm") + val settings = CodeStyle.getLanguageSettings(myFixture.file) + settings.indentOptions?.INDENT_SIZE = 6 + settings.indentOptions?.CONTINUATION_INDENT_SIZE = 9 + WriteCommandAction.runWriteCommandAction(myFixture.project) + { + CodeStyleManager.getInstance(myFixture.project).reformatText( + myFixture.file, + ContainerUtil.newArrayList(myFixture.file.textRange) + ) + } + myFixture.checkResultByFile("basic_after.asm") + } + + @Test + internal fun check_formatting_for_mnemonics(@MyFixture myFixture: CodeInsightTestFixture) { + myFixture.configureByFile("mnemonics_before.asm") + val settings = CodeStyle.getLanguageSettings(myFixture.file) + settings.indentOptions?.INDENT_SIZE = 8 + WriteCommandAction.runWriteCommandAction(myFixture.project) + { + CodeStyleManager.getInstance(myFixture.project).reformatText( + myFixture.file, + ContainerUtil.newArrayList(myFixture.file.textRange) + ) + } + myFixture.checkResultByFile("mnemonics_after.asm") + } +} diff --git a/src/test/resources/formatting/basic_after.asm b/src/test/resources/formatting/basic_after.asm new file mode 100644 index 0000000..728fa22 --- /dev/null +++ b/src/test/resources/formatting/basic_after.asm @@ -0,0 +1,51 @@ +; this is a test + +FOO = 1 +; this is the main demo routine +demo_main: + moveq.l #0,d0 ; end of line comment + rts ; some more comments + +; data area starts here +.data dc.w 10,0 + even + +this_is_a_very_long_label: moveq.l #0,d0 ; and an end of line comment, too + +; this is another folding area +; could be anything. + +intro_part1 + ; What is this doing here? + dc.w $47fe + illegal + rts + +; this comment is two lines away + + +intro_part2: + moveq.l #0,d1 + rts + +; standard macros +BLTWAIT MACRO +.bw\@ + btst #DMAB_BLTDONE-8,dmaconr(a5) + bne.s .bw\@ + ENDM + + MACRO BLTHOGOFF + moveq.l #0,d0 + ENDM + +********************** foobar + + +some_more_data: + dc.w $123 + dc.w $345 + dc.w $333 + dc.w $222 + +CUBE_SIZE = 100 diff --git a/src/test/resources/formatting/basic_before.asm b/src/test/resources/formatting/basic_before.asm new file mode 100644 index 0000000..130dc6e --- /dev/null +++ b/src/test/resources/formatting/basic_before.asm @@ -0,0 +1,51 @@ + ; this is a test + +FOO = 1 +; this is the main demo routine +demo_main: + moveq.l #0,d0 ; end of line comment + rts ; some more comments + +; data area starts here +.data dc.w 10,0 + even + +this_is_a_very_long_label: moveq.l #0,d0 ; and an end of line comment, too + +; this is another folding area +; could be anything. + +intro_part1 + ; What is this doing here? + dc.w $47fe + illegal + rts + +; this comment is two lines away + + +intro_part2: + moveq.l #0,d1 + rts + +; standard macros +BLTWAIT MACRO +.bw\@ + btst #DMAB_BLTDONE-8,dmaconr(a5) + bne.s .bw\@ + ENDM + + MACRO BLTHOGOFF + moveq.l #0,d0 + ENDM + +********************** foobar + + +some_more_data: + dc.w $123 + dc.w $345 + dc.w $333 + dc.w $222 + +CUBE_SIZE = 100 diff --git a/src/test/resources/formatting/mnemonics_after.asm b/src/test/resources/formatting/mnemonics_after.asm new file mode 100644 index 0000000..df68218 --- /dev/null +++ b/src/test/resources/formatting/mnemonics_after.asm @@ -0,0 +1,13 @@ + moveq.l #10,d1 + add.l #10,d1 + subq.b #2,d2 + bra.s .foo + nop +.foo move.l d2,d1 + rts +.verylonglabel: stop #$2000 + +.narf + moveq.l #2,d0 + +globallabel: moveq.l #0,d0 diff --git a/src/test/resources/formatting/mnemonics_before.asm b/src/test/resources/formatting/mnemonics_before.asm new file mode 100644 index 0000000..df68218 --- /dev/null +++ b/src/test/resources/formatting/mnemonics_before.asm @@ -0,0 +1,13 @@ + moveq.l #10,d1 + add.l #10,d1 + subq.b #2,d2 + bra.s .foo + nop +.foo move.l d2,d1 + rts +.verylonglabel: stop #$2000 + +.narf + moveq.l #2,d0 + +globallabel: moveq.l #0,d0