[java debugger] SourcePosition#getElementAt is nullable

it indeed can return null, and clients should be ready for that

GitOrigin-RevId: c1a0c0b01951cf3035a4633bae0906f38a07060a
This commit is contained in:
Max Medvedev
2023-07-09 12:52:41 +02:00
committed by intellij-monorepo-bot
parent e61eb774b0
commit c5be6baafc
8 changed files with 22 additions and 30 deletions

View File

@@ -1,18 +1,4 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.debugger.engine;
import com.intellij.debugger.SourcePosition;
@@ -31,7 +17,8 @@ public class JavaSourcePositionHighlighter extends SourcePositionHighlighter imp
public TextRange getHighlightRange(SourcePosition sourcePosition) {
// Highlight only return keyword in case of conditional return breakpoint.
PsiElement element = sourcePosition.getElementAt();
if (JavaLineBreakpointType.isReturnKeyword(element) &&
if (element != null &&
JavaLineBreakpointType.isReturnKeyword(element) &&
element == JavaLineBreakpointType.findSingleConditionalReturn(sourcePosition)) {
return element.getTextRange();
}

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.debugger.engine;
import com.intellij.debugger.SourcePosition;
@@ -6,6 +6,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
abstract class RemappedSourcePosition extends SourcePosition {
private SourcePosition myDelegate;
@@ -22,7 +23,7 @@ abstract class RemappedSourcePosition extends SourcePosition {
}
@Override
public PsiElement getElementAt() {
public @Nullable PsiElement getElementAt() {
checkRemap();
return myDelegate.getElementAt();
}

View File

@@ -29,7 +29,7 @@ public abstract class SourcePosition implements Navigatable {
@NotNull
public abstract PsiFile getFile();
public abstract PsiElement getElementAt();
public abstract @Nullable PsiElement getElementAt();
/**
* @return a zero-based line number
@@ -137,7 +137,7 @@ public abstract class SourcePosition implements Navigatable {
}
@Override
public PsiElement getElementAt() {
public @Nullable PsiElement getElementAt() {
updateData();
PsiElement element = SoftReference.dereference(myPsiElementRef);
if (element == null) {

View File

@@ -63,7 +63,7 @@ class KotlinLambdaMethodFilter(
return@runReadAction true
}
val blockAt = elementAt.parentOfType<KtBlockExpression>(withSelf = true)
val blockAt = elementAt?.parentOfType<KtBlockExpression>(withSelf = true)
blockAt == bodyExpression
}
}

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.debugger.core.breakpoints
import com.intellij.debugger.SourcePosition
@@ -62,7 +62,7 @@ open class KotlinFunctionBreakpoint(
}
override fun refineSourcePosition(sourcePosition: SourcePosition): SourcePosition {
val declaration = sourcePosition.elementAt.parentOfType<KtDeclaration>(withSelf = true) ?: return sourcePosition
val declaration = sourcePosition.elementAt?.parentOfType<KtDeclaration>(withSelf = true) ?: return sourcePosition
if (declaration.isExpectDeclaration()) {
val actualDeclaration = declaration.getActualJvmDeclaration() ?: return sourcePosition
return SourcePosition.createFromElement(actualDeclaration) ?: sourcePosition

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
// The package directive doesn't match the file location to prevent API breakage
package org.jetbrains.kotlin.idea.debugger.breakpoints
@@ -112,7 +112,7 @@ class KotlinLineBreakpointType :
if (lambdas.isEmpty() && condRet == null) return emptyList()
val result = LinkedList<JavaLineBreakpointType.JavaBreakpointVariant>()
val elementAt = pos.elementAt.parentsWithSelf.firstIsInstance<KtElement>()
val elementAt = pos.elementAt?.parentsWithSelf?.firstIsInstance<KtElement>() ?: return emptyList()
val mainMethod = PsiTreeUtil.getParentOfType(elementAt, KtFunction::class.java, false)
var mainMethodAdded = false
if (mainMethod != null) {
@@ -157,7 +157,7 @@ class KotlinLineBreakpointType :
val lambdaOrdinal = properties.lambdaOrdinal ?: return null
// Since lambda breakpoints are placed on the first lambda statement,
// we should find the function parent to highlight lambda breakpoints properly
val function = position.elementAt.parentOfType<KtFunction>() ?: return null
val function = position.elementAt?.parentOfType<KtFunction>() ?: return null
val updatedPosition = SourcePosition.createFromElement(function) ?: return null
return getLambdaByOrdinal(updatedPosition, lambdaOrdinal)?.textRange
}

View File

@@ -1,4 +1,4 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package org.jetbrains.kotlin.idea.debugger.coroutine
import com.intellij.debugger.engine.DebugProcessImpl
@@ -26,7 +26,8 @@ internal class KotlinVariableNameFinder(val debugProcess: DebugProcessImpl) {
fun findVisibleVariableNames(location: Location): List<String> {
val sourcePosition = KotlinPositionManager(debugProcess).safeGetSourcePosition(location) ?: return emptyList()
ProgressManager.checkCanceled()
return findVisibleVariableNamesFrom(sourcePosition.elementAt)
val elementAt = sourcePosition.elementAt ?: return emptyList()
return findVisibleVariableNamesFrom(elementAt)
}
private fun findVisibleVariableNamesFrom(element: PsiElement): List<String> {

View File

@@ -250,7 +250,10 @@ abstract class KotlinDescriptorTestCaseWithStepping : KotlinDescriptorTestCase()
try {
doStepInto(ignoreFilters, filters[chooseFromList - 1])
} catch (e: IndexOutOfBoundsException) {
val elementText = runReadAction { debuggerContext.sourcePosition.elementAt.getElementTextWithContext() }
val elementText = runReadAction {
val elementAt = debuggerContext.sourcePosition.elementAt ?: return@runReadAction "<no-element>"
elementAt.getElementTextWithContext()
}
throw AssertionError("Couldn't find smart step into command at: \n$elementText", e)
}
}
@@ -285,7 +288,7 @@ abstract class KotlinDescriptorTestCaseWithStepping : KotlinDescriptorTestCase()
private fun List<SmartStepTarget>.getIndicesInTree(): List<Int> {
val targetsIndicesInTree = MutableList(size) { 0 }
runReadAction {
val elementAt = debuggerContext.sourcePosition.elementAt
val elementAt = debuggerContext.sourcePosition.elementAt ?: return@runReadAction
val topmostElement = getTopmostElementAtOffset(elementAt, elementAt.textRange.startOffset)
topmostElement.accept(object : KtTreeVisitorVoid() {
private var elementIndex = 0