Skip to content

Commit

Permalink
modifying_psi.md: Remove hardcoded code snippet, cleanup applyFix and…
Browse files Browse the repository at this point in the history
… reference it from the page
  • Loading branch information
karollewandowski committed Oct 18, 2023
1 parent 012d042 commit 7bd389f
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -98,37 +98,39 @@ public String getName() {
return InspectionBundle.message("inspection.comparing.string.references.use.quickfix");
}

/**
* This method manipulates the PSI tree to replace 'a==b' with 'a.equals(b)' or 'a!=b' with '!a.equals(b)'.
*
* @param project The project that contains the file being edited.
* @param descriptor A problem found by this inspection.
*/
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
// binaryExpression holds a PSI expression of the form "x == y",
// which needs to be replaced with "x.equals(y)"
PsiBinaryExpression binaryExpression = (PsiBinaryExpression) descriptor.getPsiElement();
IElementType opSign = binaryExpression.getOperationTokenType();
PsiExpression lExpr = binaryExpression.getLOperand();
PsiExpression rExpr = binaryExpression.getROperand();
if (rExpr == null) {
return;
}

// Step 1: Create a replacement fragment from text, with "a" and "b" as placeholders
PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
PsiMethodCallExpression equalsCall =
(PsiMethodCallExpression) factory.createExpressionFromText("a.equals(b)", null);

PsiExpression qualifierExpression = equalsCall.getMethodExpression().getQualifierExpression();
// Step 2: Replace "a" and "b" with elements from the original file
PsiExpression qualifierExpression =
equalsCall.getMethodExpression().getQualifierExpression();
assert qualifierExpression != null;
qualifierExpression.replace(lExpr);
equalsCall.getArgumentList().getExpressions()[0].replace(rExpr);

// Step 3: Replace a larger element in the original file with the replacement tree
PsiExpression result = (PsiExpression) binaryExpression.replace(equalsCall);

// Steps 4-6 needed only for negation
if (opSign == JavaTokenType.NE) {
PsiPrefixExpression negation = (PsiPrefixExpression) factory.createExpressionFromText("!a", null);
// Step 4: Create a replacement fragment with negation and negated operand placeholder
PsiPrefixExpression negation =
(PsiPrefixExpression) factory.createExpressionFromText("!a", null);
PsiExpression operand = negation.getOperand();
assert operand != null;
// Step 5: Replace operand placeholder with the actual expression
operand.replace(result);
// Step 6: Replace the result with the negated expression
result.replace(negation);
}
}
Expand All @@ -137,7 +139,5 @@ public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descri
public String getFamilyName() {
return getName();
}

}

}
18 changes: 1 addition & 17 deletions topics/basics/architectural_overview/modifying_psi.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,24 +40,8 @@ Just as everywhere else in the IntelliJ Platform API, the text passed to `create
As an example of this approach, see the quickfix in the `ComparingStringReferencesInspection` [example](code_inspections.md):

```java
// binaryExpression holds a PSI expression of the form "x == y", which needs to be replaced with "x.equals(y)"
PsiBinaryExpression binaryExpression = (PsiBinaryExpression) descriptor.getPsiElement();
IElementType opSign = binaryExpression.getOperationTokenType();
PsiExpression lExpr = binaryExpression.getLOperand();
PsiExpression rExpr = binaryExpression.getROperand();

// Step 1: Create a replacement fragment from text, with "a" and "b" as placeholders
PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
PsiMethodCallExpression equalsCall =
(PsiMethodCallExpression) factory.createExpressionFromText("a.equals(b)", null);

// Step 2: replace "a" and "b" with elements from the original file
equalsCall.getMethodExpression().getQualifierExpression().replace(lExpr);
equalsCall.getArgumentList().getExpressions()[0].replace(rExpr);

// Step 3: replace a larger element in the original file with the replacement tree
PsiExpression result = (PsiExpression) binaryExpression.replace(equalsCall);
```
{src="comparing_string_references_inspection/src/main/java/org/intellij/sdk/codeInspection/ComparingStringReferencesInspection.java" include-symbol="applyFix"}

## Maintaining Tree Structure Consistency

Expand Down

0 comments on commit 7bd389f

Please sign in to comment.