Skip to content

Refactoring JavaKeywordCompletion and PsiJavaPatterns - #310

Merged
VISTALL merged 1 commit into
consulo:masterfrom
unv-unv:kw-completion-refactoring
Oct 8, 2026
Merged

VISTALL merged 1 commit into
consulo:masterfrom
unv-unv:kw-completion-refactoring

Conversation

@unv-unv

@unv-unv unv-unv commented Oct 8, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@unv-unv

unv-unv commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

@claude review pr with inline comments

@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Claude finished @unv-unv's task in 3m 23s —— View job


Claude finished reviewing PR #310

Summary

I found no logic changes. Most of the PR is reformatting (2 → 4 space indent, braces on single-line ifs), plus instanceof pattern-matching rewrites and new @RequiredReadAction annotations. I compared every non-whitespace change against the original and all of them behave the same: createTypeDeclaration, nextIsIdentifier, isInstanceofPlace, isVariableTypePosition, isInsideQualifierClass / isInsideInheritorClass, and the Conditions.instanceOf → PsiTypeElement.class::isInstance swap.

Inline comments

PsiJavaPatterns.java

  • The @RequiredReadAction annotations are on the wrong conditions. They were added to the accepts in psiJavaElement(Class...) and psiModifierListOwner, which only do instanceof checks. The conditions that actually read PSI have none: psiNewExpression (getClassOrAnonymousClassReference / getQualifiedName), and psiLiteral / literalExpression (getValue()).
  • Leftover final on parameters at L61, L84, L98 and L117, which doesn't match the rest of the cleanup.

JavaKeywordCompletion.java

  • Some methods that read PSI still lack @RequiredReadAction: isLambdaParameterType, getFileForDeclaration, expectsClassLiteral, isForLoopMachinery and superConstructorHasParameters.
  • Indentation slips from the reformat: in isSuitableForClass (L863–869) and addPrimitiveTypes (L946–950), the method-call arguments sit at the same level as the || operand.
  • addUnfinishedMethodTypeParameters: the pattern variable is named capture, which doesn't say what it matches. I suggested a rename; the pattern could also become a static final constant.
  • Smaller nits: a leftover final boolean hasParams (L499), and in isInsideInheritorClass a typed for loop would remove the (PsiClass) parent cast.

I didn't build or run tests; this is a read-only review.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inline review from Claude. Overall the refactoring looks behavior-preserving: I checked every non-whitespace hunk (pattern-matching instanceof rewrites, the flattened else if in createTypeDeclaration, the inlined boolean chains in nextIsIdentifier, isInstanceofPlace, isVariableTypePosition, isInsideQualifierClass and isInsideInheritorClass, and Conditions.instanceOf → PsiTypeElement.class::isInstance) and found no logic changes. The comments below are about where @RequiredReadAction is applied, leftover final modifiers, and a couple of indentation slips from the reformat.

Comment on lines +63 to +64
@Override
@RequiredReadAction

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This accepts only calls Class.isInstance, so it never touches PSI and doesn't need @RequiredReadAction. Meanwhile the conditions that do read PSI (psiNewExpression, psiLiteral, literalExpression) have no annotation. I'd drop it here (and in psiModifierListOwner below) and add it where it actually applies.

Suggested change
@Override
@RequiredReadAction
@Override

Comment on lines +145 to +146
@Override
@RequiredReadAction

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here: a plain instanceof check doesn't need a read action.

Suggested change
@Override
@RequiredReadAction
@Override


public static PsiJavaElementPattern.Capture<PsiNewExpression> psiNewExpression(final String... fqns) {
return new PsiJavaElementPattern.Capture<>(new InitialPatternCondition<>(PsiNewExpression.class) {
@Override

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the condition that needs @RequiredReadAction: getClassOrAnonymousClassReference() and getQualifiedName() both walk or resolve PSI. The same goes for PsiLiteral.getValue() in psiLiteral (L86) and literalExpression (L119).

Suggested change
@Override
@Override
@RequiredReadAction

}

@SafeVarargs
public static PsiJavaElementPattern.Capture<PsiElement> psiJavaElement(final Class<? extends PsiElement>... classAlternatives) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the reformat removed final from the other parameters (for example psiJavaElement(Class<T> aClass)), but it's still here and on L84, L98 and L117. Effectively-final is enough for capture in the anonymous classes.

Suggested change
public static PsiJavaElementPattern.Capture<PsiElement> psiJavaElement(final Class<? extends PsiElement>... classAlternatives) {
public static PsiJavaElementPattern.Capture<PsiElement> psiJavaElement(Class<? extends PsiElement>... classAlternatives) {

return psiLiteral(null);
}

public static PsiJavaElementPattern.Capture<PsiLiteral> psiLiteral(@Nullable final ElementPattern value) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public static PsiJavaElementPattern.Capture<PsiLiteral> psiLiteral(@Nullable final ElementPattern value) {
public static PsiJavaElementPattern.Capture<PsiLiteral> psiLiteral(@Nullable ElementPattern value) {

.accepts(myPosition)) {
PsiMethod method = PsiTreeUtil.getParentOfType(myPosition, PsiMethod.class, false, PsiClass.class);
assert method != null;
final boolean hasParams = superConstructorHasParameters(method);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: this final is a leftover; the PR drops final elsewhere, and effectively-final is enough for the anonymous ParenthesesInsertHandler.

Suggested change
final boolean hasParams = superConstructorHasParameters(method);
boolean hasParams = superConstructorHasParameters(method);

|| isStatementPosition(position);
}

private boolean isLambdaParameterType() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RequiredReadAction was added to almost every PSI-touching method in this file, but a few were missed: isLambdaParameterType, getFileForDeclaration (L741), expectsClassLiteral (L993), isForLoopMachinery (L1098) and superConstructorHasParameters (L1146). Some of them are called from annotated methods, so the read-action inspection may flag the gaps.

Suggested change
private boolean isLambdaParameterType() {
@RequiredReadAction
private boolean isLambdaParameterType() {

if (expressionPosition && !session.isKeywordAlreadyProcessed(PsiKeyword.VOID)) {
result.accept(BasicExpressionCompletionContributor.createKeywordLookupItem(position, PsiKeyword.VOID));
}
private static boolean expectsClassLiteral(PsiElement position) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private static boolean expectsClassLiteral(PsiElement position) {
@RequiredReadAction
private static boolean expectsClassLiteral(PsiElement position) {

if (isEndOfBlock(position) &&
PsiTreeUtil.getParentOfType(position, PsiCodeBlock.class, true, PsiMember.class) != null) {
return !isForLoopMachinery(position);
private static boolean isForLoopMachinery(PsiElement position) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private static boolean isForLoopMachinery(PsiElement position) {
@RequiredReadAction
private static boolean isForLoopMachinery(PsiElement position) {

if (psiClass == null) {
return false;
}
private static boolean superConstructorHasParameters(PsiMethod method) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private static boolean superConstructorHasParameters(PsiMethod method) {
@RequiredReadAction
private static boolean superConstructorHasParameters(PsiMethod method) {

@VISTALL
VISTALL merged commit 64a0cd3 into consulo:master Oct 8, 2026
1 check passed
@unv-unv
unv-unv deleted the kw-completion-refactoring branch October 8, 2026 20:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants