Changed LookupUtil to use stub indexes instead of iterating over global labels and symbol definitions. Added basic test for Structure View.
This commit is contained in:
parent
89ecaeb613
commit
3165d99fc2
14
README.md
14
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.
|
@ -46,6 +46,12 @@ intellij {
|
||||
|
||||
patchPluginXml {
|
||||
setChangeNotes("""
|
||||
<h4>V0.2 (xx-Jul-21)</h4>
|
||||
<ul>
|
||||
<li>Added (same) icon for plugin as for file type.
|
||||
<li>Performance improvement: Use Word-Index for global labels and symbols instead of iterating over the file.
|
||||
<li>Performance improvement: Use Stub-Index for global labels and symbols.
|
||||
</ul>
|
||||
<h4>V0.1 (20-Jul-21)</h4>
|
||||
<ul>
|
||||
<li>Initial public release.
|
||||
|
@ -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<M68kGlobalLabel> {
|
||||
return getFiles(project)
|
||||
.flatMap(::findAllGlobalLabels)
|
||||
.toList()
|
||||
val results: MutableList<M68kGlobalLabel> = 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<M68kGlobalLabel> {
|
||||
val results: MutableList<M68kGlobalLabel> = 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<M68kSymbolDefinition> {
|
||||
return getFiles(project)
|
||||
.flatMap(::findAllSymbolDefinitions)
|
||||
.toList()
|
||||
}
|
||||
|
||||
fun findAllSymbolDefinitions(file: M68kFile): List<M68kSymbolDefinition> {
|
||||
val results: MutableList<M68kSymbolDefinition> = 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<M68kSymbolDefinition> {
|
||||
val results: MutableList<M68kSymbolDefinition> = 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
|
||||
}
|
||||
}
|
@ -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)
|
||||
|
@ -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
|
||||
"""
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
25
src/test/resources/structureview/basic_example.asm
Normal file
25
src/test/resources/structureview/basic_example.asm
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user