WiP formatter.

This commit is contained in:
Chris Hodges 2022-12-23 20:24:50 +01:00
parent 130f6a106d
commit df2a220473
22 changed files with 580 additions and 56 deletions

View File

@ -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.). _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 ## 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 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 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

View File

@ -1,15 +1,15 @@
plugins { plugins {
id 'java' id 'java'
id 'org.jetbrains.intellij' version '1.9.0' id 'org.jetbrains.intellij' version '1.11.0'
id 'org.jetbrains.kotlin.jvm' version '1.7.20' id 'org.jetbrains.kotlin.jvm' version '1.8.0-RC2'
id 'jacoco' id 'jacoco'
id 'com.github.kt3k.coveralls' version '2.12.0' id 'com.github.kt3k.coveralls' version '2.12.0'
} }
group = 'de.platon42' group = 'de.platon42'
version = '0.10' version = '0.10'
sourceCompatibility = "1.8" sourceCompatibility = 17
targetCompatibility = "1.8" targetCompatibility = 17
repositories { repositories {
mavenCentral() mavenCentral()
@ -23,39 +23,29 @@ repositories {
dependencies { dependencies {
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8' implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
testImplementation 'org.assertj:assertj-core:3.23.1' testImplementation 'org.assertj:assertj-core:3.23.1'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.0' testImplementation 'org.junit.jupiter:junit-jupiter-api:5.9.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.9.1'
testImplementation "org.jetbrains.kotlin:kotlin-test" testImplementation "org.jetbrains.kotlin:kotlin-test"
testImplementation "org.jetbrains.kotlin:kotlin-reflect" 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" // testImplementation "org.jetbrains.kotlin:kotlin-test-junit"
} }
compileKotlin {
kotlinOptions {
jvmTarget = "1.8"
freeCompilerArgs += "-Xjvm-default=all"
}
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
}
intellij { intellij {
setVersion("2022.2.3") // LATEST-EAP-SNAPSHOT setVersion("2022.3") // LATEST-EAP-SNAPSHOT
setUpdateSinceUntilBuild(false) setUpdateSinceUntilBuild(false)
// setPlugins(["com.intellij.java"]) // setPlugins(["com.intellij.java"])
} }
runPluginVerifier { 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-203.8084.11", // 2020.3
"CL-211.7628.27", // 2021.1 "CL-211.7628.27", // 2021.1
"CL-212.5712.21", // 2021.2 "CL-212.5712.21", // 2021.2
"CL-213.7172.20", // 2021.3.4 "CL-213.7172.20", // 2021.3.4
"CL-221.5921.22", // 2022.1.3 "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" downloadDir = System.getProperty("user.home") + "/.gradle/caches/modules-2/files-2.1/com.jetbrains.intellij.idea/verifier"
} }

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists 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 zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

17
plans.txt Normal file
View File

@ -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"

View File

@ -649,22 +649,12 @@ public class M68kParser implements PsiParser, LightPsiParser {
} }
/* ********************************************************** */ /* ********************************************************** */
// AsmInstruction | MacroCall // AsmInstruction | MacroCall | PreprocessorDirective
static boolean Instruction(PsiBuilder b, int l) { static boolean Instruction(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "Instruction")) return false; if (!recursion_guard_(b, l, "Instruction")) return false;
if (!nextTokenIs(b, "", MACRO_INVOCATION, MNEMONIC)) return false;
boolean r; boolean r;
r = AsmInstruction(b, l + 1); r = AsmInstruction(b, l + 1);
if (!r) r = MacroCall(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); if (!r) r = PreprocessorDirective(b, l + 1);
return r; 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) { static boolean LabelInsts(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "LabelInsts")) return false; if (!recursion_guard_(b, l, "LabelInsts")) return false;
boolean r; boolean r;
r = LabelWithInstruction(b, l + 1); r = LabelWithInstruction(b, l + 1);
if (!r) r = LabelOnly(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; return r;
} }
@ -698,27 +688,18 @@ public class M68kParser implements PsiParser, LightPsiParser {
} }
/* ********************************************************** */ /* ********************************************************** */
// Label (Instruction|PreprocessorDirective) // Label Instruction
static boolean LabelWithInstruction(PsiBuilder b, int l) { static boolean LabelWithInstruction(PsiBuilder b, int l) {
if (!recursion_guard_(b, l, "LabelWithInstruction")) return false; if (!recursion_guard_(b, l, "LabelWithInstruction")) return false;
if (!nextTokenIs(b, "", GLOBAL_LABEL_DEF, LOCAL_LABEL_DEF)) return false; if (!nextTokenIs(b, "", GLOBAL_LABEL_DEF, LOCAL_LABEL_DEF)) return false;
boolean r; boolean r;
Marker m = enter_section_(b); Marker m = enter_section_(b);
r = Label(b, l + 1); r = Label(b, l + 1);
r = r && LabelWithInstruction_1(b, l + 1); r = r && Instruction(b, l + 1);
exit_section_(b, m, null, r); exit_section_(b, m, null, r);
return 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? // LOCAL_LABEL_DEF COLON?
public static boolean LocalLabel(PsiBuilder b, int l) { public static boolean LocalLabel(PsiBuilder b, int l) {

View File

@ -10,7 +10,7 @@ class M68kFileElementType private constructor() : ILightStubFileElementType<PsiF
@JvmField @JvmField
val INSTANCE = M68kFileElementType() val INSTANCE = M68kFileElementType()
const val STUB_VERSION = 7 const val STUB_VERSION = 8
const val STUB_EXTERNAL_ID_PREFIX = "MC68000." const val STUB_EXTERNAL_ID_PREFIX = "MC68000."
const val EXTERNAL_ID = STUB_EXTERNAL_ID_PREFIX + "FILE" const val EXTERNAL_ID = STUB_EXTERNAL_ID_PREFIX + "FILE"
} }

View File

@ -0,0 +1,51 @@
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.M68kTypes
class M68kAsmBlock(
node: ASTNode, wrap: Wrap?, alignment: Alignment?,
private val column: Int,
private val codeStyleSettings: CodeStyleSettings
) : AbstractBlock(node, wrap, alignment) {
override fun getIndent() = Indent.getNoneIndent()
private fun normalIndent(): Indent {
return IndentImpl(Indent.Type.SPACES, true, codeStyleSettings.indentOptions.INDENT_SIZE, false, false)
}
override fun getSpacing(child1: Block?, child2: Block): Spacing? {
return null
}
override fun isLeaf() = (node.firstChildNode == null)
override fun buildChildren(): List<Block> {
val subBlocks = ArrayList<Block>()
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
}
}

View File

@ -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) {
}

View File

@ -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)
}

View File

@ -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<Block>()
}

View File

@ -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
)
}
}

View File

@ -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<Block>()
}

View File

@ -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<Block> {
val subBlocks = ArrayList<Block>()
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
}
}

View File

@ -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<Block> {
val subBlocks = ArrayList<Block>()
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
}
}

View File

@ -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
"""
}

View File

@ -136,11 +136,10 @@ SymbolDefinition ::= SYMBOLDEF {
Assignment ::= SymbolDefinition COLON? (OP_ASSIGN|EQU) expr Assignment ::= SymbolDefinition COLON? (OP_ASSIGN|EQU) expr
private LabelInsts ::= LabelWithInstruction | LabelOnly | InstructionOnly private LabelInsts ::= LabelWithInstruction | LabelOnly | Instruction
private LabelOnly ::= Label private LabelOnly ::= Label
private LabelWithInstruction ::= Label (Instruction|PreprocessorDirective) private LabelWithInstruction ::= Label Instruction
private InstructionOnly ::= (Instruction|PreprocessorDirective)
LocalLabel ::= LOCAL_LABEL_DEF COLON? { LocalLabel ::= LOCAL_LABEL_DEF COLON? {
name = "local label" name = "local label"
@ -199,7 +198,7 @@ MacroCall ::= MACRO_INVOCATION PlainOperands? {
} }
AsmInstruction ::= AsmOp AsmOperands? AsmInstruction ::= AsmOp AsmOperands?
private Instruction ::= AsmInstruction | MacroCall private Instruction ::= AsmInstruction | MacroCall | PreprocessorDirective
//external Instruction ::= parseMacroCallOrAsmInstruction //external Instruction ::= parseMacroCallOrAsmInstruction
private AsmOperands ::= AddressingMode (SEPARATOR AddressingMode)? private AsmOperands ::= AddressingMode (SEPARATOR AddressingMode)?

View File

@ -21,9 +21,12 @@
implementationClass="de.platon42.intellij.plugins.m68k.parser.M68kParserDefinition"/> implementationClass="de.platon42.intellij.plugins.m68k.parser.M68kParserDefinition"/>
<lang.syntaxHighlighterFactory language="MC68000" <lang.syntaxHighlighterFactory language="MC68000"
implementationClass="de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighterFactory"/> implementationClass="de.platon42.intellij.plugins.m68k.syntax.M68kSyntaxHighlighterFactory"/>
<lang.foldingBuilder <lang.foldingBuilder language="MC68000"
language="MC68000" implementationClass="de.platon42.intellij.plugins.m68k.folding.M68kFoldingBuilder"/>
implementationClass="de.platon42.intellij.plugins.m68k.folding.M68kFoldingBuilder"/> <lang.formatter language="MC68000"
implementationClass="de.platon42.intellij.plugins.m68k.formatter.M68kAsmFormattingModelBuilder"/>
<codeStyleSettingsProvider implementation="de.platon42.intellij.plugins.m68k.formatter.M68kAsmCodeStyleSettingsProvider"/>
<langCodeStyleSettingsProvider implementation="de.platon42.intellij.plugins.m68k.formatter.M68kLanguageCodeStyleSettingsProvider"/>
<navbar implementation="de.platon42.intellij.plugins.m68k.navigation.M68kStructureAwareNavbar"/> <navbar implementation="de.platon42.intellij.plugins.m68k.navigation.M68kStructureAwareNavbar"/>
<highlightVisitor implementation="de.platon42.intellij.plugins.m68k.syntax.M68kRainbowVisitor"/> <highlightVisitor implementation="de.platon42.intellij.plugins.m68k.syntax.M68kRainbowVisitor"/>
<colorSettingsPage implementation="de.platon42.intellij.plugins.m68k.syntax.M68kColorSettingsPage"/> <colorSettingsPage implementation="de.platon42.intellij.plugins.m68k.syntax.M68kColorSettingsPage"/>

View File

@ -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")
}
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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