Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix decompilation of Kernel that causes syntax highlighting crashes #1877

Merged
merged 8 commits into from
Jan 15, 2021
Prev Previous commit
Next Next commit
Connect compiled stubs to decompiled source by name/arity
Previously, when the decompiler didn't use the Docs chunk, it was guaranteed that the PsiCompiled stubs would correlate, in-order, with the decompiled source call definitions, and so mirrors could be set by matching up the list of them in order.  Since the Docs doesn't have to correspond to and doesn't correspond to the binary precisely for some BEAMs, most importantly, `Elixir.Kernel.beam`, the PsiCompiled stub and decompiled source is now matched by name and arity.   This means some mirrors are missed, but no errors are produced.
  • Loading branch information
KronicDeth committed Jan 15, 2021
commit a03c8a80c38d70a7c4f9d1d2b402505c206d756e
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# https://www.jetbrains.com/intellij-repository/releases
# https://www.jetbrains.com/intellij-repository/snapshots

baseVersion = 11.9.0
baseVersion = 11.9.1
ideaVersion = 2020.2.2
javaVersion = 1.9
javaTargetVersion = 1.9
Expand Down
27 changes: 20 additions & 7 deletions src/org/elixir_lang/beam/psi/impl/ModuleImpl.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import org.elixir_lang.psi.call.MaybeExported
import org.elixir_lang.beam.psi.stubs.ModuleStubElementTypes
import com.intellij.util.IncorrectOperationException
import com.intellij.psi.ResolveState
import com.intellij.psi.impl.source.SourceTreeToPsiMap
import com.intellij.psi.impl.source.tree.TreeElement
import com.intellij.util.ArrayFactory
import org.elixir_lang.beam.psi.Module
import org.elixir_lang.psi.call.Call
import org.jetbrains.annotations.Contract
Expand Down Expand Up @@ -46,7 +46,14 @@ class ModuleImpl<T : StubElement<*>?>(private val stub: T) : ModuleElementImpl()

override fun setMirror(element: TreeElement) {
setMirrorCheckingType(element, null)
setMirrors(callDefinitions(), callDefinitions(element))

val callDefinitionByArityByName = callDefinitionByArityByName(element)

for (callDefinitionStub in callDefinitions()) {
callDefinitionByArityByName[callDefinitionStub.exportedName()]
?.get(callDefinitionStub.exportedArity())
?.let { (callDefinitionStub as ModuleElementImpl).setMirror(SourceTreeToPsiMap.psiToTreeNotNull(it)) }
}
}

private fun callDefinitions(): Array<MaybeExported> =
Expand Down Expand Up @@ -87,24 +94,30 @@ class ModuleImpl<T : StubElement<*>?>(private val stub: T) : ModuleElementImpl()

companion object {
@Contract(pure = true)
private fun callDefinitions(mirror: TreeElement): Array<MaybeExported> {
private fun callDefinitionByArityByName(mirror: TreeElement): Map<String, Map<Int, MaybeExported>> {
val mirrorPsi = mirror.psi

return if (mirrorPsi is Call) {
val callDefinitionList: MutableList<MaybeExported> = ArrayList()
val initialResolveState = ResolveState.initial().putInitialVisitedElement(mirrorPsi)
val callDefinitionByArityByName = mutableMapOf<String, MutableMap<Int, MaybeExported>>()

callDefinitionClauseCallWhile(mirrorPsi, initialResolveState) { call: Call?, accResolvedState: ResolveState? ->
if (call is MaybeExported) {
val maybeExportedCall = call as MaybeExported
callDefinitionList.add(maybeExportedCall)

maybeExportedCall
.exportedName()
?.let { exportedName ->
callDefinitionByArityByName
.getOrPut(exportedName) { mutableMapOf() }[maybeExportedCall.exportedArity()] = maybeExportedCall
}
}
true
}

callDefinitionList.toTypedArray()
callDefinitionByArityByName
} else {
emptyArray()
emptyMap()
}
}
}
Expand Down