diff --git a/README.md b/README.md
index 2120f90..b1574cd 100644
--- a/README.md
+++ b/README.md
@@ -36,7 +36,6 @@ it's "good enough" to get started, and I can return to demo coding with its curr
## Known issues
-- Performance is not optimal yet (no stub index).
- No referencing of macro invocations and macro definitions.
- `Find Usages` always shows _"Unclassified"_ though it shouldn't.
- Macro definitions may cause syntax errors when using backslash arguments.
@@ -55,9 +54,14 @@ it's "good enough" to get started, and I can return to demo coding with its curr
- Formatter + Code Style Settings
- Register use analysis (but this only makes sense after macro evaluation)
+## Recommendations
+
+Currently, I would suggest using the fabulous [Browse Word at Caret Plugin](https://plugins.jetbrains.com/plugin/201-browsewordatcaret)
+to highlight the same address and data registers while editing (see new `View -> Highlight Word at Caret` menu item).
+
## Development notice
-This plugin has been written in Kotlin 1.5.
+This plugin has been written in Kotlin 1.5 using Grammar-Kit.
It is probably the only plugin (besides [Cajon](https://github.com/chrisly42/cajon-plugin) from the same author) that uses JUnit 5 Jupiter for unit testing so
far (or at least the only one I'm aware of ;) ). The IntelliJ framework actually uses the JUnit 3 TestCase for plugin testing, and it took me quite a while to
@@ -65,6 +69,12 @@ make it work with JUnit 5. Feel free to use the code (in package ```de.platon42.
## Changelog
+### V0.2 (unreleased)
+
+- Added (same) icon for plugin as for file type.
+- Performance improvement: Use Word-Index for global labels and symbols instead of iterating over the file.
+- Performance improvement: Use Stub-Index for global labels and symbols.
+
### V0.1 (20-Jul-21)
- Initial public release.
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index 658fe0d..43c6367 100644
--- a/build.gradle
+++ b/build.gradle
@@ -46,6 +46,12 @@ intellij {
patchPluginXml {
setChangeNotes("""
+
V0.2 (xx-Jul-21)
+
+ - Added (same) icon for plugin as for file type.
+
- Performance improvement: Use Word-Index for global labels and symbols instead of iterating over the file.
+
- Performance improvement: Use Stub-Index for global labels and symbols.
+
V0.1 (20-Jul-21)
- Initial public release.
diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/psi/M68kLookupUtil.kt b/src/main/java/de/platon42/intellij/plugins/m68k/psi/M68kLookupUtil.kt
index 0d9a827..fab0724 100644
--- a/src/main/java/de/platon42/intellij/plugins/m68k/psi/M68kLookupUtil.kt
+++ b/src/main/java/de/platon42/intellij/plugins/m68k/psi/M68kLookupUtil.kt
@@ -1,28 +1,41 @@
package de.platon42.intellij.plugins.m68k.psi
import com.intellij.openapi.project.Project
-import com.intellij.psi.PsiManager
-import com.intellij.psi.search.FileTypeIndex
import com.intellij.psi.search.GlobalSearchScope
+import com.intellij.psi.stubs.StubIndex
import com.intellij.psi.util.PsiTreeUtil
-import de.platon42.intellij.plugins.m68k.M68kFileType
+import de.platon42.intellij.plugins.m68k.stubs.M68kGlobalLabelStubIndex
+import de.platon42.intellij.plugins.m68k.stubs.M68kSymbolDefinitionStubIndex
object M68kLookupUtil {
fun findAllGlobalLabels(project: Project): List {
- return getFiles(project)
- .flatMap(::findAllGlobalLabels)
- .toList()
+ val results: MutableList = ArrayList()
+ StubIndex.getInstance().processAllKeys(M68kGlobalLabelStubIndex.KEY, project)
+ {
+ results.addAll(StubIndex.getElements(M68kGlobalLabelStubIndex.KEY, it, project, GlobalSearchScope.allScope(project), M68kGlobalLabel::class.java))
+ true
+ }
+ return results
}
fun findAllGlobalLabels(file: M68kFile): List {
val results: MutableList = ArrayList()
- var currentStatement = file.firstChild
- while (currentStatement != null) {
- val child = currentStatement.firstChild
- if (child is M68kGlobalLabel) results.add(child)
- currentStatement = PsiTreeUtil.getNextSiblingOfType(currentStatement, M68kStatement::class.java)
- }
+ StubIndex.getInstance().processAllKeys(
+ M68kGlobalLabelStubIndex.KEY,
+ {
+ results.addAll(
+ StubIndex.getElements(
+ M68kGlobalLabelStubIndex.KEY,
+ it,
+ file.project,
+ GlobalSearchScope.fileScope(file),
+ M68kGlobalLabel::class.java
+ )
+ )
+ true
+ }, GlobalSearchScope.fileScope(file), null
+ )
return results
}
@@ -40,23 +53,40 @@ object M68kLookupUtil {
}
fun findAllSymbolDefinitions(project: Project): List {
- return getFiles(project)
- .flatMap(::findAllSymbolDefinitions)
- .toList()
- }
-
- fun findAllSymbolDefinitions(file: M68kFile): List {
val results: MutableList = ArrayList()
- var currentStatement = file.firstChild
- while (currentStatement != null) {
- val child = currentStatement.firstChild
- if (child is M68kAssignment) results.add(child.firstChild as M68kSymbolDefinition)
- currentStatement = PsiTreeUtil.getNextSiblingOfType(currentStatement, M68kStatement::class.java)
+ StubIndex.getInstance().processAllKeys(M68kSymbolDefinitionStubIndex.KEY, project)
+ {
+ results.addAll(
+ StubIndex.getElements(
+ M68kSymbolDefinitionStubIndex.KEY,
+ it,
+ project,
+ GlobalSearchScope.allScope(project),
+ M68kSymbolDefinition::class.java
+ )
+ )
+ true
}
return results
}
- private fun getFiles(project: Project) =
- FileTypeIndex.getFiles(M68kFileType.INSTANCE, GlobalSearchScope.allScope(project)).asSequence()
- .map { PsiManager.getInstance(project).findFile(it) as M68kFile }
+ fun findAllSymbolDefinitions(file: M68kFile): List {
+ val results: MutableList = ArrayList()
+ StubIndex.getInstance().processAllKeys(
+ M68kSymbolDefinitionStubIndex.KEY,
+ {
+ results.addAll(
+ StubIndex.getElements(
+ M68kSymbolDefinitionStubIndex.KEY,
+ it,
+ file.project,
+ GlobalSearchScope.fileScope(file),
+ M68kSymbolDefinition::class.java
+ )
+ )
+ true
+ }, GlobalSearchScope.fileScope(file), null
+ )
+ return results
+ }
}
\ No newline at end of file
diff --git a/src/main/java/de/platon42/intellij/plugins/m68k/structureview/M68kStructureViewElement.kt b/src/main/java/de/platon42/intellij/plugins/m68k/structureview/M68kStructureViewElement.kt
index a93ca86..d87ef2a 100644
--- a/src/main/java/de/platon42/intellij/plugins/m68k/structureview/M68kStructureViewElement.kt
+++ b/src/main/java/de/platon42/intellij/plugins/m68k/structureview/M68kStructureViewElement.kt
@@ -4,6 +4,7 @@ import com.intellij.ide.structureView.StructureViewTreeElement
import com.intellij.ide.util.treeView.smartTree.TreeElement
import com.intellij.navigation.ItemPresentation
import com.intellij.psi.NavigatablePsiElement
+import com.intellij.refactoring.suggested.startOffset
import de.platon42.intellij.plugins.m68k.psi.M68kFile
import de.platon42.intellij.plugins.m68k.psi.M68kGlobalLabel
import de.platon42.intellij.plugins.m68k.psi.M68kLookupUtil
@@ -18,8 +19,10 @@ class M68kStructureViewElement(private val myElement: NavigatablePsiElement) : S
return when (myElement) {
is M68kFile -> {
listOf(
- M68kLookupUtil.findAllSymbolDefinitions(myElement),
- M68kLookupUtil.findAllGlobalLabels(myElement)
+ M68kLookupUtil.findAllSymbolDefinitions(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!! })
)
.flatten()
.map(::M68kStructureViewElement)
diff --git a/src/test/java/de/platon42/intellij/plugins/m68k/structureview/M68kStructureViewTest.kt b/src/test/java/de/platon42/intellij/plugins/m68k/structureview/M68kStructureViewTest.kt
new file mode 100644
index 0000000..98f65af
--- /dev/null
+++ b/src/test/java/de/platon42/intellij/plugins/m68k/structureview/M68kStructureViewTest.kt
@@ -0,0 +1,37 @@
+package de.platon42.intellij.plugins.m68k.structureview
+
+import com.intellij.testFramework.PlatformTestUtil
+import com.intellij.testFramework.fixtures.CodeInsightTestFixture
+import de.platon42.intellij.jupiter.LightCodeInsightExtension
+import de.platon42.intellij.jupiter.MyFixture
+import de.platon42.intellij.jupiter.TestDataPath
+import de.platon42.intellij.plugins.m68k.AbstractM68kTest
+import org.junit.jupiter.api.Test
+import org.junit.jupiter.api.extension.ExtendWith
+
+@TestDataPath("src/test/resources/structureview")
+@ExtendWith(LightCodeInsightExtension::class)
+internal class M68kStructureViewTest : AbstractM68kTest() {
+
+ @Test
+ internal fun do_basic_verification_of_resulting_structure_view(@MyFixture myFixture: CodeInsightTestFixture) {
+ myFixture.configureByFile("basic_example.asm")
+ myFixture.testStructureView {
+ val tree = it.tree
+ PlatformTestUtil.waitWhileBusy(tree)
+ PlatformTestUtil.assertTreeEqual(
+ tree, """-basic_example.asm
+ PIC_WIDTH
+ PIC_HEIGHT
+ DEBUG_LEVEL
+ entry
+ -init
+ .looph
+ .loopw
+ main
+ exit
+"""
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/test/resources/structureview/basic_example.asm b/src/test/resources/structureview/basic_example.asm
new file mode 100644
index 0000000..a7e9edd
--- /dev/null
+++ b/src/test/resources/structureview/basic_example.asm
@@ -0,0 +1,25 @@
+PIC_WIDTH = 320
+PIC_HEIGHT equ 256
+DEBUG_LEVEL set 10
+
+entry:
+ bsr init
+ bsr main
+ bsr exit
+ rts
+
+init
+ move.w #PIC_HEIGHT,d1
+.looph move.w #PIC_WIDTH,d0
+.loopw clr.b (a0)+
+ subq.w #1,d0
+ bne.s .loopw
+ subq.w #1,d1
+ bne.s .looph
+ rts
+
+main moveq.l #0,d0
+ rts
+
+exit illegal
+ rts
\ No newline at end of file