mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-12396 Fixed: Property getter live template is useful only inside python class
Separate Python liveTemplatesContext into two parts: General and Class
This commit is contained in:
@@ -8,7 +8,8 @@
|
||||
<option name="HTML" value="false" />
|
||||
<option name="XSL_TEXT" value="false" />
|
||||
<option name="XML" value="false" />
|
||||
<option name="Python" value="true" />
|
||||
<option name="Python" value="false" />
|
||||
<option name="Python_Class" value="true" />
|
||||
<option name="Django" value="false" />
|
||||
<option name="CSS_PROPERTY_VALUE" value="false" />
|
||||
<option name="CSS_DECLARATION_BLOCK" value="false" />
|
||||
@@ -272,7 +273,8 @@
|
||||
<option name="HTML" value="false" />
|
||||
<option name="XSL_TEXT" value="false" />
|
||||
<option name="XML" value="false" />
|
||||
<option name="Python" value="true" />
|
||||
<option name="Python" value="false" />
|
||||
<option name="Python_Class" value="true" />
|
||||
<option name="Django" value="false" />
|
||||
<option name="CSS_PROPERTY_VALUE" value="false" />
|
||||
<option name="CSS_DECLARATION_BLOCK" value="false" />
|
||||
@@ -292,7 +294,8 @@
|
||||
<option name="HTML" value="false" />
|
||||
<option name="XSL_TEXT" value="false" />
|
||||
<option name="XML" value="false" />
|
||||
<option name="Python" value="true" />
|
||||
<option name="Python" value="false" />
|
||||
<option name="Python_Class" value="true" />
|
||||
<option name="Django" value="false" />
|
||||
<option name="CSS_PROPERTY_VALUE" value="false" />
|
||||
<option name="CSS_DECLARATION_BLOCK" value="false" />
|
||||
@@ -312,7 +315,8 @@
|
||||
<option name="HTML" value="false" />
|
||||
<option name="XSL_TEXT" value="false" />
|
||||
<option name="XML" value="false" />
|
||||
<option name="Python" value="true" />
|
||||
<option name="Python" value="false" />
|
||||
<option name="Python_Class" value="true" />
|
||||
<option name="Django" value="false" />
|
||||
<option name="CSS_PROPERTY_VALUE" value="false" />
|
||||
<option name="CSS_DECLARATION_BLOCK" value="false" />
|
||||
|
||||
@@ -374,7 +374,9 @@
|
||||
<localInspection language="Python" shortName="PyPep8NamingInspection" suppressId="PyPep8Naming" displayName="PEP 8 naming convention violation" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyPep8NamingInspection"/>
|
||||
<localInspection language="Python" shortName="PyAssignmentToLoopOrWithParameterInspection" suppressId="PyAssignmentToLoopOrWithParameter" displayName="Assignment to 'for' loop or 'with' statement parameter" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyAssignmentToLoopOrWithParameterInspection"/>
|
||||
|
||||
<liveTemplateContext implementation="com.jetbrains.python.codeInsight.liveTemplates.PythonTemplateContextType"/>
|
||||
<defaultLiveTemplatesProvider implementation="com.jetbrains.python.codeInsight.liveTemplates.PyDefaultLiveTemplatesProvider"/>
|
||||
<liveTemplateContext implementation="com.jetbrains.python.codeInsight.liveTemplates.PythonTemplateContextType$General"/>
|
||||
<liveTemplateContext implementation="com.jetbrains.python.codeInsight.liveTemplates.PythonTemplateContextType$Class"/>
|
||||
<liveTemplateMacro implementation="com.jetbrains.python.codeInsight.liveTemplates.CollectionElementNameMacro"/>
|
||||
<liveTemplateMacro implementation="com.jetbrains.python.codeInsight.liveTemplates.PyClassNameMacro"/>
|
||||
<liveTemplateMacro implementation="com.jetbrains.python.codeInsight.liveTemplates.PyFunctionNameMacro"/>
|
||||
@@ -418,8 +420,6 @@
|
||||
serviceImplementation="com.jetbrains.python.sdk.PySdkService"/>
|
||||
<autoImportOptionsProvider instance="com.jetbrains.python.codeInsight.imports.PyAutoImportOptions"/>
|
||||
|
||||
<defaultLiveTemplatesProvider implementation="com.jetbrains.python.codeInsight.liveTemplates.PyDefaultLiveTemplatesProvider"/>
|
||||
|
||||
<completion.contributor language="Python"
|
||||
implementationClass="com.jetbrains.python.codeInsight.completion.PyClassNameCompletionContributor"/>
|
||||
<weigher key="completion" implementationClass="com.jetbrains.python.codeInsight.completion.PythonCompletionWeigher" order="first"/>
|
||||
|
||||
+50
-8
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -15,15 +15,18 @@
|
||||
*/
|
||||
package com.jetbrains.python.codeInsight.liveTemplates;
|
||||
|
||||
import com.intellij.codeInsight.template.FileTypeBasedContextType;
|
||||
import com.intellij.codeInsight.template.EverywhereContextType;
|
||||
import com.intellij.codeInsight.template.TemplateContextType;
|
||||
import com.intellij.patterns.PsiElementPattern;
|
||||
import com.intellij.psi.PsiComment;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.ProcessingContext;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.PythonFileType;
|
||||
import com.jetbrains.python.PythonLanguage;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyParameterList;
|
||||
import com.jetbrains.python.psi.PyStringLiteralExpression;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -33,22 +36,37 @@ import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class PythonTemplateContextType extends FileTypeBasedContextType {
|
||||
public PythonTemplateContextType() {
|
||||
super("Python", "Python", PythonFileType.INSTANCE);
|
||||
public abstract class PythonTemplateContextType extends TemplateContextType {
|
||||
|
||||
public PythonTemplateContextType(@NotNull String id,
|
||||
@NotNull String presentableName,
|
||||
@NotNull java.lang.Class<? extends TemplateContextType> baseContextType) {
|
||||
super(id, presentableName, baseContextType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInContext(@NotNull PsiFile file, int offset) {
|
||||
if (super.isInContext(file, offset)) {
|
||||
if (isPythonLanguage(file, offset)) {
|
||||
final PsiElement element = file.findElementAt(offset);
|
||||
|
||||
if (element != null) {
|
||||
return !(isAfterDot(element) || element instanceof PsiComment || isInsideStringLiteral(element) || isInsideParameterList(element));
|
||||
if (isAfterDot(element) || element instanceof PsiComment || isInsideStringLiteral(element) || isInsideParameterList(element)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return isInContext(element);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected abstract boolean isInContext(@NotNull PsiElement element);
|
||||
|
||||
private static boolean isPythonLanguage(@NotNull PsiFile file, int offset) {
|
||||
return PsiUtilCore.getLanguageAtOffset(file, offset).isKindOf(PythonLanguage.getInstance());
|
||||
}
|
||||
|
||||
private static boolean isInsideStringLiteral(@NotNull PsiElement element) {
|
||||
return PsiTreeUtil.getParentOfType(element, PyStringLiteralExpression.class, false) != null;
|
||||
}
|
||||
@@ -62,4 +80,28 @@ public class PythonTemplateContextType extends FileTypeBasedContextType {
|
||||
psiElement().withElementType(PyTokenTypes.DOT));
|
||||
return capture.accepts(element, new ProcessingContext());
|
||||
}
|
||||
|
||||
public static class General extends PythonTemplateContextType {
|
||||
|
||||
public General() {
|
||||
super("Python", "Python", EverywhereContextType.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInContext(@NotNull PsiElement element) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Class extends PythonTemplateContextType {
|
||||
|
||||
public Class() {
|
||||
super("Python_Class", "Class", General.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isInContext(@NotNull PsiElement element) {
|
||||
return PsiTreeUtil.getParentOfType(element, PyClass.class) != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
foo.<caret>
|
||||
@@ -0,0 +1,3 @@
|
||||
class C(object):
|
||||
p<caret>
|
||||
pass
|
||||
@@ -0,0 +1,2 @@
|
||||
p<caret>
|
||||
pass
|
||||
@@ -0,0 +1 @@
|
||||
# <caret>
|
||||
@@ -0,0 +1,2 @@
|
||||
def foo(a, <caret>):
|
||||
pass
|
||||
@@ -0,0 +1 @@
|
||||
"abc<caret>"
|
||||
@@ -0,0 +1,3 @@
|
||||
<html>
|
||||
<caret>
|
||||
</html>
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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.liveTemplates;
|
||||
|
||||
import com.intellij.codeInsight.template.TemplateContextType;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import com.jetbrains.python.fixtures.PyTestCase;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PyLiveTemplatesTest extends PyTestCase {
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return super.getTestDataPath() + "/codeInsight/liveTemplates/context/";
|
||||
}
|
||||
|
||||
public void testNotPython() {
|
||||
doTest(Collections.emptyList(), "html");
|
||||
}
|
||||
|
||||
// PY-12212
|
||||
public void testAfterDot() {
|
||||
doTest(Collections.emptyList());
|
||||
}
|
||||
|
||||
// PY-13076
|
||||
public void testInComment() {
|
||||
doTest(Collections.emptyList());
|
||||
}
|
||||
|
||||
// PY-12349
|
||||
public void testInStringLiteral() {
|
||||
doTest(Collections.emptyList());
|
||||
}
|
||||
|
||||
// PY-12395
|
||||
public void testInParameterList() {
|
||||
doTest(Collections.emptyList());
|
||||
}
|
||||
|
||||
public void testGeneral() {
|
||||
doTest(
|
||||
Collections.singletonList(PythonTemplateContextType.General.class)
|
||||
);
|
||||
}
|
||||
|
||||
// PY-12396
|
||||
public void testClass() {
|
||||
doTest(
|
||||
Arrays.asList(PythonTemplateContextType.Class.class, PythonTemplateContextType.General.class)
|
||||
);
|
||||
}
|
||||
|
||||
private void doTest(@NotNull List<Class<? extends PythonTemplateContextType>> expectedContextTypes) {
|
||||
doTest(expectedContextTypes, "py");
|
||||
}
|
||||
|
||||
private void doTest(@NotNull List<Class<? extends PythonTemplateContextType>> expectedContextTypes, @NotNull String extension) {
|
||||
myFixture.configureByFile(getTestName(true) + "." + extension);
|
||||
|
||||
UsefulTestCase.assertSameElements(
|
||||
calculateEnabledContextTypes(getRegisteredContextTypes()),
|
||||
expectedContextTypes
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<Class<? extends PythonTemplateContextType>> calculateEnabledContextTypes(@NotNull List<PythonTemplateContextType> registeredContextTypes) {
|
||||
//noinspection Convert2MethodRef
|
||||
return registeredContextTypes
|
||||
.stream()
|
||||
.filter(type -> type.isInContext(myFixture.getFile(), myFixture.getCaretOffset()))
|
||||
.map(type -> type.getClass())
|
||||
.sorted((o1, o2) -> o1.getSimpleName().compareTo(o2.getSimpleName()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<PythonTemplateContextType> getRegisteredContextTypes() {
|
||||
return Arrays
|
||||
.stream(TemplateContextType.EP_NAME.getExtensions())
|
||||
.filter(type -> type instanceof PythonTemplateContextType)
|
||||
.map(type -> (PythonTemplateContextType)type)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user