Added documentation provider info for global labels. Shows directives and comments above.
Fixed BNF for labels with preprocessor statements. Bumped versions.
This commit is contained in:
parent
1bff1a12c2
commit
a03de6c394
12
README.md
12
README.md
@ -112,6 +112,7 @@ If the current statement has no valid syntax, the instruction details of all mat
|
|||||||
## Known issues
|
## Known issues
|
||||||
|
|
||||||
- `Find Usages` always shows _"Unclassified"_ though it shouldn't (?)
|
- `Find Usages` always shows _"Unclassified"_ though it shouldn't (?)
|
||||||
|
- Typing in the `END` keyword will sometimes mess up the parsing for the next tokens.
|
||||||
- Macro invocations are not yet evaluated, thus no referencing to symbols defined via macros (e.g. `STRUCT`).
|
- Macro invocations are not yet evaluated, thus no referencing to symbols defined via macros (e.g. `STRUCT`).
|
||||||
- Scoping for global symbols and labels is currently the whole project.
|
- Scoping for global symbols and labels is currently the whole project.
|
||||||
- No support for register replacement (e.g. registers replaced by `EQUR` or `EQURL` will cause syntax errors)
|
- No support for register replacement (e.g. registers replaced by `EQUR` or `EQURL` will cause syntax errors)
|
||||||
@ -142,19 +143,22 @@ make it work with JUnit 5. Feel free to use the code (in package ```de.platon42.
|
|||||||
|
|
||||||
## Feedback
|
## Feedback
|
||||||
|
|
||||||
I guess there are currently about 100 users of this plugin and while I wrote this mainly for myself, I'm only doing this in my spare time. Feedback
|
I guess there are currently over 500 users of this plugin and while I wrote this mainly for myself, I'm only doing this in my spare time.
|
||||||
and [rating](https://plugins.jetbrains.com/plugin/17268-mc68000-assembly-language-support/reviews)
|
|
||||||
are appreciated. They really are, because they do keep me motivated to continue development.
|
Feedback and [rating](https://plugins.jetbrains.com/plugin/17268-mc68000-assembly-language-support/reviews)
|
||||||
|
are appreciated. It really is keeping me motivated to continue development.
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
### V0.7 (unreleased)
|
### V0.7 (26-Sep-21)
|
||||||
|
|
||||||
- Bugfix: `btst` with pc-relative and weird immediate mode was missing (courtesy of Yann).
|
- Bugfix: `btst` with pc-relative and weird immediate mode was missing (courtesy of Yann).
|
||||||
- Bugfix: `movem` with pc-relative mode was missing for weird immediate mode (courtesy of Yann).
|
- Bugfix: `movem` with pc-relative mode was missing for weird immediate mode (courtesy of Yann).
|
||||||
- Bugfix: Special registers for address mode matching only worked with lower case register names (courtesy of Yann).
|
- Bugfix: Special registers for address mode matching only worked with lower case register names (courtesy of Yann).
|
||||||
- Enhancement: Assembler syntax with implicit immediate 1 for shifts and rotations no longer cause syntax errors (courtesy of Yann).
|
- Enhancement: Assembler syntax with implicit immediate 1 for shifts and rotations no longer cause syntax errors (courtesy of Yann).
|
||||||
- Enhancement: Documentation for instruction with special register shows specific register expected.
|
- Enhancement: Documentation for instruction with special register shows specific register expected.
|
||||||
|
- New: Added documentation provider info for global labels. Shows directives and comments above.
|
||||||
|
- Bugfix: Fixed BNF for labels with preprocessor statements.
|
||||||
|
|
||||||
### V0.6 (09-Aug-21)
|
### V0.6 (09-Aug-21)
|
||||||
|
|
||||||
|
37
build.gradle
37
build.gradle
@ -1,9 +1,9 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
id 'org.jetbrains.intellij' version '1.1.5'
|
id 'org.jetbrains.intellij' version '1.1.6'
|
||||||
id 'org.jetbrains.kotlin.jvm' version '1.5.21'
|
id 'org.jetbrains.kotlin.jvm' version '1.5.21'
|
||||||
id 'jacoco'
|
id 'jacoco'
|
||||||
id 'com.github.kt3k.coveralls' version '2.11.0'
|
id 'com.github.kt3k.coveralls' version '2.12.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
group = 'de.platon42'
|
group = 'de.platon42'
|
||||||
@ -22,9 +22,9 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
|
implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
|
||||||
testImplementation "org.assertj:assertj-core:3.20.2"
|
testImplementation "org.assertj:assertj-core:3.21.0"
|
||||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.0-M1'
|
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
|
||||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.0-M1'
|
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.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.jetbrains.kotlin:kotlin-test-junit"
|
// testImplementation "org.jetbrains.kotlin:kotlin-test-junit"
|
||||||
@ -57,35 +57,16 @@ runPluginVerifier {
|
|||||||
|
|
||||||
patchPluginXml {
|
patchPluginXml {
|
||||||
setChangeNotes("""
|
setChangeNotes("""
|
||||||
<h4>V0.7 (unreleased)</h4>
|
<p>I still got zero feedback and zero <a href="https://plugins.jetbrains.com/plugin/17268-mc68000-assembly-language-support/reviews">ratings</a> :-(</p>
|
||||||
|
<h4>V0.7 (26-Sep-21)</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Bugfix: 'btst' with pc-relative and weird immediate mode was missing (courtesy of Yann).
|
<li>Bugfix: 'btst' with pc-relative and weird immediate mode was missing (courtesy of Yann).
|
||||||
<li>Bugfix: 'movem' with pc-relative mode was missing for weird immediate mode (courtesy of Yann).
|
<li>Bugfix: 'movem' with pc-relative mode was missing for weird immediate mode (courtesy of Yann).
|
||||||
<li>Bugfix: Special registers for address mode matching only worked with lower case register names (courtesy of Yann).
|
<li>Bugfix: Special registers for address mode matching only worked with lower case register names (courtesy of Yann).
|
||||||
<li>Enhancement: Assembler syntax with implicit immediate 1 for shifts and rotations no longer cause syntax errors (courtesy of Yann).
|
<li>Enhancement: Assembler syntax with implicit immediate 1 for shifts and rotations no longer cause syntax errors (courtesy of Yann).
|
||||||
<li>Enhancement: Documentation for instruction with special register shows specific register expected.
|
<li>Enhancement: Documentation for instruction with special register shows specific register expected.
|
||||||
</ul>
|
<li>New: Added documentation provider info for global labels. Shows directives and comments above.
|
||||||
<h4>V0.6 (09-Aug-21)</h4>
|
<li>Bugfix: Fixed BNF for labels with preprocessor statements.
|
||||||
<ul>
|
|
||||||
<li>Enhancement: 'opt' and several other directives ('printt', 'fail' etc.) no longer causes a syntax error when unquoted.
|
|
||||||
<li>Enhancement: 'include', 'incdir' and 'incbin' and 'output' with '<pathname>' quotes no longer cause syntax error.
|
|
||||||
<li>New: Files in 'include' directives can be referenced and renamed/refactored.
|
|
||||||
<li>New: Code completion for local label definitions, suggesting undefined labels already referenced.
|
|
||||||
<li>New: Added inspection suppression possibility and quickfix.
|
|
||||||
<li>New: Added inspection for unresolved symbols, macros and labels.
|
|
||||||
<li>Enhancement: 'END' directive stops parsing.
|
|
||||||
</ul>
|
|
||||||
<h4>V0.5 (06-Aug-21)</h4>
|
|
||||||
<ul>
|
|
||||||
<li>Bugfix: movem ISA was wrong regarding movem.w <ea>,<registerlist> (sign extends registers).
|
|
||||||
<li>Cosmetics: Changed Register Flow Documentation wording from 'reads' to 'uses' and from 'modifies' to 'changes'.
|
|
||||||
<li>Bugfix: Minor fix for 'andi/eori/ori to ccr' which were not byte sized in ISA.
|
|
||||||
<li>Bugfix: Added alternate condition code tests HS (=CC) and LO (=CS).
|
|
||||||
<li>Performance: Optimized mnemonic lookup.
|
|
||||||
<li>Enhancement: Reworked Instruction Documentation provider, now shows condition codes.
|
|
||||||
<li>Bugfix: In ISA exg is no longer treated as setting a definitive value.
|
|
||||||
<li>New: Added inspection to find dead writes to registers!
|
|
||||||
<li>New: Added inspection to warn about unexpected condition code unaffecting instructions before conditional instructions.
|
|
||||||
</ul>
|
</ul>
|
||||||
<p>Full changelog available at <a href="https://github.com/chrisly42/mc68000-asm-plugin#changelog">Github project site</a>.</p>
|
<p>Full changelog available at <a href="https://github.com/chrisly42/mc68000-asm-plugin#changelog">Github project site</a>.</p>
|
||||||
""")
|
""")
|
||||||
|
@ -562,9 +562,13 @@ public class M68kParser implements PsiParser, LightPsiParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// Instruction
|
// Instruction|PreprocessorDirective
|
||||||
static boolean InstructionOnly(PsiBuilder b, int l) {
|
static boolean InstructionOnly(PsiBuilder b, int l) {
|
||||||
return Instruction(b, l + 1);
|
if (!recursion_guard_(b, l, "InstructionOnly")) return false;
|
||||||
|
boolean r;
|
||||||
|
r = Instruction(b, l + 1);
|
||||||
|
if (!r) r = PreprocessorDirective(b, l + 1);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
@ -596,18 +600,27 @@ public class M68kParser implements PsiParser, LightPsiParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// Label Instruction
|
// Label (Instruction|PreprocessorDirective)
|
||||||
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 && Instruction(b, l + 1);
|
r = r && LabelWithInstruction_1(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) {
|
||||||
@ -817,28 +830,21 @@ public class M68kParser implements PsiParser, LightPsiParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// Label? PreprocessorKeyword PreprocessorOperands?
|
// PreprocessorKeyword PreprocessorOperands?
|
||||||
public static boolean PreprocessorDirective(PsiBuilder b, int l) {
|
public static boolean PreprocessorDirective(PsiBuilder b, int l) {
|
||||||
if (!recursion_guard_(b, l, "PreprocessorDirective")) return false;
|
if (!recursion_guard_(b, l, "PreprocessorDirective")) return false;
|
||||||
|
if (!nextTokenIs(b, "<preprocessor directive>", DATA_DIRECTIVE, OTHER_DIRECTIVE)) return false;
|
||||||
boolean r;
|
boolean r;
|
||||||
Marker m = enter_section_(b, l, _NONE_, PREPROCESSOR_DIRECTIVE, "<preprocessor directive>");
|
Marker m = enter_section_(b, l, _NONE_, PREPROCESSOR_DIRECTIVE, "<preprocessor directive>");
|
||||||
r = PreprocessorDirective_0(b, l + 1);
|
r = PreprocessorKeyword(b, l + 1);
|
||||||
r = r && PreprocessorKeyword(b, l + 1);
|
r = r && PreprocessorDirective_1(b, l + 1);
|
||||||
r = r && PreprocessorDirective_2(b, l + 1);
|
|
||||||
exit_section_(b, l, m, r, false, null);
|
exit_section_(b, l, m, r, false, null);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Label?
|
|
||||||
private static boolean PreprocessorDirective_0(PsiBuilder b, int l) {
|
|
||||||
if (!recursion_guard_(b, l, "PreprocessorDirective_0")) return false;
|
|
||||||
Label(b, l + 1);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// PreprocessorOperands?
|
// PreprocessorOperands?
|
||||||
private static boolean PreprocessorDirective_2(PsiBuilder b, int l) {
|
private static boolean PreprocessorDirective_1(PsiBuilder b, int l) {
|
||||||
if (!recursion_guard_(b, l, "PreprocessorDirective_2")) return false;
|
if (!recursion_guard_(b, l, "PreprocessorDirective_1")) return false;
|
||||||
PreprocessorOperands(b, l + 1);
|
PreprocessorOperands(b, l + 1);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1220,14 +1226,12 @@ public class M68kParser implements PsiParser, LightPsiParser {
|
|||||||
|
|
||||||
/* ********************************************************** */
|
/* ********************************************************** */
|
||||||
// Assignment
|
// Assignment
|
||||||
// | PreprocessorDirective
|
|
||||||
// | LabelInsts
|
// | LabelInsts
|
||||||
public static boolean statement(PsiBuilder b, int l) {
|
public static boolean statement(PsiBuilder b, int l) {
|
||||||
if (!recursion_guard_(b, l, "statement")) return false;
|
if (!recursion_guard_(b, l, "statement")) return false;
|
||||||
boolean r;
|
boolean r;
|
||||||
Marker m = enter_section_(b, l, _NONE_, STATEMENT, "<statement>");
|
Marker m = enter_section_(b, l, _NONE_, STATEMENT, "<statement>");
|
||||||
r = Assignment(b, l + 1);
|
r = Assignment(b, l + 1);
|
||||||
if (!r) r = PreprocessorDirective(b, l + 1);
|
|
||||||
if (!r) r = LabelInsts(b, l + 1);
|
if (!r) r = LabelInsts(b, l + 1);
|
||||||
exit_section_(b, l, m, r, false, M68kParser::statement_recover);
|
exit_section_(b, l, m, r, false, M68kParser::statement_recover);
|
||||||
return r;
|
return r;
|
||||||
|
@ -2,18 +2,11 @@
|
|||||||
package de.platon42.intellij.plugins.m68k.psi;
|
package de.platon42.intellij.plugins.m68k.psi;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface M68kPreprocessorDirective extends M68kPsiElement {
|
public interface M68kPreprocessorDirective extends M68kPsiElement {
|
||||||
|
|
||||||
@Nullable
|
|
||||||
M68kGlobalLabel getGlobalLabel();
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
M68kLocalLabel getLocalLabel();
|
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
M68kPreprocessorKeyword getPreprocessorKeyword();
|
M68kPreprocessorKeyword getPreprocessorKeyword();
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ import com.intellij.psi.PsiElementVisitor;
|
|||||||
import com.intellij.psi.util.PsiTreeUtil;
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import de.platon42.intellij.plugins.m68k.psi.*;
|
import de.platon42.intellij.plugins.m68k.psi.*;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -26,18 +25,6 @@ public class M68kPreprocessorDirectiveImpl extends M68kPreprocessorDirectiveMixi
|
|||||||
else super.accept(visitor);
|
else super.accept(visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public M68kGlobalLabel getGlobalLabel() {
|
|
||||||
return PsiTreeUtil.getChildOfType(this, M68kGlobalLabel.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public M68kLocalLabel getLocalLabel() {
|
|
||||||
return PsiTreeUtil.getChildOfType(this, M68kLocalLabel.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public M68kPreprocessorKeyword getPreprocessorKeyword() {
|
public M68kPreprocessorKeyword getPreprocessorKeyword() {
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
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<String>()
|
||||||
|
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("<br>", DocumentationMarkup.GRAYED_START, DocumentationMarkup.GRAYED_END) else ""
|
||||||
|
|
||||||
|
commentpart +
|
||||||
|
DocumentationMarkup.DEFINITION_START + StringUtil.escapeXmlEntities(element.name!!) + DocumentationMarkup.DEFINITION_END +
|
||||||
|
content
|
||||||
|
} else null
|
||||||
|
}
|
||||||
|
}
|
@ -16,7 +16,7 @@ class M68kSymbolDefinitionDocumentationProvider : AbstractDocumentationProvider(
|
|||||||
override fun generateDoc(element: PsiElement, originalElement: PsiElement?): String? {
|
override fun generateDoc(element: PsiElement, originalElement: PsiElement?): String? {
|
||||||
return if (element is M68kSymbolDefinition) {
|
return if (element is M68kSymbolDefinition) {
|
||||||
// TODO find out how we can generate inner links for more symbol references inside the expression (DocumentationManagerUtil)
|
// TODO find out how we can generate inner links for more symbol references inside the expression (DocumentationManagerUtil)
|
||||||
val value = (element.getParent() as M68kAssignment).expr.text
|
val value = (element.parent as M68kAssignment).expr.text
|
||||||
DocumentationMarkup.DEFINITION_START + StringUtil.escapeXmlEntities(element.name!!) + DocumentationMarkup.DEFINITION_END +
|
DocumentationMarkup.DEFINITION_START + StringUtil.escapeXmlEntities(element.name!!) + DocumentationMarkup.DEFINITION_END +
|
||||||
DocumentationMarkup.CONTENT_START + StringUtil.escapeXmlEntities(value) + DocumentationMarkup.CONTENT_END
|
DocumentationMarkup.CONTENT_START + StringUtil.escapeXmlEntities(value) + DocumentationMarkup.CONTENT_END
|
||||||
} else null
|
} else null
|
||||||
|
@ -121,7 +121,6 @@ M68kFile ::= line*
|
|||||||
private line ::= !<<eof>> (MacroDefinition | statement) (<<eof>>|EOL)
|
private line ::= !<<eof>> (MacroDefinition | statement) (<<eof>>|EOL)
|
||||||
|
|
||||||
statement ::= (Assignment
|
statement ::= (Assignment
|
||||||
| PreprocessorDirective
|
|
||||||
| LabelInsts)
|
| LabelInsts)
|
||||||
{pin = 1 recoverWhile = statement_recover}
|
{pin = 1 recoverWhile = statement_recover}
|
||||||
|
|
||||||
@ -140,8 +139,8 @@ Assignment ::= SymbolDefinition COLON? (OP_ASSIGN|EQU) expr
|
|||||||
private LabelInsts ::= LabelWithInstruction | LabelOnly | InstructionOnly
|
private LabelInsts ::= LabelWithInstruction | LabelOnly | InstructionOnly
|
||||||
|
|
||||||
private LabelOnly ::= Label
|
private LabelOnly ::= Label
|
||||||
private LabelWithInstruction ::= Label Instruction
|
private LabelWithInstruction ::= Label (Instruction|PreprocessorDirective)
|
||||||
private InstructionOnly ::= Instruction
|
private InstructionOnly ::= (Instruction|PreprocessorDirective)
|
||||||
|
|
||||||
LocalLabel ::= LOCAL_LABEL_DEF COLON? {
|
LocalLabel ::= LOCAL_LABEL_DEF COLON? {
|
||||||
name = "local label"
|
name = "local label"
|
||||||
@ -175,7 +174,7 @@ AsmOp ::= MNEMONIC OperandSize? {
|
|||||||
|
|
||||||
PreprocessorKeyword ::= (DATA_DIRECTIVE | OTHER_DIRECTIVE)
|
PreprocessorKeyword ::= (DATA_DIRECTIVE | OTHER_DIRECTIVE)
|
||||||
|
|
||||||
PreprocessorDirective ::= Label? PreprocessorKeyword PreprocessorOperands? {
|
PreprocessorDirective ::= PreprocessorKeyword PreprocessorOperands? {
|
||||||
mixin = "de.platon42.intellij.plugins.m68k.psi.M68kPreprocessorDirectiveMixin"
|
mixin = "de.platon42.intellij.plugins.m68k.psi.M68kPreprocessorDirectiveMixin"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ object M68kPsiImplUtil {
|
|||||||
|
|
||||||
// Local Label
|
// Local Label
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getName(element: M68kLocalLabel): String = element.firstChild?.text ?: ""
|
fun getName(element: M68kLocalLabel): String? = element.firstChild?.text
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun setName(element: M68kLocalLabel, name: String): PsiElement {
|
fun setName(element: M68kLocalLabel, name: String): PsiElement {
|
||||||
|
@ -39,6 +39,8 @@
|
|||||||
implementationClass="de.platon42.intellij.plugins.m68k.refs.M68kPreprocessorDirectiveElementManipulator"/>
|
implementationClass="de.platon42.intellij.plugins.m68k.refs.M68kPreprocessorDirectiveElementManipulator"/>
|
||||||
<lang.documentationProvider language="MC68000"
|
<lang.documentationProvider language="MC68000"
|
||||||
implementationClass="de.platon42.intellij.plugins.m68k.documentation.M68kSymbolDefinitionDocumentationProvider"/>
|
implementationClass="de.platon42.intellij.plugins.m68k.documentation.M68kSymbolDefinitionDocumentationProvider"/>
|
||||||
|
<lang.documentationProvider language="MC68000"
|
||||||
|
implementationClass="de.platon42.intellij.plugins.m68k.documentation.M68kGlobalLabelDocumentationProvider"/>
|
||||||
<lang.documentationProvider language="MC68000"
|
<lang.documentationProvider language="MC68000"
|
||||||
implementationClass="de.platon42.intellij.plugins.m68k.documentation.M68kRegisterFlowDocumentationProvider"/>
|
implementationClass="de.platon42.intellij.plugins.m68k.documentation.M68kRegisterFlowDocumentationProvider"/>
|
||||||
<lang.documentationProvider language="MC68000"
|
<lang.documentationProvider language="MC68000"
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
package de.platon42.intellij.plugins.m68k.documentation
|
||||||
|
|
||||||
|
import com.intellij.testFramework.fixtures.CodeInsightTestFixture
|
||||||
|
import de.platon42.intellij.jupiter.LightCodeInsightExtension
|
||||||
|
import de.platon42.intellij.jupiter.MyFixture
|
||||||
|
import org.assertj.core.api.Assertions.assertThat
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith
|
||||||
|
|
||||||
|
@ExtendWith(LightCodeInsightExtension::class)
|
||||||
|
internal class M68kGlobalLabelDocumentationProviderTest : AbstractDocumentationProviderTest() {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
internal fun check_documentation_for_a_label_definition(@MyFixture myFixture: CodeInsightTestFixture) {
|
||||||
|
myFixture.configureByText(
|
||||||
|
"documentme.asm", """
|
||||||
|
rts
|
||||||
|
; inputs: d0 = number
|
||||||
|
|
||||||
|
; output: d0 = square
|
||||||
|
squareme: include "fancysquarecode.asm"
|
||||||
|
rts
|
||||||
|
bsr square<caret>me
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
assertThat(generateDocumentation(myFixture))
|
||||||
|
.isEqualTo("<span class='grayed'>; inputs: d0 = number<br>; output: d0 = square</span><div class='definition'><pre>squareme</pre></div><div class='content'>include "fancysquarecode.asm"</div>")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
internal fun check_documentation_for_a_label_definition_next_line(@MyFixture myFixture: CodeInsightTestFixture) {
|
||||||
|
myFixture.configureByText(
|
||||||
|
"documentme.asm", """
|
||||||
|
; output: d0 = square
|
||||||
|
square<caret>me:
|
||||||
|
; oh man
|
||||||
|
include "fancysquarecode.asm"
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
assertThat(generateDocumentation(myFixture))
|
||||||
|
.isEqualTo("<span class='grayed'>; output: d0 = square</span><div class='definition'><pre>squareme</pre></div><div class='content'>include "fancysquarecode.asm"</div>")
|
||||||
|
}
|
||||||
|
}
|
@ -1,10 +1,10 @@
|
|||||||
Assembly File: a.asm
|
Assembly File: a.asm
|
||||||
M68kStatementImpl(STATEMENT)
|
M68kStatementImpl(STATEMENT)
|
||||||
|
M68kGlobalLabelImpl(GLOBAL_LABEL)
|
||||||
|
PsiElement(M68kTokenType.GLOBAL_LABEL_DEF)('foo')
|
||||||
|
PsiElement(M68kTokenType.COLON)(':')
|
||||||
|
PsiWhiteSpace(' ')
|
||||||
M68kPreprocessorDirectiveImpl(PREPROCESSOR_DIRECTIVE)
|
M68kPreprocessorDirectiveImpl(PREPROCESSOR_DIRECTIVE)
|
||||||
M68kGlobalLabelImpl(GLOBAL_LABEL)
|
|
||||||
PsiElement(M68kTokenType.GLOBAL_LABEL_DEF)('foo')
|
|
||||||
PsiElement(M68kTokenType.COLON)(':')
|
|
||||||
PsiWhiteSpace(' ')
|
|
||||||
M68kPreprocessorKeywordImpl(PREPROCESSOR_KEYWORD)
|
M68kPreprocessorKeywordImpl(PREPROCESSOR_KEYWORD)
|
||||||
PsiElement(M68kTokenType.DATA_DIRECTIVE)('dc.b')
|
PsiElement(M68kTokenType.DATA_DIRECTIVE)('dc.b')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
Assembly File: a.asm
|
Assembly File: a.asm
|
||||||
M68kStatementImpl(STATEMENT)
|
M68kStatementImpl(STATEMENT)
|
||||||
|
M68kGlobalLabelImpl(GLOBAL_LABEL)
|
||||||
|
PsiElement(M68kTokenType.GLOBAL_LABEL_DEF)('howto')
|
||||||
|
PsiElement(M68kTokenType.COLON)(':')
|
||||||
M68kPreprocessorDirectiveImpl(PREPROCESSOR_DIRECTIVE)
|
M68kPreprocessorDirectiveImpl(PREPROCESSOR_DIRECTIVE)
|
||||||
M68kGlobalLabelImpl(GLOBAL_LABEL)
|
|
||||||
PsiElement(M68kTokenType.GLOBAL_LABEL_DEF)('howto')
|
|
||||||
PsiElement(M68kTokenType.COLON)(':')
|
|
||||||
M68kPreprocessorKeywordImpl(PREPROCESSOR_KEYWORD)
|
M68kPreprocessorKeywordImpl(PREPROCESSOR_KEYWORD)
|
||||||
PsiElement(M68kTokenType.OTHER_DIRECTIVE)('incbin')
|
PsiElement(M68kTokenType.OTHER_DIRECTIVE)('incbin')
|
||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
|
Loading…
Reference in New Issue
Block a user