mirror of
https://github.com/JetBrains/intellij-sdk-code-samples.git
synced 2025-07-29 09:47:50 +08:00
Migrate Intentions and Inspections tutorials from Confluence and minor fixes
- https://confluence.jetbrains.com/display/IDEADEV/Creation+of+Intention+Action -https://confluence.jetbrains.com/display/IDEADEV/Inspection+of+Code+Source
This commit is contained in:
parent
1793463daf
commit
d30c85e66c
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PLUGIN_MODULE" version="4">
|
||||||
|
<component name="DevKit.ModuleBuildProperties" url="file://$MODULE_DIR$/source/META-INF/plugin.xml" />
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/source" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/testSource" isTestSource="true" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
14
comparing_references_inspection/source/META-INF/plugin.xml
Normal file
14
comparing_references_inspection/source/META-INF/plugin.xml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<idea-plugin version="2">
|
||||||
|
<name>Comparing References Inspection</name>
|
||||||
|
<description>Inspection for (probably) inappropriate use of equality relation operation.</description>
|
||||||
|
<version>1.0</version>
|
||||||
|
<vendor>JetBrains</vendor>
|
||||||
|
<!--
|
||||||
|
<idea-version since-build="3000"/>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
|
<inspectionToolProvider implementation="com.intellij.codeInspection.ComparingReferencesProvider"/>
|
||||||
|
</extensions>
|
||||||
|
|
||||||
|
</idea-plugin>
|
@ -0,0 +1,152 @@
|
|||||||
|
package com.intellij.codeInspection;
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.daemon.GroupNames;
|
||||||
|
import com.intellij.openapi.diagnostic.Logger;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.openapi.util.Ref;
|
||||||
|
import com.intellij.psi.*;
|
||||||
|
import com.intellij.psi.tree.IElementType;
|
||||||
|
import com.intellij.ui.DocumentAdapter;
|
||||||
|
import com.intellij.util.IncorrectOperationException;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.event.DocumentEvent;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author max
|
||||||
|
*/
|
||||||
|
public class ComparingReferencesInspection extends BaseJavaLocalInspectionTool {
|
||||||
|
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ComparingReferencesInspection");
|
||||||
|
|
||||||
|
private final LocalQuickFix myQuickFix = new MyQuickFix();
|
||||||
|
|
||||||
|
@SuppressWarnings({"WeakerAccess"}) @NonNls public String CHECKED_CLASSES = "java.lang.String;java.util.Date";
|
||||||
|
@NonNls private static final String DESCRIPTION_TEMPLATE = InspectionsBundle.message("inspection.comparing.references.problem.descriptor");
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String getDisplayName() {
|
||||||
|
|
||||||
|
return "'==' or '!=' instead of 'equals()'";
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String getGroupDisplayName() {
|
||||||
|
return GroupNames.BUGS_GROUP_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String getShortName() {
|
||||||
|
return "ComparingReferences";
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isCheckedType(PsiType type) {
|
||||||
|
if (!(type instanceof PsiClassType)) return false;
|
||||||
|
|
||||||
|
StringTokenizer tokenizer = new StringTokenizer(CHECKED_CLASSES, ";");
|
||||||
|
while (tokenizer.hasMoreTokens()) {
|
||||||
|
String className = tokenizer.nextToken();
|
||||||
|
if (type.equalsToText(className)) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
|
||||||
|
return new JavaElementVisitor() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitReferenceExpression(PsiReferenceExpression psiReferenceExpression) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override public void visitBinaryExpression(PsiBinaryExpression expression) {
|
||||||
|
super.visitBinaryExpression(expression);
|
||||||
|
IElementType opSign = expression.getOperationTokenType();
|
||||||
|
if (opSign == JavaTokenType.EQEQ || opSign == JavaTokenType.NE) {
|
||||||
|
PsiExpression lOperand = expression.getLOperand();
|
||||||
|
PsiExpression rOperand = expression.getROperand();
|
||||||
|
if (rOperand == null || isNullLiteral(lOperand) || isNullLiteral(rOperand)) return;
|
||||||
|
|
||||||
|
PsiType lType = lOperand.getType();
|
||||||
|
PsiType rType = rOperand.getType();
|
||||||
|
|
||||||
|
if (isCheckedType(lType) || isCheckedType(rType)) {
|
||||||
|
holder.registerProblem(expression,
|
||||||
|
DESCRIPTION_TEMPLATE, myQuickFix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isNullLiteral(PsiExpression expr) {
|
||||||
|
return expr instanceof PsiLiteralExpression && "null".equals(expr.getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class MyQuickFix implements LocalQuickFix {
|
||||||
|
@NotNull
|
||||||
|
public String getName() {
|
||||||
|
// The test (see the TestThisPlugin class) uses this string to identify the quick fix action.
|
||||||
|
return InspectionsBundle.message("inspection.comparing.references.use.quickfix");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||||
|
try {
|
||||||
|
PsiBinaryExpression binaryExpression = (PsiBinaryExpression)descriptor.getPsiElement();
|
||||||
|
IElementType opSign = binaryExpression.getOperationTokenType();
|
||||||
|
PsiExpression lExpr = binaryExpression.getLOperand();
|
||||||
|
PsiExpression rExpr = binaryExpression.getROperand();
|
||||||
|
if (rExpr == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
|
||||||
|
PsiMethodCallExpression equalsCall = (PsiMethodCallExpression)factory.createExpressionFromText("a.equals(b)", null);
|
||||||
|
|
||||||
|
equalsCall.getMethodExpression().getQualifierExpression().replace(lExpr);
|
||||||
|
equalsCall.getArgumentList().getExpressions()[0].replace(rExpr);
|
||||||
|
|
||||||
|
PsiExpression result = (PsiExpression)binaryExpression.replace(equalsCall);
|
||||||
|
|
||||||
|
if (opSign == JavaTokenType.NE) {
|
||||||
|
PsiPrefixExpression negation = (PsiPrefixExpression)factory.createExpressionFromText("!a", null);
|
||||||
|
negation.getOperand().replace(result);
|
||||||
|
result.replace(negation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IncorrectOperationException e) {
|
||||||
|
LOG.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String getFamilyName() {
|
||||||
|
return getName();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public JComponent createOptionsPanel() {
|
||||||
|
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
||||||
|
final JTextField checkedClasses = new JTextField(CHECKED_CLASSES);
|
||||||
|
checkedClasses.getDocument().addDocumentListener(new DocumentAdapter() {
|
||||||
|
public void textChanged(DocumentEvent event) {
|
||||||
|
CHECKED_CLASSES = checkedClasses.getText();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
panel.add(checkedClasses);
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isEnabledByDefault() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.intellij.codeInspection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author max
|
||||||
|
*/
|
||||||
|
public class ComparingReferencesProvider implements InspectionToolProvider {
|
||||||
|
public Class[] getInspectionClasses() {
|
||||||
|
return new Class[] { ComparingReferencesInspection.class};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
This inspection reports when the '==' or '!=' operator was used between expressions of
|
||||||
|
reference types. <br>
|
||||||
|
In the text field below, specify the semicolon separated list of classes to be considered as suspicious.
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,6 @@
|
|||||||
|
public class X {
|
||||||
|
public boolean compare2Strings(java.lang.String s1, java.lang.String s2) {
|
||||||
|
return (s1.equals(s2));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
6
comparing_references_inspection/testData/before.java
Normal file
6
comparing_references_inspection/testData/before.java
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
public class X {
|
||||||
|
public boolean compare2Strings(java.lang.String s1, java.lang.String s2) {
|
||||||
|
return (<caret>s1 == s2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
public class X {
|
||||||
|
public boolean compare2Dates(java.util.Date dt1, java.util.Date dt2){
|
||||||
|
return (!dt1.equals(dt2));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
6
comparing_references_inspection/testData/before1.java
Normal file
6
comparing_references_inspection/testData/before1.java
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
public class X {
|
||||||
|
public boolean compare2Dates(java.util.Date dt1, java.util.Date dt2){
|
||||||
|
return (dt1 <caret>!= dt2);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
package testPlugin;
|
||||||
|
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||||
|
import com.intellij.codeInsight.intention.IntentionAction;
|
||||||
|
import com.intellij.codeInspection.ComparingReferencesInspection;
|
||||||
|
import com.intellij.testFramework.UsefulTestCase;
|
||||||
|
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
|
||||||
|
import com.intellij.testFramework.fixtures.*;
|
||||||
|
import junit.framework.Assert;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see JavaCodeInsightFixtureTestCase
|
||||||
|
* @see LightCodeInsightFixtureTestCase
|
||||||
|
*/
|
||||||
|
public class TestThisPlugin extends UsefulTestCase {
|
||||||
|
|
||||||
|
protected CodeInsightTestFixture myFixture;
|
||||||
|
// Specify path to your test data directory
|
||||||
|
// e.g. final String dataPath = "c:\\users\\john.doe\\idea\\community\\samples\\ComparingReferences/testData";
|
||||||
|
final String dataPath = "c:\\users\\John.Doe\\idea\\community\\samples\\comparingReferences/testData";
|
||||||
|
|
||||||
|
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
|
||||||
|
final IdeaTestFixtureFactory fixtureFactory = IdeaTestFixtureFactory.getFixtureFactory();
|
||||||
|
final TestFixtureBuilder<IdeaProjectTestFixture> testFixtureBuilder = fixtureFactory.createFixtureBuilder(getName());
|
||||||
|
myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(testFixtureBuilder.getFixture());
|
||||||
|
myFixture.setTestDataPath(dataPath);
|
||||||
|
final JavaModuleFixtureBuilder builder = testFixtureBuilder.addModule(JavaModuleFixtureBuilder.class);
|
||||||
|
|
||||||
|
builder.addContentRoot(myFixture.getTempDirPath()).addSourceRoot("");
|
||||||
|
builder.setMockJdkLevel(JavaModuleFixtureBuilder.MockJdkLevel.jdk15);
|
||||||
|
myFixture.setUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
myFixture.tearDown();
|
||||||
|
myFixture = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void doTest(String testName, String hint) throws Throwable {
|
||||||
|
myFixture.configureByFile(testName + ".java");
|
||||||
|
myFixture.enableInspections(ComparingReferencesInspection.class);
|
||||||
|
List<HighlightInfo> highlightInfos = myFixture.doHighlighting();
|
||||||
|
Assert.assertTrue(!highlightInfos.isEmpty());
|
||||||
|
|
||||||
|
final IntentionAction action = myFixture.findSingleIntention(hint);
|
||||||
|
|
||||||
|
Assert.assertNotNull(action);
|
||||||
|
myFixture.launchAction(action);
|
||||||
|
myFixture.checkResultByFile(testName + ".after.java");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test the "==" case
|
||||||
|
public void test() throws Throwable {
|
||||||
|
doTest("before", "Use equals()");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test the "!=" case
|
||||||
|
public void test1() throws Throwable {
|
||||||
|
doTest("before1", "Use equals()");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
27
conditional_operator_intention/META-INF/plugin.xml
Normal file
27
conditional_operator_intention/META-INF/plugin.xml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<idea-plugin version="2">
|
||||||
|
<name>Conditional Operator Converter</name>
|
||||||
|
<id>ConditionalOperatorConverter</id>
|
||||||
|
<description>Intention action that suggests to convert a conditional operator into
|
||||||
|
'if' block.
|
||||||
|
</description>
|
||||||
|
<version>1.3</version>
|
||||||
|
<vendor>JetBrains</vendor>
|
||||||
|
<!--
|
||||||
|
<idea-version since-build="2000"/>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
|
<intentionAction>
|
||||||
|
<className>com.intellij.codeInsight.intention.ConditionalOperatorConvertor</className>
|
||||||
|
<category>Conditional Operator</category>
|
||||||
|
<descriptionDirectoryName>ConditionalOperatorConvertor</descriptionDirectoryName>
|
||||||
|
|
||||||
|
</intentionAction>
|
||||||
|
</extensions>
|
||||||
|
|
||||||
|
<project-components>
|
||||||
|
<component>
|
||||||
|
<implementation-class>com.intellij.codeInsight.intention.ConditionalOperatorConvertor</implementation-class>
|
||||||
|
</component>
|
||||||
|
</project-components>
|
||||||
|
</idea-plugin>
|
@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="PLUGIN_MODULE" version="4">
|
||||||
|
<component name="DevKit.ModuleBuildProperties" url="file://$MODULE_DIR$/source/META-INF/plugin.xml" />
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/source" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/testSource" isTestSource="true" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
35
conditional_operator_intention/source/META-INF/plugin.xml
Normal file
35
conditional_operator_intention/source/META-INF/plugin.xml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<idea-plugin version="2">
|
||||||
|
<id>com.your.company.unique.plugin.id</id>
|
||||||
|
<name>Plugin display name here</name>
|
||||||
|
<version>1.0</version>
|
||||||
|
<vendor email="support@yourcompany.com" url="http://www.yourcompany.com">YourCompany</vendor>
|
||||||
|
|
||||||
|
<description><![CDATA[
|
||||||
|
Enter short description for your plugin here.<br>
|
||||||
|
<em>most HTML tags may be used</em>
|
||||||
|
]]></description>
|
||||||
|
|
||||||
|
<change-notes><![CDATA[
|
||||||
|
Add change notes here.<br>
|
||||||
|
<em>most HTML tags may be used</em>
|
||||||
|
]]>
|
||||||
|
</change-notes>
|
||||||
|
|
||||||
|
<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/build_number_ranges.html for description -->
|
||||||
|
<idea-version since-build="141.0"/>
|
||||||
|
|
||||||
|
<!-- please see http://www.jetbrains.org/intellij/sdk/docs/basics/getting_started/plugin_compatibility.html
|
||||||
|
on how to target different products -->
|
||||||
|
<!-- uncomment to enable plugin in all products
|
||||||
|
<depends>com.intellij.modules.lang</depends>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
|
<!-- Add your extensions here -->
|
||||||
|
</extensions>
|
||||||
|
|
||||||
|
<actions>
|
||||||
|
<!-- Add your actions here -->
|
||||||
|
</actions>
|
||||||
|
|
||||||
|
</idea-plugin>
|
@ -0,0 +1,110 @@
|
|||||||
|
package com.intellij.codeInsight.intention;
|
||||||
|
|
||||||
|
import com.intellij.openapi.editor.Editor;
|
||||||
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.psi.*;
|
||||||
|
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
|
import com.intellij.util.IncorrectOperationException;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dsl
|
||||||
|
*/
|
||||||
|
@NonNls public class ConditionalOperatorConvertor extends PsiElementBaseIntentionAction implements IntentionAction {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String getText() {
|
||||||
|
return "Convert ternary operator to if statement";
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public String getFamilyName() {
|
||||||
|
return getText();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAvailable(@NotNull Project project, Editor editor, @Nullable PsiElement element) {
|
||||||
|
if (element == null) return false;
|
||||||
|
if (!element.isWritable()) return false;
|
||||||
|
|
||||||
|
if (element instanceof PsiJavaToken) {
|
||||||
|
final PsiJavaToken token = (PsiJavaToken)element;
|
||||||
|
if (token.getTokenType() != JavaTokenType.QUEST) return false;
|
||||||
|
if (token.getParent() instanceof PsiConditionalExpression) {
|
||||||
|
final PsiConditionalExpression conditionalExpression = (PsiConditionalExpression)token.getParent();
|
||||||
|
if (conditionalExpression.getThenExpression() == null
|
||||||
|
|| conditionalExpression.getElseExpression() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||||
|
final int offset = editor.getCaretModel().getOffset();
|
||||||
|
final PsiElement element = file.findElementAt(offset);
|
||||||
|
PsiConditionalExpression conditionalExpression = PsiTreeUtil.getParentOfType(element,
|
||||||
|
PsiConditionalExpression.class, false);
|
||||||
|
if (conditionalExpression == null) return;
|
||||||
|
if (conditionalExpression.getThenExpression() == null || conditionalExpression.getElseExpression() == null) return;
|
||||||
|
|
||||||
|
final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
|
||||||
|
|
||||||
|
PsiElement originalStatement = PsiTreeUtil.getParentOfType(conditionalExpression, PsiStatement.class, false);
|
||||||
|
while (originalStatement instanceof PsiForStatement) {
|
||||||
|
originalStatement = PsiTreeUtil.getParentOfType(originalStatement, PsiStatement.class, true);
|
||||||
|
}
|
||||||
|
if (originalStatement == null) return;
|
||||||
|
|
||||||
|
// Maintain declrations
|
||||||
|
if (originalStatement instanceof PsiDeclarationStatement) {
|
||||||
|
final PsiDeclarationStatement declaration = (PsiDeclarationStatement)originalStatement;
|
||||||
|
final PsiElement[] declaredElements = declaration.getDeclaredElements();
|
||||||
|
PsiLocalVariable variable = null;
|
||||||
|
for (PsiElement declaredElement : declaredElements) {
|
||||||
|
if (declaredElement instanceof PsiLocalVariable && PsiTreeUtil.isAncestor(declaredElement, conditionalExpression, true)) {
|
||||||
|
variable = (PsiLocalVariable)declaredElement;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (variable == null) return;
|
||||||
|
variable.normalizeDeclaration();
|
||||||
|
final Object marker = new Object();
|
||||||
|
PsiTreeUtil.mark(conditionalExpression, marker);
|
||||||
|
PsiExpressionStatement statement =
|
||||||
|
(PsiExpressionStatement)factory.createStatementFromText(variable.getName() + " = 0;", null);
|
||||||
|
statement = (PsiExpressionStatement)CodeStyleManager.getInstance(project).reformat(statement);
|
||||||
|
((PsiAssignmentExpression)statement.getExpression()).getRExpression().replace(variable.getInitializer());
|
||||||
|
variable.getInitializer().delete();
|
||||||
|
final PsiElement variableParent = variable.getParent();
|
||||||
|
originalStatement = variableParent.getParent().addAfter(statement, variableParent);
|
||||||
|
conditionalExpression = (PsiConditionalExpression)PsiTreeUtil.releaseMark(originalStatement, marker);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create then and else branches
|
||||||
|
final PsiElement[] originalElements = new PsiElement[]{originalStatement, conditionalExpression};
|
||||||
|
final PsiExpression condition = (PsiExpression)conditionalExpression.getCondition().copy();
|
||||||
|
final PsiElement[] thenElements = PsiTreeUtil.copyElements(originalElements);
|
||||||
|
final PsiElement[] elseElements = PsiTreeUtil.copyElements(originalElements);
|
||||||
|
thenElements[1].replace(conditionalExpression.getThenExpression());
|
||||||
|
elseElements[1].replace(conditionalExpression.getElseExpression());
|
||||||
|
|
||||||
|
PsiIfStatement statement = (PsiIfStatement)factory.createStatementFromText("if (true) { a = b } else { c = d }",
|
||||||
|
null);
|
||||||
|
statement = (PsiIfStatement)CodeStyleManager.getInstance(project).reformat(statement);
|
||||||
|
statement.getCondition().replace(condition);
|
||||||
|
statement = (PsiIfStatement)originalStatement.replace(statement);
|
||||||
|
|
||||||
|
((PsiBlockStatement)statement.getThenBranch()).getCodeBlock().getStatements()[0].replace(thenElements[0]);
|
||||||
|
((PsiBlockStatement)statement.getElseBranch()).getCodeBlock().getStatements()[0].replace(elseElements[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean startInWriteAction() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
public class X {
|
||||||
|
void f(boolean isMale) {
|
||||||
|
String title;
|
||||||
|
if (isMale) {
|
||||||
|
title = "Mr.";
|
||||||
|
} else {
|
||||||
|
title = "Ms.";
|
||||||
|
}
|
||||||
|
System.out.println("title = " + title);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
public class X {
|
||||||
|
void f(boolean isMale) {
|
||||||
|
String title = isMale <spot>?</spot> "Mr." : "Ms.";
|
||||||
|
System.out.println("title = " + title);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
This intention converts a ternary operator to a corresponding if statement. <br>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,11 @@
|
|||||||
|
public class X {
|
||||||
|
void f(boolean isMale) {
|
||||||
|
String title;
|
||||||
|
if (isMale) {
|
||||||
|
title = "Mr.";
|
||||||
|
} else {
|
||||||
|
title = "Ms.";
|
||||||
|
}
|
||||||
|
System.out.println("title = " + title);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
public class X {
|
||||||
|
void f(boolean isMale) {
|
||||||
|
String title = isMale <caret>? "Mr." : "Ms.";
|
||||||
|
System.out.println("title = " + title);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
package testPlugin;
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.intention.IntentionAction;
|
||||||
|
|
||||||
|
import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
|
||||||
|
import com.intellij.testFramework.fixtures.*;
|
||||||
|
import junit.framework.Assert;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by IntelliJ IDEA.
|
||||||
|
* User: Alexey.Chursin
|
||||||
|
* Date: Sep 13, 2010
|
||||||
|
* Time: 9:35:50 PM
|
||||||
|
* To change this template use File | Settings | File Templates.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class YourTest {
|
||||||
|
protected CodeInsightTestFixture myFixture;
|
||||||
|
// Specify path to your test data
|
||||||
|
// e.g. final String dataPath = "c:\\users\\john.doe\\idea\\community\\samples\\conditionalOperatorConvertor/testData";
|
||||||
|
final String dataPath = "c:\\users\\John.Doe\\idea\\community\\samples\\conditionalOperatorConvertor/testData";
|
||||||
|
|
||||||
|
@Before
|
||||||
|
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
|
||||||
|
final IdeaTestFixtureFactory fixtureFactory = IdeaTestFixtureFactory.getFixtureFactory();
|
||||||
|
final TestFixtureBuilder<IdeaProjectTestFixture> testFixtureBuilder = fixtureFactory.createFixtureBuilder();
|
||||||
|
myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(testFixtureBuilder.getFixture());
|
||||||
|
myFixture.setTestDataPath(dataPath);
|
||||||
|
final JavaModuleFixtureBuilder builder = testFixtureBuilder.addModule(JavaModuleFixtureBuilder.class);
|
||||||
|
|
||||||
|
builder.addContentRoot(myFixture.getTempDirPath()).addSourceRoot("");
|
||||||
|
builder.setMockJdkLevel(JavaModuleFixtureBuilder.MockJdkLevel.jdk15);
|
||||||
|
myFixture.setUp();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
myFixture.tearDown();
|
||||||
|
myFixture = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void doTest(String testName, String hint) throws Throwable {
|
||||||
|
// Messages.showInfoMessage("Test started", "Info");
|
||||||
|
myFixture.configureByFile(testName + ".java");
|
||||||
|
final IntentionAction action = myFixture.findSingleIntention(hint);
|
||||||
|
Assert.assertNotNull(action);
|
||||||
|
myFixture.launchAction(action);
|
||||||
|
myFixture.checkResultByFile(testName + ".after.java");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() throws Throwable {
|
||||||
|
doTest("before.template", "Convert ternary operator to if statement");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user