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:
breandan 2015-12-11 15:05:46 -05:00
parent b063fac031
commit e8f66fb06b
32 changed files with 707 additions and 10 deletions

4
.idea/modules.xml generated
View File

@ -2,7 +2,8 @@
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/code_samples/MaxOpenedProjects/MaxOpenedProjects.iml" filepath="$PROJECT_DIR$/code_samples/MaxOpenedProjects/MaxOpenedProjects.iml" />
<module fileurl="file://$PROJECT_DIR$/code_samples/comparing_references_inspection/comparing_references_inspection.iml" filepath="$PROJECT_DIR$/code_samples/comparing_references_inspection/comparing_references_inspection.iml" />
<module fileurl="file://$PROJECT_DIR$/code_samples/conditional_operator_intention/conditional_operator_intention.iml" filepath="$PROJECT_DIR$/code_samples/conditional_operator_intention/conditional_operator_intention.iml" />
<module fileurl="file://$PROJECT_DIR$/code_samples/editor_basics/editor_basics.iml" filepath="$PROJECT_DIR$/code_samples/editor_basics/editor_basics.iml" />
<module fileurl="file://$PROJECT_DIR$/code_samples/facet_basics/facet_basics.iml" filepath="$PROJECT_DIR$/code_samples/facet_basics/facet_basics.iml" />
<module fileurl="file://$PROJECT_DIR$/code_samples/framework/framework.iml" filepath="$PROJECT_DIR$/code_samples/framework/framework.iml" />
@ -10,6 +11,7 @@
<module fileurl="file://$PROJECT_DIR$/code_samples/inspection/inspection.iml" filepath="$PROJECT_DIR$/code_samples/inspection/inspection.iml" />
<module fileurl="file://$PROJECT_DIR$/.idea/intellij-sdk-docs.iml" filepath="$PROJECT_DIR$/.idea/intellij-sdk-docs.iml" />
<module fileurl="file://$PROJECT_DIR$/code_sample/kotlin_demo/kotlin_demo.iml" filepath="$PROJECT_DIR$/code_sample/kotlin_demo/kotlin_demo.iml" />
<module fileurl="file://$PROJECT_DIR$/code_samples/max_opened_projects/max_opened_projects.iml" filepath="$PROJECT_DIR$/code_samples/max_opened_projects/max_opened_projects.iml" />
<module fileurl="file://$PROJECT_DIR$/code_samples/module/module.iml" filepath="$PROJECT_DIR$/code_samples/module/module.iml" />
<module fileurl="file://$PROJECT_DIR$/code_samples/plugin_sample/plugin_sample.iml" filepath="$PROJECT_DIR$/code_samples/plugin_sample/plugin_sample.iml" />
<module fileurl="file://$PROJECT_DIR$/code_samples/project_model/project_model.iml" filepath="$PROJECT_DIR$/code_samples/project_model/project_model.iml" />

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PLUGIN_MODULE" version="4">
<component name="DevKit.ModuleBuildProperties" url="file://$MODULE_DIR$/../../code_samples/kotlin_demo/resources/META-INF/plugin.xml" />
<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$/../../code_samples/kotlin_demo">
<sourceFolder url="file://$MODULE_DIR$/../../code_samples/kotlin_demo/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/../../code_samples/kotlin_demo/resources" type="java-resource" />
<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" />

View 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>

View File

@ -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;
}
}

View File

@ -0,0 +1,10 @@
package com.intellij.codeInspection;
/**
* @author max
*/
public class ComparingReferencesProvider implements InspectionToolProvider {
public Class[] getInspectionClasses() {
return new Class[] { ComparingReferencesInspection.class};
}
}

View File

@ -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>

View File

@ -0,0 +1,6 @@
public class X {
public boolean compare2Strings(java.lang.String s1, java.lang.String s2) {
return (s1.equals(s2));
}
}

View File

@ -0,0 +1,6 @@
public class X {
public boolean compare2Strings(java.lang.String s1, java.lang.String s2) {
return (<caret>s1 == s2);
}
}

View File

@ -0,0 +1,6 @@
public class X {
public boolean compare2Dates(java.util.Date dt1, java.util.Date dt2){
return (!dt1.equals(dt2));
}
}

View File

@ -0,0 +1,6 @@
public class X {
public boolean compare2Dates(java.util.Date dt1, java.util.Date dt2){
return (dt1 <caret>!= dt2);
}
}

View File

@ -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()");
}
}

View 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>

View File

@ -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>

View 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>

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -0,0 +1,6 @@
public class X {
void f(boolean isMale) {
String title = isMale <spot>?</spot> "Mr." : "Ms.";
System.out.println("title = " + title);
}
}

View File

@ -0,0 +1,5 @@
<html>
<body>
This intention converts a ternary operator to a corresponding if statement. <br>
</body>
</html>

View File

@ -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);
}
}

View File

@ -0,0 +1,6 @@
public class X {
void f(boolean isMale) {
String title = isMale <caret>? "Mr." : "Ms.";
System.out.println("title = " + title);
}
}

View File

@ -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");
}
}

View File

@ -1,12 +1,8 @@
https://confluence.jetbrains.com/pages/viewpage.action?pageId=15799219
https://confluence.jetbrains.com/download/attachments/15799219/Presentation.pdf
https://confluence.jetbrains.com/display/IDEADEV/IntelliJ+IDEA+Notifications
https://confluence.jetbrains.com/display/IDEADEV/Creation+of+Intention+Action
https://confluence.jetbrains.com/display/IDEADEV/Inspection+of+Code+Source
https://confluence.jetbrains.com/display/IDEADEV/ComparisonChainGen
https://confluence.jetbrains.com/display/IDEADEV/Diana+Plugin+Migration+Guide
https://confluence.jetbrains.com/display/IDEADEV/Customizing+the+IDEA+Settings+Dialog
https://confluence.jetbrains.com/display/IDEADEV/Implementing+Run+Configurations+in+IntelliJ+IDEA
https://confluence.jetbrains.com/display/IDEADEV/Remote+communication
https://confluence.jetbrains.com/display/IDEADEV/Sample+Text+File+Editor

View File

@ -2,4 +2,73 @@
title: Code Inspections
---
In Progress
This topic describes the [comparing_refereces_inspection](https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/comparing_references_inspection), a sample plugin that creates a custom [inspection](http://www.jetbrains.com/idea/webhelp/code-inspection.html) for Java code. In addition, the sample plugin contains a JUnit-based test.
### About Code Inspections
**IntelliJ IDEA** provides tools designed for static code analysis (so called _code inspections_) that help you maintain and clean up your code without actually executing it. In **IntelliJ IDEA** you will find a set of built-in inspections that are grouped by their goals and sense. For more information about code inspections, see [Inspecting Source Code](http://www.jetbrains.com/idea/webhelp/inspecting-source-code.html) the in **IntelliJ IDEA** Web Help.
You can create custom inspections through the **IntelliJ IDEA** interface (see [Creating Own Inspections](http://www.jetbrains.com/idea/webhelp/creating-own-inspections.html)). Alternatively, you can develop a plugin to implement a custom inspection.
### Used Techniques
The **comparing_references_inspection** sample plugin illustrates the use of the following techniques:
- How to analyze a [PSI tree](http://confluence.jetbrains.net/display/IDEADEV/IntelliJ+IDEA+Architectural+Overview#PsiFiles).
- How to find a Java token of interest in the PSI tree.
- How to inspect Java code in the **IntelliJ IDEA** editor using the [BaseJavaLocalInspectionTool](upsource:///java/java-analysis-api/src/com/intellij/codeInspection/BaseJavaLocalInspectionTool.java) class.
- How to create a JUnit test for this plugin using the [IdeaTestFixtureFactory](upsource:///platform/testFramework/src/com/intellij/testFramework/fixtures/IdeaTestFixtureFactory.java) class.
### Sample Plugin
The **comparingReferences** sample plugin is available in the `<%IntelliJ SDK Docs project%>/code_samples/comparing_references_inspection` directory.
When launched, this plugin adds the **'==' or '!=' instead of 'equals()'** item to the **Probable bugs** node in the [Inspections list](http://www.jetbrains.com/idea/webhelp/inspections-2.html).
![](img/comparingReferences_options.png)
##### Running the Plugin
**To run the sample plugin**
1. Start **IntelliJ IDEA** and open the **comparingReferences** plugin project saved into the `<%IntelliJ SDK Docs project%>/code_samples/comparing_references_inspection` directory.
2. Open the [Project Structure](http://www.jetbrains.com/idea/webhelp/project-structure.html) dialog and ensure that the project settings are valid for your environment.
3. If necessary, modify the [Run/Debug Configurations](http://www.jetbrains.com/idea/webhelp/run-debug-configuration-plugin.html) and Run the plugin by choosing the **Run | Run** on the main menu.
##### Configuring the Plugin
Once the plugin is launched, you can set the plugin options. You can specify the Java classes to be participated in the code inspection and the severity level of the found probable bugs.
**To configure the sample plugin**
1. On the IDEA main menu, choose **File | Settings**, and then under **Project Settings**, click **Inspections**.
2. In the list of the IntelliJ IDEA inspections, expand the **Probable bugs** node, and then click **'==' or '!=' instead of 'equals()'**.
![Image](https://confluence.jetbrains.com/download/attachments/36023033/comparingReferences_options.png?version=1&modificationDate=1284998753000&api=v2)
3. Under **Options**, you can specify the following plugin settings:
- From the **Severity** list, select the severity level of probable bugs the plugin will find (such as Warning, Info, etc.)
- In the text box under **Severity**, specify the semicolon separated list of Java classes to be participated in this code inspection.
4. When finished, click **OK**.
##### How does it work?
The plugin inspects your code opened in the **IntelliJ IDEA** editor or the code you are typing. The plugin highlights the code fragments where two variables of the reference type are separated by **==** or **!=** and proposes to replace this code fragment with **.equals()**:
![](img/comparingReferences.png)
In this example, the **s1** and **s2** are variables of the String type. Clicking **Use equals()** replaces
```java
return (s1==s2);
```
with the code:
```java
return (s1.equals(s2));
```
##### Testing the Plugin
The sample plugin contains the `TestThisPlugin` Java class in the `testSource/testPlugin` package and the test data in the `testData` directory.
This test adds two test cases to this plugin project. To run test cases, run the `YourTest.test()` or `YourTest.test1()` method, respectively.
For detailed information about testing and all related procedures, refer to [Testing](http://www.jetbrains.com/idea/webhelp/testing.html) and [Testing Support](http://www.jetbrains.com/idea/webhelp/testing-support.html) in the **IntelliJ IDEA** Web Help.

View File

@ -0,0 +1,70 @@
---
title: Code Intentions
---
This topic describes the [conditional_operator_intention](https://github.com/JetBrains/intellij-sdk-docs/tree/master/code_samples/conditional_operator_intention), a sample plugin that adds a new [intention action](http://www.jetbrains.com/idea/webhelp/intention-actions.html) to the IntelliJ Platform Intentions list. In addition, the sample plugin contains a JUnit-based test.
### About Intention Actions
The **IntelliJ Platform** analyzes your code and helps handle situations that may result in errors. When a possible problem is suspected, the IDE suggests an appropriate intention action, denoted with special icons. For more information, refer to [Intention Actions](http://www.jetbrains.com/idea/webhelp/intention-actions.html) in the **IntelliJ IDEA** Web Help.
You can view a list of all available intention actions using the [Intention List](http://www.jetbrains.com/idea/webhelp/intentions.html#intentionList) provided by the IDE.
**To display Intention List**
1. Open the **Settings** dialog box.
2. Under **IDE Settings**, click **Intentions**.
This displays the list of all intention actions currently available in **IntelliJ IDEA**. The intention actions are grouped according to the areas of their use.
To enable/disable an intention action, select/clear the check box to its left.
### Used Techniques
The **conditionalOperatorConverter** sample plugin illustrates the use of the following techniques:
- How to analyze a [PSI tree](http://confluence.jetbrains.net/display/IDEADEV/IntelliJ+IDEA+Architectural+Overview#PsiFiles).
- How to find a Java token of interest in the PSI tree.
- How to invoke a quick fix action for a token element under cursor using the [PsiElementBaseIntentionAction](upsource:///platform/lang-api/src/com/intellij/codeInsight/intention/PsiElementBaseIntentionAction.java) class.
- How to create a JUnit test for this plugin using the [IdeaTestFixtureFactory](upsource:///platform/testFramework/src/com/intellij/testFramework/fixtures/IdeaTestFixtureFactory.java) class.
### Sample Plugin
The **ConditionalOperatorConverter** sample plugin is available in the `<%IntelliJ SDK Docs project%>/code_samples/conditional_operator_intention` directory. When launched, this plugin adds the **Convert ternary operator if statement** item to the **Conditional Operator** node in the IDEA Intentions list:
![](img/IntentionsList.png)
##### Running the Plugin
**To run the sample plugin**
1. Start **IntelliJ IDEA** and open the **conditionalOperatorConvertor** plugin project saved into the `<%IntelliJ SDK Docs project%>/code_samples/conditional_operator_intention` directory.
2. Open the [Project Structure](http://www.jetbrains.com/idea/webhelp/project-structure.html) dialog and ensure that the project settings are valid for your environment.
3. If necessary, modify the [Run/Debug Configurations](http://www.jetbrains.com/idea/webhelp/run-debug-configuration-plugin.html) and Run the plugin by choosing the **Run | Run** on the main menu.
##### How does it work?
The plugin analyzes symbols under the cursor in your code opened in the IDEA editor. If the cursor is positioned on the "?" conditional operator, **IntelliJ IDEA** proposes to replace this conditional (ternary) operator with the "if-then-else" statement:
![](img/TernaryOperator.png)
In this example, the code:
```java
return (n>=0) ? n : -n;
```
will be replaced with the code:
```java
if ((n>=0)) {
return n;
} else {
return -n;
}
```
###### Testing the Plugin
The sample plugin contains the `YourTest` Java class in the `testSource/testPlugin/` package and the test data in the `testData/` directory.
To perform the plugin test, run the `YourTest.test()` method.
For detailed information about testing and all related procedures, refer to [Testing](http://www.jetbrains.com/idea/webhelp/testing.html) and [Testing Support](http://www.jetbrains.com/idea/webhelp/testing-support.html) in the **IntelliJ IDEA** Web Help.

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB