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:
@@ -562,9 +562,13 @@ public class M68kParser implements PsiParser, LightPsiParser {
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// Instruction
|
||||
// Instruction|PreprocessorDirective
|
||||
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) {
|
||||
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 && Instruction(b, l + 1);
|
||||
r = r && LabelWithInstruction_1(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) {
|
||||
@@ -817,28 +830,21 @@ public class M68kParser implements PsiParser, LightPsiParser {
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// Label? PreprocessorKeyword PreprocessorOperands?
|
||||
// PreprocessorKeyword PreprocessorOperands?
|
||||
public static boolean PreprocessorDirective(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "PreprocessorDirective")) return false;
|
||||
if (!nextTokenIs(b, "<preprocessor directive>", DATA_DIRECTIVE, OTHER_DIRECTIVE)) return false;
|
||||
boolean r;
|
||||
Marker m = enter_section_(b, l, _NONE_, PREPROCESSOR_DIRECTIVE, "<preprocessor directive>");
|
||||
r = PreprocessorDirective_0(b, l + 1);
|
||||
r = r && PreprocessorKeyword(b, l + 1);
|
||||
r = r && PreprocessorDirective_2(b, l + 1);
|
||||
r = PreprocessorKeyword(b, l + 1);
|
||||
r = r && PreprocessorDirective_1(b, l + 1);
|
||||
exit_section_(b, l, m, r, false, null);
|
||||
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?
|
||||
private static boolean PreprocessorDirective_2(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "PreprocessorDirective_2")) return false;
|
||||
private static boolean PreprocessorDirective_1(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "PreprocessorDirective_1")) return false;
|
||||
PreprocessorOperands(b, l + 1);
|
||||
return true;
|
||||
}
|
||||
@@ -1220,14 +1226,12 @@ public class M68kParser implements PsiParser, LightPsiParser {
|
||||
|
||||
/* ********************************************************** */
|
||||
// Assignment
|
||||
// | PreprocessorDirective
|
||||
// | LabelInsts
|
||||
public static boolean statement(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "statement")) return false;
|
||||
boolean r;
|
||||
Marker m = enter_section_(b, l, _NONE_, STATEMENT, "<statement>");
|
||||
r = Assignment(b, l + 1);
|
||||
if (!r) r = PreprocessorDirective(b, l + 1);
|
||||
if (!r) r = LabelInsts(b, l + 1);
|
||||
exit_section_(b, l, m, r, false, M68kParser::statement_recover);
|
||||
return r;
|
||||
|
||||
@@ -2,18 +2,11 @@
|
||||
package de.platon42.intellij.plugins.m68k.psi;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface M68kPreprocessorDirective extends M68kPsiElement {
|
||||
|
||||
@Nullable
|
||||
M68kGlobalLabel getGlobalLabel();
|
||||
|
||||
@Nullable
|
||||
M68kLocalLabel getLocalLabel();
|
||||
|
||||
@NotNull
|
||||
M68kPreprocessorKeyword getPreprocessorKeyword();
|
||||
|
||||
|
||||
-13
@@ -6,7 +6,6 @@ import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import de.platon42.intellij.plugins.m68k.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -26,18 +25,6 @@ public class M68kPreprocessorDirectiveImpl extends M68kPreprocessorDirectiveMixi
|
||||
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
|
||||
@NotNull
|
||||
public M68kPreprocessorKeyword getPreprocessorKeyword() {
|
||||
|
||||
+47
@@ -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
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -16,7 +16,7 @@ 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.getParent() as M68kAssignment).expr.text
|
||||
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
|
||||
} else null
|
||||
|
||||
@@ -121,7 +121,6 @@ M68kFile ::= line*
|
||||
private line ::= !<<eof>> (MacroDefinition | statement) (<<eof>>|EOL)
|
||||
|
||||
statement ::= (Assignment
|
||||
| PreprocessorDirective
|
||||
| LabelInsts)
|
||||
{pin = 1 recoverWhile = statement_recover}
|
||||
|
||||
@@ -140,8 +139,8 @@ Assignment ::= SymbolDefinition COLON? (OP_ASSIGN|EQU) expr
|
||||
private LabelInsts ::= LabelWithInstruction | LabelOnly | InstructionOnly
|
||||
|
||||
private LabelOnly ::= Label
|
||||
private LabelWithInstruction ::= Label Instruction
|
||||
private InstructionOnly ::= Instruction
|
||||
private LabelWithInstruction ::= Label (Instruction|PreprocessorDirective)
|
||||
private InstructionOnly ::= (Instruction|PreprocessorDirective)
|
||||
|
||||
LocalLabel ::= LOCAL_LABEL_DEF COLON? {
|
||||
name = "local label"
|
||||
@@ -175,7 +174,7 @@ AsmOp ::= MNEMONIC OperandSize? {
|
||||
|
||||
PreprocessorKeyword ::= (DATA_DIRECTIVE | OTHER_DIRECTIVE)
|
||||
|
||||
PreprocessorDirective ::= Label? PreprocessorKeyword PreprocessorOperands? {
|
||||
PreprocessorDirective ::= PreprocessorKeyword PreprocessorOperands? {
|
||||
mixin = "de.platon42.intellij.plugins.m68k.psi.M68kPreprocessorDirectiveMixin"
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ object M68kPsiImplUtil {
|
||||
|
||||
// Local Label
|
||||
@JvmStatic
|
||||
fun getName(element: M68kLocalLabel): String = element.firstChild?.text ?: ""
|
||||
fun getName(element: M68kLocalLabel): String? = element.firstChild?.text
|
||||
|
||||
@JvmStatic
|
||||
fun setName(element: M68kLocalLabel, name: String): PsiElement {
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
implementationClass="de.platon42.intellij.plugins.m68k.refs.M68kPreprocessorDirectiveElementManipulator"/>
|
||||
<lang.documentationProvider language="MC68000"
|
||||
implementationClass="de.platon42.intellij.plugins.m68k.documentation.M68kSymbolDefinitionDocumentationProvider"/>
|
||||
<lang.documentationProvider language="MC68000"
|
||||
implementationClass="de.platon42.intellij.plugins.m68k.documentation.M68kGlobalLabelDocumentationProvider"/>
|
||||
<lang.documentationProvider language="MC68000"
|
||||
implementationClass="de.platon42.intellij.plugins.m68k.documentation.M68kRegisterFlowDocumentationProvider"/>
|
||||
<lang.documentationProvider language="MC68000"
|
||||
|
||||
+43
@@ -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
|
||||
M68kStatementImpl(STATEMENT)
|
||||
M68kGlobalLabelImpl(GLOBAL_LABEL)
|
||||
PsiElement(M68kTokenType.GLOBAL_LABEL_DEF)('foo')
|
||||
PsiElement(M68kTokenType.COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
M68kPreprocessorDirectiveImpl(PREPROCESSOR_DIRECTIVE)
|
||||
M68kGlobalLabelImpl(GLOBAL_LABEL)
|
||||
PsiElement(M68kTokenType.GLOBAL_LABEL_DEF)('foo')
|
||||
PsiElement(M68kTokenType.COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
M68kPreprocessorKeywordImpl(PREPROCESSOR_KEYWORD)
|
||||
PsiElement(M68kTokenType.DATA_DIRECTIVE)('dc.b')
|
||||
PsiWhiteSpace(' ')
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
Assembly File: a.asm
|
||||
M68kStatementImpl(STATEMENT)
|
||||
M68kGlobalLabelImpl(GLOBAL_LABEL)
|
||||
PsiElement(M68kTokenType.GLOBAL_LABEL_DEF)('howto')
|
||||
PsiElement(M68kTokenType.COLON)(':')
|
||||
M68kPreprocessorDirectiveImpl(PREPROCESSOR_DIRECTIVE)
|
||||
M68kGlobalLabelImpl(GLOBAL_LABEL)
|
||||
PsiElement(M68kTokenType.GLOBAL_LABEL_DEF)('howto')
|
||||
PsiElement(M68kTokenType.COLON)(':')
|
||||
M68kPreprocessorKeywordImpl(PREPROCESSOR_KEYWORD)
|
||||
PsiElement(M68kTokenType.OTHER_DIRECTIVE)('incbin')
|
||||
PsiWhiteSpace(' ')
|
||||
|
||||
Reference in New Issue
Block a user