not postfix template added
authorliana.bakradze <liana.bakradze@jetbrains.com>
Tue, 12 Jan 2016 12:58:10 +0000 (15:58 +0300)
committerliana.bakradze <liana.bakradze@jetbrains.com>
Thu, 11 Feb 2016 20:34:49 +0000 (23:34 +0300)
(cherry picked from commit 6e6ca9d)

15 files changed:
python/resources/postfixTemplates/PyNotPostfixTemplate/after.py.template [new file with mode: 0644]
python/resources/postfixTemplates/PyNotPostfixTemplate/before.py.template [new file with mode: 0644]
python/resources/postfixTemplates/PyNotPostfixTemplate/description.html [new file with mode: 0644]
python/src/META-INF/python-core-common.xml
python/src/com/jetbrains/python/codeInsight/postfix/PyNotPostfixTemplate.java [new file with mode: 0644]
python/src/com/jetbrains/python/codeInsight/postfix/PyPostfixTemplateProvider.java [new file with mode: 0644]
python/src/com/jetbrains/python/codeInsight/postfix/PyPostfixUtils.java [new file with mode: 0644]
python/testData/postfix/not/if.py [new file with mode: 0644]
python/testData/postfix/not/if_after.py [new file with mode: 0644]
python/testData/postfix/not/number.py [new file with mode: 0644]
python/testData/postfix/not/number_after.py [new file with mode: 0644]
python/testData/postfix/not/parenthesis.py [new file with mode: 0644]
python/testData/postfix/not/parenthesis_after.py [new file with mode: 0644]
python/testSrc/com/jetbrains/python/postfix/PyNotPostfixTemplateTest.java [new file with mode: 0644]
python/testSrc/com/jetbrains/python/postfix/PyPostfixTemplateTestCase.java [new file with mode: 0644]

diff --git a/python/resources/postfixTemplates/PyNotPostfixTemplate/after.py.template b/python/resources/postfixTemplates/PyNotPostfixTemplate/after.py.template
new file mode 100644 (file)
index 0000000..191818f
--- /dev/null
@@ -0,0 +1,3 @@
+def f(a) {
+  return not a
+}
\ No newline at end of file
diff --git a/python/resources/postfixTemplates/PyNotPostfixTemplate/before.py.template b/python/resources/postfixTemplates/PyNotPostfixTemplate/before.py.template
new file mode 100644 (file)
index 0000000..abcc6ca
--- /dev/null
@@ -0,0 +1,3 @@
+def f(a) {
+  return <spot>a</spot>$key
+}
\ No newline at end of file
diff --git a/python/resources/postfixTemplates/PyNotPostfixTemplate/description.html b/python/resources/postfixTemplates/PyNotPostfixTemplate/description.html
new file mode 100644 (file)
index 0000000..51d4183
--- /dev/null
@@ -0,0 +1,5 @@
+<html>
+<body>
+Negate the expression.
+</body>
+</html>
\ No newline at end of file
index 73499939e3de4263be9bca2baa5bab64c7fd4c03..f4c705450cb7656455538c737534b11505de0da9 100644 (file)
     <codeFoldingOptionsProvider instance="com.jetbrains.python.PythonFoldingOptionsProvider"/>
     <applicationService serviceInterface="com.jetbrains.python.PythonFoldingSettings"
                         serviceImplementation="com.jetbrains.python.PythonFoldingSettings"/>
+
+    <!-- postfix templates!-->
+    <codeInsight.template.postfixTemplateProvider language="Python"
+                                                  implementationClass="com.jetbrains.python.codeInsight.postfix.PyPostfixTemplateProvider"/>
   </extensions>
 
   <extensionPoints>
diff --git a/python/src/com/jetbrains/python/codeInsight/postfix/PyNotPostfixTemplate.java b/python/src/com/jetbrains/python/codeInsight/postfix/PyNotPostfixTemplate.java
new file mode 100644 (file)
index 0000000..024ff73
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000-2016 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.
+ */
+package com.jetbrains.python.codeInsight.postfix;
+
+import com.intellij.codeInsight.template.postfix.templates.NotPostfixTemplate;
+
+public class PyNotPostfixTemplate extends NotPostfixTemplate {
+  public PyNotPostfixTemplate() {
+    super("not", "." + "not", "not expr", PyPostfixUtils.PY_PSI_INFO, PyPostfixUtils.selectorAllExpressionsWithCurrentOffset());
+  }
+}
diff --git a/python/src/com/jetbrains/python/codeInsight/postfix/PyPostfixTemplateProvider.java b/python/src/com/jetbrains/python/codeInsight/postfix/PyPostfixTemplateProvider.java
new file mode 100644 (file)
index 0000000..9604810
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2000-2016 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.
+ */
+package com.jetbrains.python.codeInsight.postfix;
+
+import com.intellij.codeInsight.template.postfix.templates.PostfixTemplate;
+import com.intellij.codeInsight.template.postfix.templates.PostfixTemplateProvider;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.psi.PsiFile;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+
+public class PyPostfixTemplateProvider implements PostfixTemplateProvider {
+  @NotNull
+  @Override
+  public Set<PostfixTemplate> getTemplates() {
+    return ContainerUtil.<PostfixTemplate>newHashSet(new PyNotPostfixTemplate(),
+                                                     new PyParenthesizedExpressionPostfixTemplate());
+  }
+
+  @Override
+  public boolean isTerminalSymbol(char currentChar) {
+    return currentChar == '.'|| currentChar == '!';
+  }
+
+  @Override
+  public void preExpand(@NotNull PsiFile file, @NotNull Editor editor) {
+
+  }
+
+  @Override
+  public void afterExpand(@NotNull PsiFile file, @NotNull Editor editor) {
+
+  }
+
+  @NotNull
+  @Override
+  public PsiFile preCheck(@NotNull PsiFile copyFile, @NotNull Editor realEditor, int currentOffset) {
+    return copyFile;
+  }
+}
diff --git a/python/src/com/jetbrains/python/codeInsight/postfix/PyPostfixUtils.java b/python/src/com/jetbrains/python/codeInsight/postfix/PyPostfixUtils.java
new file mode 100644 (file)
index 0000000..dfce121
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2000-2016 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.
+ */
+package com.jetbrains.python.codeInsight.postfix;
+
+import com.intellij.codeInsight.template.postfix.templates.PostfixTemplateExpressionSelector;
+import com.intellij.codeInsight.template.postfix.templates.PostfixTemplateExpressionSelectorBase;
+import com.intellij.codeInsight.template.postfix.templates.PostfixTemplatePsiInfo;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Conditions;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.util.PsiUtilCore;
+import com.jetbrains.python.psi.*;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PyPostfixUtils {
+
+  private PyPostfixUtils() {
+  }
+
+  public static final PostfixTemplatePsiInfo PY_PSI_INFO = new PostfixTemplatePsiInfo() {
+    @NotNull
+    @Override
+    public PsiElement createExpression(@NotNull PsiElement context, @NotNull String prefix, @NotNull String suffix) {
+      String text = prefix + context.getText() + suffix;
+      return PyElementGenerator.getInstance(context.getProject()).createExpressionFromText(LanguageLevel.forElement(context), text);
+    }
+
+    @NotNull
+    @Override
+    public PsiElement getNegatedExpression(@NotNull PsiElement element) {
+      String newText = element instanceof PyBinaryExpression ? "(" + element.getText() + ")" : element.getText();
+      return PyElementGenerator.getInstance(element.getProject()).
+        createExpressionFromText(LanguageLevel.forElement(element), "not " + newText);
+    }
+  };
+
+
+  public static PostfixTemplateExpressionSelector selectorAllExpressionsWithCurrentOffset(final Condition<PsiElement> additionalFilter) {
+    return new PostfixTemplateExpressionSelectorBase(additionalFilter) {
+      @Override
+      protected List<PsiElement> getNonFilteredExpressions(@NotNull PsiElement context, @NotNull Document document, int newOffset) {
+        PsiElement elementAtCaret = PsiUtilCore.getElementAtOffset(context.getContainingFile(), newOffset - 1);
+        final List<PsiElement> expressions = new ArrayList<PsiElement>();
+        while (elementAtCaret != null) {
+          if (elementAtCaret instanceof PyStatement || elementAtCaret instanceof PyFile) {
+            break;
+          }
+          if (elementAtCaret instanceof PyExpression) {
+            expressions.add(elementAtCaret);
+          }
+          elementAtCaret = elementAtCaret.getParent();
+        }
+        return expressions;
+      }
+    };
+  }
+
+  public static PostfixTemplateExpressionSelector selectorAllExpressionsWithCurrentOffset() {
+    return selectorAllExpressionsWithCurrentOffset(Conditions.<PsiElement>alwaysTrue());
+  }
+}
diff --git a/python/testData/postfix/not/if.py b/python/testData/postfix/not/if.py
new file mode 100644 (file)
index 0000000..79de96e
--- /dev/null
@@ -0,0 +1,2 @@
+if a.not<caret>:
+    print(1)
\ No newline at end of file
diff --git a/python/testData/postfix/not/if_after.py b/python/testData/postfix/not/if_after.py
new file mode 100644 (file)
index 0000000..87d2c90
--- /dev/null
@@ -0,0 +1,2 @@
+if not a<caret>:
+    print(1)
\ No newline at end of file
diff --git a/python/testData/postfix/not/number.py b/python/testData/postfix/not/number.py
new file mode 100644 (file)
index 0000000..eadbf4d
--- /dev/null
@@ -0,0 +1 @@
+3.not<caret>
\ No newline at end of file
diff --git a/python/testData/postfix/not/number_after.py b/python/testData/postfix/not/number_after.py
new file mode 100644 (file)
index 0000000..0076b08
--- /dev/null
@@ -0,0 +1 @@
+not 3<caret>
\ No newline at end of file
diff --git a/python/testData/postfix/not/parenthesis.py b/python/testData/postfix/not/parenthesis.py
new file mode 100644 (file)
index 0000000..2eda0f5
--- /dev/null
@@ -0,0 +1,2 @@
+def f():
+    return True and False.not<caret>
\ No newline at end of file
diff --git a/python/testData/postfix/not/parenthesis_after.py b/python/testData/postfix/not/parenthesis_after.py
new file mode 100644 (file)
index 0000000..4653972
--- /dev/null
@@ -0,0 +1,2 @@
+def f():
+    return not (True and False)<caret>
\ No newline at end of file
diff --git a/python/testSrc/com/jetbrains/python/postfix/PyNotPostfixTemplateTest.java b/python/testSrc/com/jetbrains/python/postfix/PyNotPostfixTemplateTest.java
new file mode 100644 (file)
index 0000000..d1dfe1c
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2016 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.
+ */
+package com.jetbrains.python.postfix;
+
+public class PyNotPostfixTemplateTest extends PyPostfixTemplateTestCase {
+
+  public void testNumber() {
+    doTest();
+  }
+
+  public void testIf() {
+    doTest();
+  }
+
+  public void testParenthesis() {
+    doTest();
+  }
+
+  @Override
+  protected String getTestDataPath() {
+    return super.getTestDataPath() + "not/";
+  }
+}
diff --git a/python/testSrc/com/jetbrains/python/postfix/PyPostfixTemplateTestCase.java b/python/testSrc/com/jetbrains/python/postfix/PyPostfixTemplateTestCase.java
new file mode 100644 (file)
index 0000000..e3bd525
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2016 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.
+ */
+package com.jetbrains.python.postfix;
+
+import com.jetbrains.python.PythonTestUtil;
+import com.jetbrains.python.fixtures.PyTestCase;
+import org.jetbrains.annotations.NonNls;
+
+public abstract class PyPostfixTemplateTestCase extends PyTestCase {
+  protected void doTest() {
+    myFixture.configureByFile(getTestName(true) + ".py");
+    myFixture.type("\t");
+    myFixture.checkResultByFile(getTestName(true) + "_after" + ".py", true);
+  }
+
+  @Override
+  @NonNls
+  protected String getTestDataPath() {
+    return PythonTestUtil.getTestDataPath() + "/postfix/";
+  }
+}