Skip to content

Commit 327a866

Browse files
fwcdAlexandrosAlexiouowl-from-hogvarts
committed
Return null context if expression fails to compile
This prevents compilation failures from propagating as exceptions. Picked from kotlin-community-tools/kotlin-language-server@eadceb7 Co-authored-by: Alexandros Alexiou <[email protected]> Co-authored-by: owl-from-hogvarts <[email protected]>
1 parent 13fe93f commit 327a866

File tree

4 files changed

+16
-10
lines changed

4 files changed

+16
-10
lines changed

server/src/main/kotlin/org/javacs/kt/CompiledFile.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ class CompiledFile(
4545
}
4646

4747
fun typeOfExpression(expression: KtExpression, scopeWithImports: LexicalScope): KotlinType? =
48-
bindingContextOf(expression, scopeWithImports).getType(expression)
48+
bindingContextOf(expression, scopeWithImports)?.getType(expression)
4949

50-
fun bindingContextOf(expression: KtExpression, scopeWithImports: LexicalScope): BindingContext =
51-
classPath.compiler.compileKtExpression(expression, scopeWithImports, sourcePath, kind).first
50+
fun bindingContextOf(expression: KtExpression, scopeWithImports: LexicalScope): BindingContext? =
51+
classPath.compiler.compileKtExpression(expression, scopeWithImports, sourcePath, kind)?.first
5252

5353
private fun expandForType(cursor: Int, surroundingExpr: KtExpression): KtExpression {
5454
val dotParent = surroundingExpr.parent as? KtDotQualifiedExpression
@@ -73,7 +73,7 @@ class CompiledFile(
7373
val scope = scopeAtPoint(cursor) ?: return nullResult("Couldn't find scope at ${describePosition(cursor)}")
7474
// NOTE: Due to our tiny-fake-file mechanism, we may have `path == /dummy.virtual.kt != parse.containingFile.toPath`
7575
val path = surroundingExpr.containingFile.toPath()
76-
val context = bindingContextOf(surroundingExpr, scope)
76+
val context = bindingContextOf(surroundingExpr, scope) ?: return null
7777
LOG.info("Hovering {}", surroundingExpr)
7878
return referenceFromContext(cursor, path, context)
7979
}

server/src/main/kotlin/org/javacs/kt/compiler/Compiler.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -553,7 +553,7 @@ class Compiler(
553553
}
554554
}
555555

556-
fun compileKtExpression(expression: KtExpression, scopeWithImports: LexicalScope, sourcePath: Collection<KtFile>, kind: CompilationKind = CompilationKind.DEFAULT): Pair<BindingContext, ComponentProvider> {
556+
fun compileKtExpression(expression: KtExpression, scopeWithImports: LexicalScope, sourcePath: Collection<KtFile>, kind: CompilationKind = CompilationKind.DEFAULT): Pair<BindingContext, ComponentProvider>? =
557557
try {
558558
// Use same lock as 'compileFile' to avoid concurrency issues such as #42
559559
compileLock.withLock {
@@ -568,12 +568,17 @@ class Compiler(
568568
InferenceSession.default,
569569
trace,
570570
true)
571-
return Pair(trace.bindingContext, container)
571+
Pair(trace.bindingContext, container)
572572
}
573573
} catch (e: KotlinFrontEndException) {
574-
throw KotlinLSException("Error while analyzing: ${describeExpression(expression.text)}", e)
574+
LOG.error("""
575+
Error while analyzing expression: ${describeExpression(expression.text)}
576+
Message: ${e.message}
577+
Cause: ${e.cause?.message}
578+
Stack trace: ${e.attachments.joinToString("\n") { it.displayText }}
579+
""".trimIndent())
580+
null
575581
}
576-
}
577582

578583
fun removeGeneratedCode(files: Collection<KtFile>) {
579584
files.forEach { file ->

server/src/main/kotlin/org/javacs/kt/hover/Hovers.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ private fun typeHoverAt(file: CompiledFile, cursor: Int): Hover? {
3838
val expression = file.parseAtPoint(cursor)?.findParent<KtExpression>() ?: return null
3939
val javaDoc: String = expression.children.mapNotNull { (it as? PsiDocCommentBase)?.text }.map(::renderJavaDoc).firstOrNull() ?: ""
4040
val scope = file.scopeAtPoint(cursor) ?: return null
41-
val hoverText = renderTypeOf(expression, file.bindingContextOf(expression, scope))
41+
val context = file.bindingContextOf(expression, scope) ?: return null
42+
val hoverText = renderTypeOf(expression, context)
4243
val hover = MarkupContent("markdown", listOf("```kotlin\n$hoverText\n```", javaDoc).filter { it.isNotEmpty() }.joinToString("\n---\n"))
4344
return Hover(hover)
4445
}

server/src/test/kotlin/org/javacs/kt/CompilerTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ private class FileToEdit {
8989
val function = original.findElementAt(49)!!.parentsWithSelf.filterIsInstance<KtNamedFunction>().first()
9090
val scope = context.get(BindingContext.LEXICAL_SCOPE, function.bodyExpression)!!
9191
val recompile = compiler.createKtDeclaration("""private fun singleExpressionFunction() = intFunction()""")
92-
val (recompileContext, _) = compiler.compileKtExpression(recompile, scope, setOf(original))
92+
val (recompileContext, _) = compiler.compileKtExpression(recompile, scope, setOf(original))!!
9393
val intFunctionRef = recompile.findElementAt(41)!!.parentsWithSelf.filterIsInstance<KtReferenceExpression>().first()
9494
val target = recompileContext.get(BindingContext.REFERENCE_TARGET, intFunctionRef)!!
9595

0 commit comments

Comments
 (0)