Macro definitions are now word and indexed, macro calls reference to definition.
Macro definition refactoring and find usages support. Structural View also shows macro definitions. Missing REPT and ENDR assembler directives added. Changed or added some icons at various places. Reference search for global labels and symbols now uses stub index.
This commit is contained in:
@@ -10,7 +10,7 @@ class M68kFileElementType private constructor() : ILightStubFileElementType<PsiF
|
||||
@JvmField
|
||||
val INSTANCE = M68kFileElementType()
|
||||
|
||||
const val STUB_VERSION = 3
|
||||
const val STUB_VERSION = 4
|
||||
const val STUB_EXTERNAL_ID_PREFIX = "MC68000."
|
||||
const val EXTERNAL_ID = STUB_EXTERNAL_ID_PREFIX + "FILE"
|
||||
}
|
||||
|
||||
@@ -7,5 +7,6 @@ object M68kIcons {
|
||||
val FILE = IconLoader.getIcon("/icons/FileType_m68k.svg", javaClass)
|
||||
val LOCAL_LABEL = AllIcons.Nodes.AbstractMethod
|
||||
val GLOBAL_LABEL = AllIcons.Nodes.Method
|
||||
val SYMBOL_DEF = AllIcons.Nodes.Constant
|
||||
val SYMBOL_DEF = AllIcons.Nodes.ClassInitializer
|
||||
val MACRO_DEF = AllIcons.Nodes.MultipleTypeDefinitions
|
||||
}
|
||||
@@ -3,46 +3,48 @@ package de.platon42.intellij.plugins.m68k.asm
|
||||
object AssemblerDirectives {
|
||||
|
||||
val dataDirectives: Set<String> = setOf(
|
||||
"section", "pushsection", "popsection",
|
||||
"bss", "bss_c", "bss_f",
|
||||
"data", "data_c", "data_f",
|
||||
"text", "cseg", "code", "code_c", "code_f",
|
||||
"offset",
|
||||
"section", "pushsection", "popsection",
|
||||
"bss", "bss_c", "bss_f",
|
||||
"data", "data_c", "data_f",
|
||||
"text", "cseg", "code", "code_c", "code_f",
|
||||
"offset",
|
||||
|
||||
"abs",
|
||||
"db", "dw", "dl",
|
||||
"dr.b", "dr.w", "dr.l",
|
||||
"dc", "dc.b", "dc.w", "dc.l", "dcb", "dcb.b", "dcb.w", "dcb.l",
|
||||
"blk.b", "blk.w", "blk.l",
|
||||
"ds", "ds.b", "ds.w", "ds.l",
|
||||
"abs",
|
||||
"db", "dw", "dl",
|
||||
"dr.b", "dr.w", "dr.l",
|
||||
"dc", "dc.b", "dc.w", "dc.l", "dcb", "dcb.b", "dcb.w", "dcb.l",
|
||||
"blk.b", "blk.w", "blk.l",
|
||||
"ds", "ds.b", "ds.w", "ds.l",
|
||||
|
||||
"align", "even", "odd", "cnop", "long", "dphrase", "phrase", "qphrase",
|
||||
"align", "even", "odd", "cnop", "long", "dphrase", "phrase", "qphrase",
|
||||
|
||||
"cargs", "comm", "comment",
|
||||
"rsset", "clrfo", "clrso", "setfo", "setso"
|
||||
"cargs", "comm", "comment",
|
||||
"rsset", "clrfo", "clrso", "setfo", "setso"
|
||||
)
|
||||
|
||||
val otherDirective: Set<String> = setOf(
|
||||
"if",
|
||||
"ifeq", "ifne", "ifgt", "ifge", "iflt", "ifle", "ifb", "ifnb", "ifc", "ifnc",
|
||||
"ifd", "ifnd", "ifmacrod", "ifmacrond",
|
||||
//"iif" // not supported
|
||||
"else", "endif", "endc",
|
||||
"if",
|
||||
"ifeq", "ifne", "ifgt", "ifge", "iflt", "ifle", "ifb", "ifnb", "ifc", "ifnc",
|
||||
"ifd", "ifnd", "ifmacrod", "ifmacrond",
|
||||
//"iif" // not supported
|
||||
"else", "endif", "endc",
|
||||
|
||||
"macro", "exitm", "mexit", "endm",
|
||||
"rept", "endr",
|
||||
|
||||
"extern", "nref", "xdef", "xref", "globl", "public", "weak",
|
||||
"macro", "exitm", "mexit", "endm",
|
||||
|
||||
"reg", "equr", "equrl",
|
||||
"extern", "nref", "xdef", "xref", "globl", "public", "weak",
|
||||
|
||||
"incdir", "include", "incbin", "output",
|
||||
"reg", "equr", "equrl",
|
||||
|
||||
"list", "nlist", "nolist", "llen", "nopage", "page", "spc",
|
||||
"org",
|
||||
"incdir", "include", "incbin", "output",
|
||||
|
||||
"assert", "fail", "print", "printt", "printv", "echo",
|
||||
"list", "nlist", "nolist", "llen", "nopage", "page", "spc",
|
||||
"org",
|
||||
|
||||
"inline", "einline",
|
||||
"rem", "erem"
|
||||
"assert", "fail", "print", "printt", "printv", "echo",
|
||||
|
||||
"inline", "einline",
|
||||
"rem", "erem"
|
||||
)
|
||||
}
|
||||
+9
-2
@@ -2,15 +2,22 @@ package de.platon42.intellij.plugins.m68k.asm
|
||||
|
||||
import com.intellij.codeInsight.completion.*
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||
import com.intellij.icons.AllIcons
|
||||
import com.intellij.patterns.PlatformPatterns
|
||||
import com.intellij.util.ProcessingContext
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kTypes
|
||||
|
||||
class M68kMnemonicCompletionContributor : CompletionContributor() {
|
||||
|
||||
companion object {
|
||||
val MNEMONICS = M68kIsa.mnemonics
|
||||
.map { PrioritizedLookupElement.withPriority(LookupElementBuilder.create(it).withIcon(AllIcons.Nodes.Protected), 10.0) }
|
||||
}
|
||||
|
||||
init {
|
||||
extend(CompletionType.BASIC, PlatformPatterns.psiElement(M68kTypes.MACRO_INVOKATION), object : CompletionProvider<CompletionParameters>() {
|
||||
extend(CompletionType.BASIC, PlatformPatterns.psiElement(M68kTypes.MACRO_INVOCATION), object : CompletionProvider<CompletionParameters>() {
|
||||
override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, resultSet: CompletionResultSet) {
|
||||
resultSet.addAllElements(M68kIsa.mnemonics.map(LookupElementBuilder::create))
|
||||
resultSet.addAllElements(MNEMONICS)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.intellij.psi.TokenType
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import de.platon42.intellij.plugins.m68k.asm.AssemblerDirectives
|
||||
import de.platon42.intellij.plugins.m68k.asm.M68kIsa.mnemonics
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kTypes
|
||||
|
||||
object LexerUtil {
|
||||
|
||||
@@ -48,6 +49,17 @@ object LexerUtil {
|
||||
return TokenType.WHITE_SPACE
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun handleMacroMode(lexer: _M68kLexer): IElementType {
|
||||
if (lexer.lexerPrefs.macroParametersUnparsed) {
|
||||
lexer.yybegin(_M68kLexer.MACROCALL)
|
||||
} else {
|
||||
lexer.yybegin(_M68kLexer.ASMOPS)
|
||||
}
|
||||
lexer.eatOneWhitespace = true
|
||||
return M68kTypes.MACRO_INVOCATION
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun handleMacroLineEol(lexer: _M68kLexer): IElementType {
|
||||
if (++lexer.macroLines > lexer.lexerPrefs.maxLinesPerMacro) {
|
||||
|
||||
@@ -89,10 +89,10 @@ PLAIN_MACRO_LINE=[^;\r\n]+
|
||||
if(isAsmMnemonic(yytext())) { yybegin(ASMINSTR); return MNEMONIC; }
|
||||
if(isDataDirective(yytext())) { yybegin(EXPR); return DATA_DIRECTIVE; }
|
||||
if(isOtherDirective(yytext())) { yybegin(EXPR); return OTHER_DIRECTIVE; }
|
||||
yybegin(MACROCALL); eatOneWhitespace = true; return MACRO_INVOKATION;
|
||||
return handleMacroMode(this);
|
||||
}
|
||||
// {MNEMONIC} { if(isAsmMnemonic(yytext())) { yybegin(ASMINSTR); return MNEMONIC; } else { yybegin(INSTRPART); return SYMBOL; } }
|
||||
{MACRONAME} { yybegin(MACROCALL); eatOneWhitespace = true; return MACRO_INVOKATION; }
|
||||
{MACRONAME} { return handleMacroMode(this); }
|
||||
{HASH_COMMENT} { yybegin(YYINITIAL); return COMMENT; }
|
||||
}
|
||||
|
||||
@@ -107,10 +107,10 @@ PLAIN_MACRO_LINE=[^;\r\n]+
|
||||
if(isAsmMnemonic(yytext())) { yybegin(ASMINSTR); return MNEMONIC; }
|
||||
if(isDataDirective(yytext())) { yybegin(EXPR); return DATA_DIRECTIVE; }
|
||||
if(isOtherDirective(yytext())) { yybegin(EXPR); return OTHER_DIRECTIVE; }
|
||||
yybegin(MACROCALL); eatOneWhitespace = true; return MACRO_INVOKATION;
|
||||
return handleMacroMode(this);
|
||||
}
|
||||
// {MNEMONIC} { if(isAsmMnemonic(yytext())) { yybegin(ASMINSTR); return MNEMONIC; } else { return SYMBOL; } }
|
||||
{MACRONAME} { yybegin(MACROCALL); eatOneWhitespace = true; return MACRO_INVOKATION; }
|
||||
{MACRONAME} { return handleMacroMode(this); }
|
||||
|
||||
{COMMENT} { yybegin(WAITEOL); return COMMENT; }
|
||||
}
|
||||
@@ -130,10 +130,10 @@ PLAIN_MACRO_LINE=[^;\r\n]+
|
||||
{WHITE_SPACE} { return handleEolCommentWhitespace(this); }
|
||||
{EOL} { yybegin(YYINITIAL); return EOL; }
|
||||
|
||||
{COMMENT} { yybegin(WAITEOL); return COMMENT; }
|
||||
|
||||
"," { return SEPARATOR; }
|
||||
|
||||
{COMMENT} { yybegin(WAITEOL); return COMMENT; }
|
||||
|
||||
{PLAINPARAM} { return STRINGLIT; }
|
||||
}
|
||||
|
||||
|
||||
@@ -173,9 +173,22 @@ PreprocessorDirective ::= Label? (DATA_DIRECTIVE | OTHER_DIRECTIVE)
|
||||
MacroPlainLine ::= MACRO_LINE
|
||||
MacroNameDefinition ::= MACRO_NAME
|
||||
|
||||
MacroDefinition ::= ((MacroNameDefinition MACRO_TAG)|(MACRO_TAG MacroNameDefinition)) MacroPlainLine* MACRO_END_TAG {pin=1}
|
||||
MacroDefinition ::= ((MacroNameDefinition MACRO_TAG)|(MACRO_TAG MacroNameDefinition)) MacroPlainLine* MACRO_END_TAG {
|
||||
pin=1
|
||||
name = "macro definition"
|
||||
implements = "de.platon42.intellij.plugins.m68k.psi.M68kNamedElement"
|
||||
mixin = "de.platon42.intellij.plugins.m68k.psi.M68kMacroDefinitionMixin"
|
||||
elementTypeFactory = "de.platon42.intellij.plugins.m68k.stubs.M68kStubElementTypeFactory.stubFactory"
|
||||
stubClass = "de.platon42.intellij.plugins.m68k.stubs.M68kMacroDefinitionStub"
|
||||
methods = [getName setName getNameIdentifier]
|
||||
}
|
||||
|
||||
|
||||
MacroCall ::= MACRO_INVOCATION PlainOperands? {
|
||||
mixin = "de.platon42.intellij.plugins.m68k.psi.M68kMacroCallMixin"
|
||||
methods = [getMacroName]
|
||||
}
|
||||
|
||||
MacroCall ::= MACRO_INVOKATION PlainOperands?
|
||||
AsmInstruction ::= AsmOp AsmOperands?
|
||||
private Instruction ::= AsmInstruction | MacroCall
|
||||
//external Instruction ::= parseMacroCallOrAsmInstruction
|
||||
@@ -185,7 +198,7 @@ private AsmOperands ::= AddressingMode (SEPARATOR AddressingMode)?
|
||||
private PreprocessorOperands ::= PreprocessorOperand (SEPARATOR PreprocessorOperand)*
|
||||
private PreprocessorOperand ::= expr
|
||||
|
||||
private PlainOperands ::= STRINGLIT (SEPARATOR STRINGLIT)*
|
||||
private PlainOperands ::= (expr|AddressingMode) (SEPARATOR (expr|AddressingMode))*
|
||||
|
||||
// TODO This should probably be a ILazyParseableElementType, no idea how to implement that yet
|
||||
SymbolReference ::= SYMBOL {
|
||||
|
||||
@@ -27,6 +27,16 @@ object M68kElementFactory {
|
||||
return PsiTreeUtil.findChildOfType(file, M68kSymbolReference::class.java)!!
|
||||
}
|
||||
|
||||
fun createMacroDefinition(project: Project, name: String): M68kMacroDefinition {
|
||||
val file = createFile(project, "$name macro\nendm\n")
|
||||
return PsiTreeUtil.findChildOfType(file, M68kMacroDefinition::class.java)!!
|
||||
}
|
||||
|
||||
fun createMacroCall(project: Project, name: String): M68kMacroCall {
|
||||
val file = createFile(project, " $name\n")
|
||||
return PsiTreeUtil.findChildOfType(file, M68kMacroCall::class.java)!!
|
||||
}
|
||||
|
||||
fun createFile(project: Project, content: String): M68kFile {
|
||||
return PsiFileFactory.getInstance(project).createFileFromText("dummy.m68k", INSTANCE, content) as M68kFile
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.stubs.StubIndex
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import de.platon42.intellij.plugins.m68k.stubs.M68kGlobalLabelStubIndex
|
||||
import de.platon42.intellij.plugins.m68k.stubs.M68kMacroDefinitionStubIndex
|
||||
import de.platon42.intellij.plugins.m68k.stubs.M68kSymbolDefinitionStubIndex
|
||||
|
||||
object M68kLookupUtil {
|
||||
@@ -93,4 +94,47 @@ object M68kLookupUtil {
|
||||
}
|
||||
|
||||
fun findAllSymbolDefinitionNames(project: Project): Collection<String> = StubIndex.getInstance().getAllKeys(M68kSymbolDefinitionStubIndex.KEY, project)
|
||||
|
||||
|
||||
fun findAllMacroDefinitions(project: Project): List<M68kMacroDefinition> {
|
||||
val results: MutableList<M68kMacroDefinition> = ArrayList()
|
||||
StubIndex.getInstance().processAllKeys(M68kMacroDefinitionStubIndex.KEY, project)
|
||||
{
|
||||
results.addAll(
|
||||
StubIndex.getElements(
|
||||
M68kMacroDefinitionStubIndex.KEY,
|
||||
it,
|
||||
project,
|
||||
GlobalSearchScope.allScope(project),
|
||||
M68kMacroDefinition::class.java
|
||||
)
|
||||
)
|
||||
true
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
fun findAllMacroDefinitions(file: M68kFile): List<M68kMacroDefinition> {
|
||||
val results: MutableList<M68kMacroDefinition> = ArrayList()
|
||||
StubIndex.getInstance().processAllKeys(
|
||||
M68kMacroDefinitionStubIndex.KEY,
|
||||
{
|
||||
results.addAll(
|
||||
StubIndex.getElements(
|
||||
M68kMacroDefinitionStubIndex.KEY,
|
||||
it,
|
||||
file.project,
|
||||
GlobalSearchScope.fileScope(file),
|
||||
M68kMacroDefinition::class.java
|
||||
)
|
||||
)
|
||||
true
|
||||
}, GlobalSearchScope.fileScope(file), null
|
||||
)
|
||||
return results
|
||||
}
|
||||
|
||||
fun findAllMacroDefinitionNames(project: Project): Collection<String> = StubIndex.getInstance().getAllKeys(M68kMacroDefinitionStubIndex.KEY, project)
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package de.platon42.intellij.plugins.m68k.psi
|
||||
|
||||
import com.intellij.extapi.psi.ASTWrapperPsiElement
|
||||
import com.intellij.lang.ASTNode
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry
|
||||
|
||||
abstract class M68kMacroCallMixin(node: ASTNode) : ASTWrapperPsiElement(node), M68kMacroCall {
|
||||
|
||||
override fun getReferences(): Array<PsiReference> {
|
||||
return ReferenceProvidersRegistry.getReferencesFromProviders(this)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package de.platon42.intellij.plugins.m68k.psi
|
||||
|
||||
import com.intellij.extapi.psi.StubBasedPsiElementBase
|
||||
import com.intellij.ide.projectView.PresentationData
|
||||
import com.intellij.lang.ASTNode
|
||||
import com.intellij.navigation.ItemPresentation
|
||||
import com.intellij.psi.stubs.IStubElementType
|
||||
import de.platon42.intellij.plugins.m68k.M68kIcons
|
||||
import de.platon42.intellij.plugins.m68k.stubs.M68kMacroDefinitionStub
|
||||
import javax.swing.Icon
|
||||
|
||||
abstract class M68kMacroDefinitionMixin : StubBasedPsiElementBase<M68kMacroDefinitionStub>, M68kMacroDefinition {
|
||||
|
||||
constructor(node: ASTNode) : super(node)
|
||||
|
||||
constructor(stub: M68kMacroDefinitionStub, nodeType: IStubElementType<*, *>) : super(stub, nodeType)
|
||||
|
||||
override fun getPresentation(): ItemPresentation? {
|
||||
return PresentationData(name, containingFile.name, getIcon(0), null)
|
||||
}
|
||||
|
||||
override fun getIcon(flags: Int): Icon? {
|
||||
return M68kIcons.MACRO_DEF
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return javaClass.simpleName + "(MACRO_DEFINITION)"
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import com.intellij.psi.PsiElement
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kElementFactory.createGlobalLabel
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kElementFactory.createLocalLabel
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kElementFactory.createMacroDefinition
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kElementFactory.createSymbolDefinition
|
||||
|
||||
object M68kPsiImplUtil {
|
||||
@@ -71,4 +72,26 @@ object M68kPsiImplUtil {
|
||||
val text = element.firstChild.text
|
||||
return text.startsWith('.') || text.endsWith('$')
|
||||
}
|
||||
|
||||
|
||||
// Macro Definition
|
||||
@JvmStatic
|
||||
fun getName(element: M68kMacroDefinition): String? = element.macroNameDefinition.firstChild.text
|
||||
|
||||
@JvmStatic
|
||||
fun setName(element: M68kMacroDefinition, name: String): PsiElement {
|
||||
val nameNode = element.macroNameDefinition
|
||||
val newMacroDefinition = createMacroDefinition(element.project, name)
|
||||
nameNode.replace(newMacroDefinition.firstChild)
|
||||
return element
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getNameIdentifier(element: M68kMacroDefinition): PsiElement = element.firstChild
|
||||
|
||||
|
||||
// Macro Call
|
||||
@JvmStatic
|
||||
fun getMacroName(element: M68kMacroCall): String = element.firstChild.text
|
||||
|
||||
}
|
||||
@@ -13,12 +13,13 @@ class M68kRenameInputValidator : RenameInputValidator {
|
||||
override fun getPattern(): ElementPattern<out PsiElement?> = StandardPatterns.or(
|
||||
PlatformPatterns.psiElement(M68kGlobalLabel::class.java),
|
||||
PlatformPatterns.psiElement(M68kLocalLabel::class.java),
|
||||
PlatformPatterns.psiElement(M68kSymbolDefinition::class.java)
|
||||
PlatformPatterns.psiElement(M68kSymbolDefinition::class.java),
|
||||
PlatformPatterns.psiElement(M68kMacroDefinition::class.java)
|
||||
)
|
||||
|
||||
override fun isInputValid(newName: String, element: PsiElement, context: ProcessingContext): Boolean {
|
||||
return when (element) {
|
||||
is M68kGlobalLabel, is M68kSymbolDefinition -> SYMBOL_PATTERN.matcher(newName).matches()
|
||||
is M68kGlobalLabel, is M68kSymbolDefinition, is M68kMacroDefinition -> SYMBOL_PATTERN.matcher(newName).matches()
|
||||
is M68kLocalLabel -> LOCAL_LABEL_PATTERN.matcher(newName).matches()
|
||||
else -> false
|
||||
}
|
||||
|
||||
+19
-12
@@ -7,12 +7,14 @@ import com.intellij.psi.PsiPolyVariantReferenceBase
|
||||
import com.intellij.psi.ResolveResult
|
||||
import com.intellij.psi.impl.source.resolve.ResolveCache
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.search.PsiSearchHelper
|
||||
import com.intellij.psi.search.UsageSearchContext
|
||||
import com.intellij.psi.stubs.StubIndex
|
||||
import com.intellij.util.SmartList
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kGlobalLabel
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kNamedElement
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kSymbolDefinition
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kSymbolReference
|
||||
import de.platon42.intellij.plugins.m68k.stubs.M68kGlobalLabelStubIndex
|
||||
import de.platon42.intellij.plugins.m68k.stubs.M68kSymbolDefinitionStubIndex
|
||||
|
||||
class M68kGlobalLabelSymbolReference(element: M68kSymbolReference) :
|
||||
PsiPolyVariantReferenceBase<M68kSymbolReference>(element, TextRange(0, element.textLength)) {
|
||||
@@ -24,18 +26,23 @@ class M68kGlobalLabelSymbolReference(element: M68kSymbolReference) :
|
||||
class Resolver : ResolveCache.PolyVariantResolver<M68kGlobalLabelSymbolReference> {
|
||||
override fun resolve(ref: M68kGlobalLabelSymbolReference, incompleteCode: Boolean): Array<ResolveResult> {
|
||||
val refName = ref.element.symbolName
|
||||
|
||||
val project = ref.element.project
|
||||
val targets: MutableList<PsiElement> = SmartList()
|
||||
PsiSearchHelper.getInstance(project).processElementsWithWord(
|
||||
{ elem, _ ->
|
||||
when (elem) {
|
||||
is M68kGlobalLabel, is M68kSymbolDefinition -> targets.add(elem)
|
||||
}
|
||||
|
||||
val targets: MutableList<M68kNamedElement> = SmartList()
|
||||
StubIndex.getInstance()
|
||||
.processElements(M68kGlobalLabelStubIndex.KEY, refName, project, GlobalSearchScope.allScope(project), M68kGlobalLabel::class.java)
|
||||
{
|
||||
targets.add(it)
|
||||
true
|
||||
}, GlobalSearchScope.allScope(project),
|
||||
refName, UsageSearchContext.IN_CODE, true
|
||||
)
|
||||
}
|
||||
|
||||
StubIndex.getInstance()
|
||||
.processElements(M68kSymbolDefinitionStubIndex.KEY, refName, project, GlobalSearchScope.allScope(project), M68kSymbolDefinition::class.java)
|
||||
{
|
||||
targets.add(it)
|
||||
true
|
||||
}
|
||||
|
||||
return targets
|
||||
.map(::PsiElementResolveResult)
|
||||
.toTypedArray()
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package de.platon42.intellij.plugins.m68k.refs
|
||||
|
||||
import com.intellij.codeInsight.completion.*
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||
import com.intellij.patterns.PlatformPatterns
|
||||
import com.intellij.util.ProcessingContext
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kLookupUtil
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kTypes
|
||||
|
||||
class M68kMacroCallCompletionContributor : CompletionContributor() {
|
||||
|
||||
init {
|
||||
extend(CompletionType.BASIC, PlatformPatterns.psiElement(M68kTypes.MACRO_INVOCATION), object : CompletionProvider<CompletionParameters>() {
|
||||
override fun addCompletions(parameters: CompletionParameters, context: ProcessingContext, resultSet: CompletionResultSet) {
|
||||
resultSet.addAllElements(M68kLookupUtil.findAllMacroDefinitions(parameters.originalFile.project).map(LookupElementBuilder::createWithIcon))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package de.platon42.intellij.plugins.m68k.refs
|
||||
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.AbstractElementManipulator
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kElementFactory
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kMacroCall
|
||||
|
||||
class M68kMacroCallElementManipulator : AbstractElementManipulator<M68kMacroCall>() {
|
||||
|
||||
@Throws(IncorrectOperationException::class)
|
||||
override fun handleContentChange(element: M68kMacroCall, range: TextRange, newContent: String): M68kMacroCall {
|
||||
val newMacroCall = M68kElementFactory.createMacroCall(element.project, newContent)
|
||||
element.firstChild.replace(newMacroCall.firstChild)
|
||||
return element
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package de.platon42.intellij.plugins.m68k.refs
|
||||
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiElementResolveResult
|
||||
import com.intellij.psi.PsiPolyVariantReferenceBase
|
||||
import com.intellij.psi.ResolveResult
|
||||
import com.intellij.psi.impl.source.resolve.ResolveCache
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.stubs.StubIndex
|
||||
import com.intellij.util.SmartList
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kMacroCall
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kMacroDefinition
|
||||
import de.platon42.intellij.plugins.m68k.stubs.M68kMacroDefinitionStubIndex
|
||||
|
||||
class M68kMacroReference(element: M68kMacroCall) :
|
||||
PsiPolyVariantReferenceBase<M68kMacroCall>(element, TextRange(0, element.macroName.length)) {
|
||||
|
||||
companion object {
|
||||
val INSTANCE = Resolver()
|
||||
}
|
||||
|
||||
class Resolver : ResolveCache.PolyVariantResolver<M68kMacroReference> {
|
||||
override fun resolve(ref: M68kMacroReference, incompleteCode: Boolean): Array<ResolveResult> {
|
||||
val macroName = ref.element.macroName
|
||||
val project = ref.element.project
|
||||
|
||||
val targets: MutableList<M68kMacroDefinition> = SmartList()
|
||||
StubIndex.getInstance()
|
||||
.processElements(M68kMacroDefinitionStubIndex.KEY, macroName, project, GlobalSearchScope.allScope(project), M68kMacroDefinition::class.java)
|
||||
{
|
||||
targets.add(it)
|
||||
true
|
||||
}
|
||||
|
||||
return targets
|
||||
.map(::PsiElementResolveResult)
|
||||
.toTypedArray()
|
||||
}
|
||||
}
|
||||
|
||||
override fun multiResolve(incompleteCode: Boolean): Array<ResolveResult> =
|
||||
ResolveCache.getInstance(element.project)
|
||||
.resolveWithCaching(this, INSTANCE, false, incompleteCode)
|
||||
|
||||
override fun resolve(): PsiElement? = multiResolve(false).singleOrNull()?.element
|
||||
|
||||
override fun getVariants(): Array<Any> = emptyArray()
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package de.platon42.intellij.plugins.m68k.refs
|
||||
import com.intellij.patterns.PlatformPatterns
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.util.ProcessingContext
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kMacroCall
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kSymbolReference
|
||||
|
||||
class M68kReferenceContributor : PsiReferenceContributor() {
|
||||
@@ -10,11 +11,13 @@ class M68kReferenceContributor : PsiReferenceContributor() {
|
||||
companion object {
|
||||
val localLabelReferenceProvider = LocalLabelReferenceProvider()
|
||||
val globalLabelReferenceProvider = GlobalLabelSymbolReferenceProvider()
|
||||
val macroReferenceProvider = MacroReferenceProvider()
|
||||
}
|
||||
|
||||
override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) {
|
||||
registrar.registerReferenceProvider(PlatformPatterns.psiElement(M68kSymbolReference::class.java), localLabelReferenceProvider)
|
||||
registrar.registerReferenceProvider(PlatformPatterns.psiElement(M68kSymbolReference::class.java), globalLabelReferenceProvider)
|
||||
registrar.registerReferenceProvider(PlatformPatterns.psiElement(M68kMacroCall::class.java), macroReferenceProvider)
|
||||
}
|
||||
|
||||
class LocalLabelReferenceProvider : PsiReferenceProvider() {
|
||||
@@ -32,4 +35,9 @@ class M68kReferenceContributor : PsiReferenceContributor() {
|
||||
return arrayOf(M68kGlobalLabelSymbolReference(symbolReference))
|
||||
}
|
||||
}
|
||||
|
||||
class MacroReferenceProvider : PsiReferenceProvider() {
|
||||
override fun getReferencesByElement(element: PsiElement, context: ProcessingContext): Array<PsiReference> =
|
||||
arrayOf(M68kMacroReference(element as M68kMacroCall))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class M68kFindUsagesProvider : FindUsagesProvider {
|
||||
override fun getWordsScanner(): WordsScanner =
|
||||
DefaultWordsScanner(
|
||||
M68kLexer(M68kLexerPrefs()), // FIXME Oh no! More Prefs!
|
||||
TokenSet.create(M68kTypes.SYMBOLDEF, M68kTypes.GLOBAL_LABEL_DEF, M68kTypes.LOCAL_LABEL_DEF, M68kTypes.SYMBOL),
|
||||
TokenSet.create(M68kTypes.SYMBOLDEF, M68kTypes.GLOBAL_LABEL_DEF, M68kTypes.LOCAL_LABEL_DEF, M68kTypes.MACRO_NAME),
|
||||
TokenSet.create(M68kTypes.COMMENT),
|
||||
TokenSet.create(M68kTypes.STRINGLIT, M68kTypes.DECIMAL, M68kTypes.HEXADECIMAL, M68kTypes.OCTAL, M68kTypes.BINARY),
|
||||
TokenSet.EMPTY
|
||||
@@ -32,6 +32,8 @@ class M68kFindUsagesProvider : FindUsagesProvider {
|
||||
is M68kLocalLabel -> "local label"
|
||||
is M68kSymbolDefinition -> "symbol definition"
|
||||
is M68kSymbolReference -> "symbol reference"
|
||||
is M68kMacroDefinition -> "macro definition"
|
||||
is M68kMacroCall -> "macro call"
|
||||
is M68kRegister -> "register"
|
||||
is M68kRefExpr -> "reference expression"
|
||||
else -> ""
|
||||
@@ -44,6 +46,8 @@ class M68kFindUsagesProvider : FindUsagesProvider {
|
||||
is M68kLocalLabel -> element.name!!
|
||||
is M68kSymbolDefinition -> element.parent.text
|
||||
is M68kSymbolReference -> element.symbolName
|
||||
is M68kMacroDefinition -> element.macroNameDefinition.text
|
||||
is M68kMacroCall -> element.macroName
|
||||
is M68kRefExpr -> element.symbolReference?.symbolName ?: ""
|
||||
is M68kRegister -> element.text
|
||||
else -> ""
|
||||
|
||||
+1
@@ -20,6 +20,7 @@ class M68kStructureViewElement(private val myElement: NavigatablePsiElement) : S
|
||||
is M68kFile -> {
|
||||
listOf(
|
||||
M68kLookupUtil.findAllSymbolDefinitions(myElement).sortedBy { it.startOffset },
|
||||
M68kLookupUtil.findAllMacroDefinitions(myElement).sortedBy { it.startOffset },
|
||||
M68kLookupUtil.findAllGlobalLabels(myElement).sortedBy { it.startOffset },
|
||||
// M68kLookupUtil.findAllSymbolDefinitions(myElement).sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER) { it.name!! }),
|
||||
// M68kLookupUtil.findAllGlobalLabels(myElement).sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER) { it.name!! })
|
||||
|
||||
+2
-1
@@ -7,6 +7,7 @@ import com.intellij.ide.util.treeView.smartTree.Sorter
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.psi.PsiFile
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kLocalLabel
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kMacroDefinition
|
||||
|
||||
class M68kStructureViewModel(psiFile: PsiFile, editor: Editor?) :
|
||||
StructureViewModelBase(psiFile, editor, M68kStructureViewElement(psiFile)), ElementInfoProvider {
|
||||
@@ -16,7 +17,7 @@ class M68kStructureViewModel(psiFile: PsiFile, editor: Editor?) :
|
||||
}
|
||||
|
||||
override fun isAlwaysLeaf(element: StructureViewTreeElement): Boolean {
|
||||
return element.value is M68kLocalLabel
|
||||
return element.value is M68kLocalLabel || element.value is M68kMacroDefinition
|
||||
}
|
||||
|
||||
override fun getSorters(): Array<Sorter> {
|
||||
|
||||
@@ -8,11 +8,14 @@ import com.intellij.psi.stubs.*
|
||||
import com.intellij.psi.tree.ILightStubFileElementType
|
||||
import de.platon42.intellij.plugins.m68k.MC68000Language.Companion.INSTANCE
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kGlobalLabel
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kMacroDefinition
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kSymbolDefinition
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kTypes
|
||||
import de.platon42.intellij.plugins.m68k.psi.impl.M68kGlobalLabelImpl
|
||||
import de.platon42.intellij.plugins.m68k.psi.impl.M68kMacroDefinitionImpl
|
||||
import de.platon42.intellij.plugins.m68k.psi.impl.M68kSymbolDefinitionImpl
|
||||
import de.platon42.intellij.plugins.m68k.stubs.impl.M68kGlobalLabelStubImpl
|
||||
import de.platon42.intellij.plugins.m68k.stubs.impl.M68kMacroDefinitionStubImpl
|
||||
import de.platon42.intellij.plugins.m68k.stubs.impl.M68kSymbolDefinitionStubImpl
|
||||
import java.io.IOException
|
||||
|
||||
@@ -67,5 +70,28 @@ interface M68kElementTypes {
|
||||
override fun indexStub(stub: M68kSymbolDefinitionStub, sink: IndexSink) = sink.occurrence(M68kSymbolDefinitionStubIndex.KEY, stub.name!!)
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val MACRO_DEFINITION: IStubElementType<M68kMacroDefinitionStub, M68kMacroDefinition> =
|
||||
object : M68kStubElementType<M68kMacroDefinitionStub, M68kMacroDefinition>("MACRO_DEFINITION") {
|
||||
override fun createPsi(stub: M68kMacroDefinitionStub): M68kMacroDefinition = M68kMacroDefinitionImpl(stub, this)
|
||||
|
||||
override fun createStub(psi: M68kMacroDefinition, parentStub: StubElement<out PsiElement>): M68kMacroDefinitionStub =
|
||||
M68kMacroDefinitionStubImpl(parentStub, this, psi.name!!)
|
||||
|
||||
override fun createStub(tree: LighterAST, node: LighterASTNode, parentStub: StubElement<*>): M68kMacroDefinitionStub {
|
||||
val idNode = LightTreeUtil.requiredChildOfType(tree, node, M68kTypes.MACRO_NAME_DEFINITION)
|
||||
return M68kMacroDefinitionStubImpl(parentStub, this, LightTreeUtil.toFilteredString(tree, idNode, null))
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun serialize(stub: M68kMacroDefinitionStub, dataStream: StubOutputStream) = dataStream.writeName(stub.name)
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun deserialize(dataStream: StubInputStream, parentStub: StubElement<*>): M68kMacroDefinitionStub =
|
||||
M68kMacroDefinitionStubImpl(parentStub, this, dataStream.readName()!!)
|
||||
|
||||
override fun indexStub(stub: M68kMacroDefinitionStub, sink: IndexSink) = sink.occurrence(M68kMacroDefinitionStubIndex.KEY, stub.name!!)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package de.platon42.intellij.plugins.m68k.stubs
|
||||
|
||||
import com.intellij.psi.stubs.NamedStub
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kMacroDefinition
|
||||
|
||||
interface M68kMacroDefinitionStub : NamedStub<M68kMacroDefinition>
|
||||
@@ -0,0 +1,16 @@
|
||||
package de.platon42.intellij.plugins.m68k.stubs
|
||||
|
||||
import com.intellij.psi.stubs.StringStubIndexExtension
|
||||
import com.intellij.psi.stubs.StubIndexKey
|
||||
import de.platon42.intellij.plugins.m68k.M68kFileElementType
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kMacroDefinition
|
||||
|
||||
class M68kMacroDefinitionStubIndex : StringStubIndexExtension<M68kMacroDefinition>() {
|
||||
override fun getKey(): StubIndexKey<String, M68kMacroDefinition> = KEY
|
||||
|
||||
override fun getVersion(): Int = M68kFileElementType.STUB_VERSION
|
||||
|
||||
companion object {
|
||||
val KEY = StubIndexKey.createIndexKey<String, M68kMacroDefinition>("mc68000.macrodef.index")
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ object M68kStubElementTypeFactory {
|
||||
return when (name) {
|
||||
"GLOBAL_LABEL" -> M68kElementTypes.GLOBAL_LABEL
|
||||
"SYMBOL_DEFINITION" -> M68kElementTypes.SYMBOL_DEFINITION
|
||||
"MACRO_DEFINITION" -> M68kElementTypes.MACRO_DEFINITION
|
||||
else -> throw RuntimeException("Unknown element type '$name'")
|
||||
}
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package de.platon42.intellij.plugins.m68k.stubs.impl
|
||||
|
||||
import com.intellij.psi.stubs.IStubElementType
|
||||
import com.intellij.psi.stubs.NamedStubBase
|
||||
import com.intellij.psi.stubs.StubElement
|
||||
import com.intellij.util.io.StringRef
|
||||
import de.platon42.intellij.plugins.m68k.psi.M68kMacroDefinition
|
||||
import de.platon42.intellij.plugins.m68k.stubs.M68kMacroDefinitionStub
|
||||
|
||||
class M68kMacroDefinitionStubImpl : NamedStubBase<M68kMacroDefinition>, M68kMacroDefinitionStub {
|
||||
constructor(parent: StubElement<*>, elementType: IStubElementType<*, *>, name: StringRef) : super(parent, elementType, name)
|
||||
constructor(parent: StubElement<*>, elementType: IStubElementType<*, *>, name: String) : super(parent, elementType, name)
|
||||
}
|
||||
@@ -34,7 +34,7 @@ class M68kSyntaxHighlighter(val project: Project?) : SyntaxHighlighterBase() {
|
||||
M68kTypes.MNEMONIC -> arrayOf(MNEMONIC)
|
||||
M68kTypes.MACRO_TAG, M68kTypes.MACRO_END_TAG -> arrayOf(MACRO_PREPROCESSOR)
|
||||
M68kTypes.MACRO_LINE -> arrayOf(MACRO_LINE)
|
||||
M68kTypes.MACRO_INVOKATION -> arrayOf(MACRO_CALL)
|
||||
M68kTypes.MACRO_INVOCATION -> arrayOf(MACRO_CALL)
|
||||
M68kTypes.MACRO_NAME -> arrayOf(MACRO_NAME_DEF)
|
||||
M68kTypes.DATA_DIRECTIVE -> arrayOf(DATA_PREPROCESSOR)
|
||||
M68kTypes.OTHER_DIRECTIVE, M68kTypes.EQU -> arrayOf(OTHER_PREPROCESSOR)
|
||||
|
||||
Reference in New Issue
Block a user