Uast: fix for creating an UClass for invalid object-literals (EA-122644, KT-20056)

This commit is contained in:
Nicolay Mitropolsky
2018-06-27 16:37:53 +03:00
parent 25e6b76238
commit 698096f13e
8 changed files with 88 additions and 36 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.uast.kotlin
import com.intellij.psi.*
import com.intellij.psi.impl.light.LightPsiClassBuilder
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.KtLightClassForScript
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
@@ -284,6 +285,37 @@ class KotlinScriptUClass(
}
}
/**
* implementation of [UClass] for invalid code, when it is impossible to create a [KtLightClass]
*/
class KotlinInvalidUClass(
override val psi: PsiClass,
givenParent: UElement?
) : AbstractKotlinUClass(givenParent), PsiClass by psi {
constructor(name: String, context: PsiElement, givenParent: UElement?) : this(LightPsiClassBuilder(context, name), givenParent)
override fun getContainingFile(): PsiFile? = uastParent?.getContainingUFile()?.sourcePsi as? PsiFile
override val sourcePsi: PsiElement? get() = null
override val uastAnchor: UIdentifier? get() = null
override val javaPsi: PsiClass get() = psi
override fun getFields(): Array<UField> = emptyArray()
override fun getInitializers(): Array<UClassInitializer> = emptyArray()
override fun getInnerClasses(): Array<UClass> = emptyArray()
override fun getMethods(): Array<UMethod> = emptyArray()
override fun getSuperClass(): UClass? = null
override fun getOriginalElement(): PsiElement? = null
}
private fun reportConvertFailure(psiMethod: PsiMethod): Nothing {
val isValid = psiMethod.isValid
val report = KotlinExceptionWithAttachments(
@@ -17,6 +17,7 @@
package org.jetbrains.uast.kotlin
import com.intellij.psi.*
import com.intellij.psi.impl.light.LightPsiClassBuilder
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.KtLightClassForScript
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
@@ -274,6 +275,38 @@ class KotlinScriptUClass(
}
}
/**
* implementation of [UClass] for invalid code, when it is impossible to create a [KtLightClass]
*/
class KotlinInvalidUClass(
override val psi: PsiClass,
givenParent: UElement?
) : AbstractKotlinUClass(givenParent), PsiClass by psi {
constructor(name: String, context: PsiElement, givenParent: UElement?) : this(LightPsiClassBuilder(context, name), givenParent)
override fun getContainingFile(): PsiFile? =
(uastParent?.getContainingUFile() as? JvmDeclarationUElementPlaceholder)?.sourcePsi as? PsiFile
override val sourcePsi: PsiElement? get() = null
override val uastAnchor: UIdentifier? get() = null
override val javaPsi: PsiClass get() = psi
override fun getFields(): Array<UField> = emptyArray()
override fun getInitializers(): Array<UClassInitializer> = emptyArray()
override fun getInnerClasses(): Array<UClass> = emptyArray()
override fun getMethods(): Array<UMethod> = emptyArray()
override fun getSuperClass(): UClass? = null
override fun getOriginalElement(): PsiElement? = null
}
private fun reportConvertFailure(psiMethod: PsiMethod): Nothing {
val isValid = psiMethod.isValid
val report = KotlinExceptionWithAttachments(
@@ -16,12 +16,8 @@
package org.jetbrains.uast.kotlin
import com.intellij.openapi.diagnostic.Attachment
import com.intellij.openapi.diagnostic.Logger
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiType
import com.intellij.psi.impl.light.LightPsiClassBuilder
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.psi.KtObjectLiteralExpression
import org.jetbrains.kotlin.psi.KtSuperTypeCallEntry
@@ -34,17 +30,9 @@ class KotlinUObjectLiteralExpression(
) : KotlinAbstractUExpression(givenParent), UObjectLiteralExpression, UCallExpressionEx, KotlinUElementWithType {
override val declaration: UClass by lz {
val lightClass: KtLightClass? = psi.objectDeclaration.toLightClass()
if (lightClass != null) {
getLanguagePlugin().convert<UClass>(lightClass, this)
} else {
logger.error(
"Failed to create light class for object declaration",
Attachment(psi.containingFile.virtualFile?.path ?: "<no path>", psi.containingFile.text)
)
getLanguagePlugin().convert(LightPsiClassBuilder(psi, "<unnamed>"), this)
}
psi.objectDeclaration.toLightClass()
?.let { getLanguagePlugin().convert<UClass>(it, this) }
?: KotlinInvalidUClass("<invalid object code>", psi, this)
}
override fun getExpressionType() = psi.objectDeclaration.toPsiType()
@@ -96,7 +84,4 @@ class KotlinUObjectLiteralExpression(
get() = psi.name ?: "<error>"
}
companion object {
val logger by lz { Logger.getInstance(KotlinUObjectLiteralExpression::class.java) }
}
}
@@ -16,12 +16,8 @@
package org.jetbrains.uast.kotlin
import com.intellij.openapi.diagnostic.Attachment
import com.intellij.openapi.diagnostic.Logger
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiType
import com.intellij.psi.impl.light.LightPsiClassBuilder
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.psi.KtObjectLiteralExpression
import org.jetbrains.kotlin.psi.KtSuperTypeCallEntry
@@ -32,17 +28,9 @@ class KotlinUObjectLiteralExpression(
givenParent: UElement?
) : KotlinAbstractUExpression(givenParent), UObjectLiteralExpression, KotlinUElementWithType {
override val declaration: UClass by lz {
val lightClass: KtLightClass? = psi.objectDeclaration.toLightClass()
if (lightClass != null) {
getLanguagePlugin().convert<UClass>(lightClass, this)
} else {
logger.error(
"Failed to create light class for object declaration",
Attachment(psi.containingFile.virtualFile?.path ?: "<no path>", psi.containingFile.text)
)
getLanguagePlugin().convert(LightPsiClassBuilder(psi, "<unnamed>"), this)
}
psi.objectDeclaration.toLightClass()
?.let { getLanguagePlugin().convert<UClass>(it, this) }
?: KotlinInvalidUClass("<invalid object code>", psi, this)
}
override fun getExpressionType() = psi.objectDeclaration.toPsiType()
@@ -91,7 +79,4 @@ class KotlinUObjectLiteralExpression(
get() = psi.name ?: "<error>"
}
companion object {
val logger by lz { Logger.getInstance(KotlinUObjectLiteralExpression::class.java) }
}
}
@@ -29,3 +29,7 @@ foo -> UAnnotationMethod (name = foo)
read -> UAnnotationMethod (name = read)
Int -> USimpleNameReferenceExpression (identifier = Int)
run -> UAnnotationMethod (name = run)
withErr -> UAnnotationMethod (name = withErr)
runnable -> ULocalVariable (name = runnable)
object -> UastEmptyExpression
Runnable -> null
+4
View File
@@ -9,4 +9,8 @@ fun foo() {
runnable2.run()
val closeableRunnable = object : Runnable, Closeable { override fun close() {} override fun run() {} }
val runnableIs = object : InputStream(), Runnable { override fun read(): Int = 0; override fun run() {} }
}
fun withErr() {
val runnable = object Runnable {} // EA-122644
}
+6
View File
@@ -51,3 +51,9 @@ UFile (package = )
UAnnotationMethod (name = run)
UBlockExpression
UAnnotationMethod (name = AnonymousKt$foo$runnableIs$1)
UAnnotationMethod (name = withErr)
UBlockExpression
UDeclarationsExpression
ULocalVariable (name = runnable)
UObjectLiteralExpression
UClass (name = <invalid object code>)
+3
View File
@@ -12,4 +12,7 @@ public final class AnonymousKt {
var closeableRunnable: <ErrorType> = anonymous object : Runnable, Closeable { override fun close() {} override fun run() {} }
var runnableIs: <ErrorType> = anonymous object : InputStream(), Runnable { override fun read(): Int = 0; override fun run() {} }
}
public static final fun withErr() : void {
var runnable: <ErrorType> = anonymous null
}
}