Skip to content

Commit

Permalink
Fixed type of anonymous table members derived from generic params.
Browse files Browse the repository at this point in the history
Previously the type worked within the scope of the defining
function, but once returned the type failed to resolve and was
essentially unusable. Explicit types (aliases or shapes) were a
workaround, but this commit resolves the problem.

Additionally, we've improved the displayed type for anonymous
tables. Rather than just seeing "table" you know see the members
and their types in both error messages and when hovering over
variables.
  • Loading branch information
Benjamin-Dobell committed Jan 1, 2023
1 parent 30c757d commit fe113c1
Show file tree
Hide file tree
Showing 44 changed files with 459 additions and 215 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.PsiElementVisitor
import com.tang.intellij.lua.lang.LuaFileType
import com.tang.intellij.lua.project.LuaSettings
import com.tang.intellij.lua.psi.*
import com.tang.intellij.lua.psi.LuaCallExpr
import com.tang.intellij.lua.psi.LuaExpression
import com.tang.intellij.lua.psi.LuaIndexExpr
import com.tang.intellij.lua.psi.LuaVisitor
import com.tang.intellij.lua.search.ProjectSearchContext
import com.tang.intellij.lua.search.PsiSearchContext
import com.tang.intellij.lua.search.SearchContext
import com.tang.intellij.lua.ty.*

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ package com.tang.intellij.lua.debugger

import com.intellij.execution.actions.ConfigurationContext
import com.intellij.execution.actions.LazyRunConfigurationProducer
import com.intellij.execution.actions.RunConfigurationProducer
import com.intellij.execution.configurations.ConfigurationFactory
import com.intellij.openapi.externalSystem.service.execution.AbstractExternalSystemTaskConfigurationType
import com.intellij.openapi.util.Ref
import com.intellij.psi.PsiElement
import com.tang.intellij.lua.debugger.app.LuaAppConfigurationType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ import com.intellij.xdebugger.evaluation.XDebuggerEvaluator
import com.intellij.xdebugger.frame.*
import com.intellij.xdebugger.impl.XDebugSessionImpl
import com.tang.intellij.lua.debugger.remote.LuaMobDebugProcess
import org.luaj.vm2.LuaTable
import org.luaj.vm2.LuaValue
import java.util.*

/**
*
Expand Down Expand Up @@ -98,4 +96,4 @@ class LuaRTable(name: String) : LuaRValue(name) {
} else
node.addChildren(list!!, true)
}
}
}
13 changes: 12 additions & 1 deletion src/main/java/com/tang/intellij/lua/documentation/DocRenderer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ fun renderTy(sb: StringBuilder, ty: ITy, tyRenderer: ITyRenderer) {
tyRenderer.render(ty, sb)
}

fun renderSignature(sb: StringBuilder, signature: IFunSignature, tyRenderer: ITyRenderer) {
fun renderSignature(sb: StringBuilder, signature: IFunSignature, tyRenderer: TyRenderer) {
val sig = mutableListOf<String>()
val params = signature.params
val varargTy = signature.variadicParamTy
Expand All @@ -56,8 +56,19 @@ fun renderSignature(sb: StringBuilder, signature: IFunSignature, tyRenderer: ITy
sb.append("(${sig.joinToString(", <br> ")})")
}
signature.returnTy?.let {
val parenthesisRequired = tyRenderer.isReturnPunctuationRequired(it)

sb.append(": ")

if (parenthesisRequired) {
sb.append("(")
}

tyRenderer.render(it, sb)

if (parenthesisRequired) {
sb.append(")")
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ import com.tang.intellij.lua.ty.*
*/
class LuaDocumentationProvider : AbstractDocumentationProvider(), DocumentationProvider {

private val renderer: ITyRenderer = object: TyRenderer() {
override fun renderType(t: String): String {
private val renderer = object: TyRenderer() {
override fun renderTypeName(t: String): String {
return if (t.isNotEmpty()) buildString { DocumentationManagerUtil.createHyperlink(this, t, t, true) } else t
}

Expand Down Expand Up @@ -81,9 +81,15 @@ class LuaDocumentationProvider : AbstractDocumentationProvider(), DocumentationP
is LuaLocalDef -> { //local xx

renderDefinition(sb) {
sb.append("local <b>${element.name}</b>: ")
val ty = element.guessType(SearchContext.get(element.project)) ?: Primitives.UNKNOWN
renderTy(sb, ty, tyRenderer)

sb.append("local <b>${element.name}</b>: ")

if (renderer.isMemberPunctuationRequired(ty)) {
"(${renderTy(sb, ty, tyRenderer)})"
} else {
renderTy(sb, ty, tyRenderer)
}
}

val owner = PsiTreeUtil.getParentOfType(element, LuaCommentOwner::class.java)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package com.tang.intellij.lua.editor.completion
import com.intellij.codeInsight.lookup.LookupElementBuilder
import com.intellij.icons.AllIcons
import com.intellij.psi.codeStyle.NameUtil
import com.intellij.util.Processor
import com.tang.intellij.lua.editor.LuaNameSuggestionProvider
import com.tang.intellij.lua.psi.search.LuaShortNamesManager

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,9 @@ import com.intellij.psi.TokenType
import com.intellij.psi.formatter.common.AbstractBlock
import com.intellij.psi.tree.IElementType
import com.intellij.psi.tree.TokenSet
import com.tang.intellij.lua.editor.formatter.LuaCodeStyleSettings
import com.tang.intellij.lua.editor.formatter.LuaFormatContext
import com.tang.intellij.lua.psi.*
import com.tang.intellij.lua.psi.LuaTypes.*
import java.util.*

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,10 @@
package com.tang.intellij.lua.errorreporting

import com.intellij.AbstractBundle
import com.intellij.CommonBundle
import com.intellij.diagnostic.AbstractMessage
import com.intellij.diagnostic.DiagnosticBundle
import com.intellij.diagnostic.IdeErrorsDialog
import com.intellij.diagnostic.ReportMessages
import com.intellij.ide.DataManager
import com.intellij.ide.plugins.PluginManager
import com.intellij.ide.plugins.PluginManagerCore
import com.intellij.idea.IdeaLogger
import com.intellij.notification.NotificationGroupManager
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package com.tang.intellij.lua.folding

import com.intellij.lang.ASTNode
import com.intellij.lang.customFolding.VisualStudioCustomFoldingProvider
import com.intellij.lang.folding.CompositeFoldingBuilder
import com.intellij.lang.folding.FoldingBuilderEx
import com.intellij.lang.folding.FoldingDescriptor
import com.intellij.openapi.editor.Document
Expand Down Expand Up @@ -130,4 +129,4 @@ class LuaRegionFoldingBuilder : FoldingBuilderEx() {
else
customFoldingBuilder.buildFoldRegions(element, document, quick)
}
}
}
1 change: 0 additions & 1 deletion src/main/java/com/tang/intellij/lua/psi/ExpressionUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package com.tang.intellij.lua.psi
import com.intellij.psi.tree.IElementType
import com.tang.intellij.lua.search.SearchContext
import com.tang.intellij.lua.ty.Primitives
import com.tang.intellij.lua.ty.Ty

data class ComputeResult(val kind: ComputeKind,
var bValue: Boolean = false,
Expand Down
1 change: 0 additions & 1 deletion src/main/java/com/tang/intellij/lua/psi/LuaFileManager.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package com.tang.intellij.lua.psi

import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.ex.ApplicationManagerEx
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.fileTypes.FileTypeEvent
import com.intellij.openapi.fileTypes.FileTypeListener
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/com/tang/intellij/lua/psi/LuaScopedTypeTree.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import com.intellij.openapi.util.Key
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.util.PsiTreeUtil
import com.tang.intellij.lua.Constants
import com.tang.intellij.lua.comment.LuaCommentUtil
import com.tang.intellij.lua.comment.psi.*
import com.tang.intellij.lua.comment.psi.api.LuaComment
Expand All @@ -31,6 +30,7 @@ import java.util.*
open class FoundLuaScope(open val scope: LuaScopedTypeTreeScope, val psiScopedTypeIndex: Int? = null)

interface LuaScopedTypeTreeScope {
val name: String
val psi: PsiElement
val tree: LuaScopedTypeTree
val parent: LuaScopedTypeTreeScope?
Expand Down Expand Up @@ -78,6 +78,8 @@ interface LuaScopedTypeTree {
}

private class ScopedTypeTreeScope(override val psi: LuaTypeScope, override val tree: ScopedTypeTree, override val parent: ScopedTypeTreeScope?): LuaScopedTypeTreeScope {
override val name = psi.containingFile.getFileIdentifier() + "@" + psi.node.startOffset

private val types = ArrayList<LuaScopedType>(0)
private val childScopes = LinkedList<ScopedTypeTreeScope>()

Expand Down Expand Up @@ -427,6 +429,8 @@ private class ScopedTypeStubTree(file: LuaPsiFile) : ScopedTypeTree(file) {
}

class ScopedTypeSubstitutor(context: SearchContext, val scope: LuaScopedTypeTreeScope) : TySubstitutor() {
override val name = "scoped:" + scope.name

override fun substitute(context: SearchContext, clazz: ITyClass): ITy {
return (clazz as? TyGenericParameter)?.let { genericParam ->
val scopedTy = scope.findName(context, genericParam.varName)?.type as? TyGenericParameter
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/tang/intellij/lua/psi/PsiExtension.kt
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ private fun LuaExpression<*>.shouldBeInternal(context: SearchContext): ITy? {

fun LuaExpression<*>.shouldBe(context: SearchContext): ITy? {
return shouldBeInternal(context)?.let {
TyAliasSubstitutor().substitute(context, it)
TyAliasSubstitutor.substitute(context, it)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import com.intellij.util.Processor
import com.intellij.util.Query
import com.intellij.util.QueryExecutor
import com.tang.intellij.lua.comment.psi.LuaDocTagClass
import com.tang.intellij.lua.ty.ITyClass

/**
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,7 @@ class ProjectSearchContext : SearchContext {

override val element: PsiElement? = null

override val identifier: String = "project"

override fun getProjectContext() = this
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,17 @@ package com.tang.intellij.lua.search

import com.intellij.openapi.project.Project
import com.intellij.psi.PsiElement
import com.tang.intellij.lua.psi.getFileIdentifier


class PsiSearchContext(override val element: PsiElement) : SearchContext() {
override val project: Project by lazy {
element.project
}

override val identifier: String
get() {
val id = element.containingFile.getFileIdentifier()
return "$id@(${element.node.startOffset})"
}
}
18 changes: 6 additions & 12 deletions src/main/java/com/tang/intellij/lua/search/SearchContext.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,9 @@ import com.intellij.psi.PsiElement
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.ProjectAndLibrariesScope
import com.tang.intellij.lua.ext.ILuaTypeInfer
import com.tang.intellij.lua.psi.LuaIndexExpr
import com.tang.intellij.lua.psi.LuaPsiTypeGuessable
import com.tang.intellij.lua.psi.ScopedTypeSubstitutor
import com.tang.intellij.lua.ty.ITy
import com.tang.intellij.lua.ty.ITyClass
import com.tang.intellij.lua.ty.isAnonymous
import com.tang.intellij.lua.ty.isSelfClass
import java.util.*

/**
Expand All @@ -38,6 +34,7 @@ import java.util.*
abstract class SearchContext() {
abstract val project: Project
abstract val element: PsiElement?
abstract val identifier: String

open fun getProjectContext(): ProjectSearchContext {
return ProjectSearchContext(this)
Expand All @@ -46,7 +43,7 @@ abstract class SearchContext() {
val index: Int get() = myIndex // Multiple results index
val supportsMultipleResults: Boolean get() = myMultipleResults

private var myDumb = false
private var myDumb = contextStack.get().lastOrNull()?.isDumb ?: false
private var myIndex = 0
private var myMultipleResults = false
private var myInStack = false
Expand Down Expand Up @@ -127,14 +124,11 @@ abstract class SearchContext() {
}

companion object {
private val threadLocal = object : ThreadLocal<Stack<SearchContext>>() {
override fun initialValue(): Stack<SearchContext> {
return Stack()
}
}
private val contextStack = ThreadLocal.withInitial { Stack<SearchContext>() }

fun get(project: Project): SearchContext {
val stack = threadLocal.get()
val stack = contextStack.get()

return if (stack.isEmpty()) {
ProjectSearchContext(project)
} else {
Expand All @@ -159,7 +153,7 @@ abstract class SearchContext() {
val result = action(ctx)
result
} else {
val stack = threadLocal.get()
val stack = contextStack.get()
val size = stack.size
stack.push(ctx)
ctx.myInStack = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import com.tang.intellij.lua.stubs.index.LuaClassMemberIndex
import com.tang.intellij.lua.stubs.index.StubKeys
import com.tang.intellij.lua.ty.ITy
import com.tang.intellij.lua.ty.Primitives
import com.tang.intellij.lua.ty.Ty
import com.tang.intellij.lua.ty.getDocTableTypeName

class LuaDocTableFieldType : LuaStubElementType<LuaDocTableFieldStub, LuaDocTableField>("DOC_TABLE_FIELD_DEF") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,15 @@

package com.tang.intellij.lua.stubs

import com.intellij.lang.ASTNode
import com.intellij.psi.stubs.IndexSink
import com.intellij.psi.stubs.StubElement
import com.intellij.psi.stubs.StubInputStream
import com.intellij.psi.stubs.StubOutputStream
import com.intellij.util.io.StringRef
import com.tang.intellij.lua.comment.psi.LuaDocTagAlias
import com.tang.intellij.lua.comment.psi.LuaDocTagClass
import com.tang.intellij.lua.comment.psi.impl.LuaDocTagAliasImpl
import com.tang.intellij.lua.psi.LuaElementType
import com.tang.intellij.lua.stubs.index.StubKeys
import com.tang.intellij.lua.ty.ITy
import com.tang.intellij.lua.ty.Ty
import com.tang.intellij.lua.ty.TyAlias

Expand Down
1 change: 0 additions & 1 deletion src/main/java/com/tang/intellij/lua/stubs/LuaFileStub.kt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import com.intellij.psi.StubBuilder
import com.intellij.psi.stubs.*
import com.intellij.psi.tree.IStubFileElementType
import com.intellij.util.io.StringRef
import com.tang.intellij.lua.Constants
import com.tang.intellij.lua.lang.LuaLanguage
import com.tang.intellij.lua.lang.LuaParserDefinition
import com.tang.intellij.lua.psi.LuaPsiFile
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@ import com.intellij.psi.stubs.*
import com.tang.intellij.lua.psi.LuaReturnStat
import com.tang.intellij.lua.psi.LuaTypes
import com.tang.intellij.lua.psi.impl.LuaReturnStatImpl
import com.tang.intellij.lua.stubs.LuaDocTyStub
import com.tang.intellij.lua.stubs.LuaStubElementType
import com.tang.intellij.lua.stubs.readTyNullable
import com.tang.intellij.lua.stubs.writeTyNullable
import com.tang.intellij.lua.ty.ITy

class LuaReturnStatType : LuaStubElementType<LuaReturnStatStub, LuaReturnStat>("Return Statement") {
Expand Down
5 changes: 2 additions & 3 deletions src/main/java/com/tang/intellij/lua/stubs/LuaTableExprStub.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@ import com.intellij.psi.stubs.IndexSink
import com.intellij.psi.stubs.StubElement
import com.intellij.psi.stubs.StubInputStream
import com.intellij.psi.stubs.StubOutputStream
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.util.io.StringRef
import com.tang.intellij.lua.psi.*
import com.tang.intellij.lua.psi.LuaTableExpr
import com.tang.intellij.lua.psi.impl.LuaTableExprImpl
import com.tang.intellij.lua.ty.getGlobalTypeName
import com.tang.intellij.lua.psi.shouldCreateStub
import com.tang.intellij.lua.ty.getTableTypeName

/**
Expand Down
Loading

0 comments on commit fe113c1

Please sign in to comment.