Added structure view.

This commit is contained in:
Chris Hodges 2021-07-20 12:31:38 +02:00
parent 331b88c05f
commit c0e2da6c38
5 changed files with 124 additions and 24 deletions

View File

@ -10,34 +10,53 @@ import de.platon42.intellij.plugins.m68k.M68kFileType
object M68kLookupUtil {
fun findAllGlobalLabels(project: Project): List<M68kGlobalLabel> {
return FileTypeIndex.getFiles(M68kFileType.INSTANCE, GlobalSearchScope.allScope(project)).asSequence()
.map { PsiManager.getInstance(project).findFile(it) as M68kFile }
.flatMap {
val results: MutableList<M68kGlobalLabel> = ArrayList()
var currentStatement = it.firstChild
while (currentStatement != null) {
val child = currentStatement.firstChild
if (child is M68kGlobalLabel) results.add(child)
currentStatement = PsiTreeUtil.getNextSiblingOfType(currentStatement, M68kStatement::class.java)
}
results
}
return getFiles(project)
.flatMap(::findAllGlobalLabels)
.toList()
}
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)
}
return results
}
fun findAllLocalLabels(globalLabel: M68kGlobalLabel): List<M68kLocalLabel> {
val statement = PsiTreeUtil.getStubOrPsiParentOfType(globalLabel, M68kStatement::class.java)!!
val results: MutableList<M68kLocalLabel> = ArrayList()
var currentStatement = PsiTreeUtil.getNextSiblingOfType(statement, M68kStatement::class.java)
while (currentStatement != null) {
val child = currentStatement.firstChild
if (child is M68kGlobalLabel) break
if (child is M68kLocalLabel) results.add(child)
currentStatement = PsiTreeUtil.getNextSiblingOfType(currentStatement, M68kStatement::class.java)
}
return results
}
fun findAllSymbolDefinitions(project: Project): List<M68kSymbolDefinition> {
return FileTypeIndex.getFiles(M68kFileType.INSTANCE, GlobalSearchScope.allScope(project)).asSequence()
.map { PsiManager.getInstance(project).findFile(it) as M68kFile }
.flatMap {
val results: MutableList<M68kSymbolDefinition> = ArrayList()
var currentStatement = it.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)
}
results
}
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)
}
return results
}
private fun getFiles(project: Project) =
FileTypeIndex.getFiles(M68kFileType.INSTANCE, GlobalSearchScope.allScope(project)).asSequence()
.map { PsiManager.getInstance(project).findFile(it) as M68kFile }
}

View File

@ -0,0 +1,40 @@
package de.platon42.intellij.plugins.m68k.structureview
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 de.platon42.intellij.plugins.m68k.psi.M68kFile
import de.platon42.intellij.plugins.m68k.psi.M68kGlobalLabel
import de.platon42.intellij.plugins.m68k.psi.M68kLookupUtil
import de.platon42.intellij.plugins.m68k.psi.M68kLookupUtil.findAllLocalLabels
class M68kStructureViewElement(private val myElement: NavigatablePsiElement) : StructureViewTreeElement {
override fun getValue(): Any = myElement
override fun getPresentation(): ItemPresentation = myElement.presentation!!
override fun getChildren(): Array<TreeElement> {
return when (myElement) {
is M68kFile -> {
listOf(
M68kLookupUtil.findAllSymbolDefinitions(myElement),
M68kLookupUtil.findAllGlobalLabels(myElement)
)
.flatten()
.map(::M68kStructureViewElement)
.toTypedArray()
}
is M68kGlobalLabel -> {
findAllLocalLabels(myElement).map(::M68kStructureViewElement).toTypedArray()
}
else -> emptyArray()
}
}
override fun navigate(requestFocus: Boolean) = myElement.navigate(requestFocus)
override fun canNavigate() = myElement.canNavigate()
override fun canNavigateToSource() = myElement.canNavigateToSource()
}

View File

@ -0,0 +1,15 @@
package de.platon42.intellij.plugins.m68k.structureview
import com.intellij.ide.structureView.StructureViewBuilder
import com.intellij.ide.structureView.StructureViewModel
import com.intellij.ide.structureView.TreeBasedStructureViewBuilder
import com.intellij.lang.PsiStructureViewFactory
import com.intellij.openapi.editor.Editor
import com.intellij.psi.PsiFile
class M68kStructureViewFactory : PsiStructureViewFactory {
override fun getStructureViewBuilder(psiFile: PsiFile): StructureViewBuilder =
object : TreeBasedStructureViewBuilder() {
override fun createStructureViewModel(editor: Editor?): StructureViewModel = M68kStructureViewModel(psiFile, editor)
}
}

View File

@ -0,0 +1,25 @@
package de.platon42.intellij.plugins.m68k.structureview
import com.intellij.ide.structureView.StructureViewModel.ElementInfoProvider
import com.intellij.ide.structureView.StructureViewModelBase
import com.intellij.ide.structureView.StructureViewTreeElement
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
class M68kStructureViewModel(psiFile: PsiFile, editor: Editor?) :
StructureViewModelBase(psiFile, editor, M68kStructureViewElement(psiFile)), ElementInfoProvider {
override fun isAlwaysShowsPlus(element: StructureViewTreeElement): Boolean {
return false
}
override fun isAlwaysLeaf(element: StructureViewTreeElement): Boolean {
return element.value is M68kLocalLabel
}
override fun getSorters(): Array<Sorter> {
return arrayOf(Sorter.ALPHA_SORTER)
}
}

View File

@ -25,6 +25,7 @@
<lang.braceMatcher language="MC68000" implementationClass="de.platon42.intellij.plugins.m68k.syntax.M68kPairedBraceMatcher"/>
<lang.quoteHandler language="MC68000" implementationClass="de.platon42.intellij.plugins.m68k.M68kStringQuoteHandler"/>
<lang.findUsagesProvider language="MC68000" implementationClass="de.platon42.intellij.plugins.m68k.scanner.M68kFindUsagesProvider"/>
<lang.psiStructureViewFactory language="MC68000" implementationClass="de.platon42.intellij.plugins.m68k.structureview.M68kStructureViewFactory"/>
<lang.elementManipulator forClass="de.platon42.intellij.plugins.m68k.psi.M68kSymbolReference"
implementationClass="de.platon42.intellij.plugins.m68k.refs.M68kSymbolReferenceElementManipulator"/>