From 7c3504e1850752a910f865f0b736e4ff1b7b08ee Mon Sep 17 00:00:00 2001 From: Brendan Douglas Date: Mon, 7 Nov 2016 17:51:42 -0500 Subject: [PATCH] Add a custom python package identifier extension point Allows bypassing the default 'is package' check, giving the option of foregoing __init__.py files prior to python 3.3 --- .../python/psi/PyCustomPackageIdentifier.java | 38 +++++++++++++++++++ python/src/META-INF/python-core-common.xml | 3 +- .../src/com/jetbrains/python/psi/PyUtil.java | 10 +++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 python/psi-api/src/com/jetbrains/python/psi/PyCustomPackageIdentifier.java diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyCustomPackageIdentifier.java b/python/psi-api/src/com/jetbrains/python/psi/PyCustomPackageIdentifier.java new file mode 100644 index 000000000000..548c182ae298 --- /dev/null +++ b/python/psi-api/src/com/jetbrains/python/psi/PyCustomPackageIdentifier.java @@ -0,0 +1,38 @@ +/* + * 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.psi; + +import com.intellij.openapi.extensions.ExtensionPointName; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; + +public interface PyCustomPackageIdentifier { + ExtensionPointName EP_NAME = ExtensionPointName.create("Pythonid.customPackageIdentifier"); + + /** + * Checks whether the given PsiDirectory can be treated as Python package. + * Used to loosen the default package checking behavior in PyUtil#isPackage. + */ + boolean isPackage(PsiDirectory directory); + + /** + * Checks whether the given PsiFile is a python package file (i.e. an __init__.py file). + * Use to treat files other than __init__.py files as python package files. + */ + boolean isPackageFile(PsiFile file); +} + diff --git a/python/src/META-INF/python-core-common.xml b/python/src/META-INF/python-core-common.xml index ef66e76a77e2..05c699c4e901 100644 --- a/python/src/META-INF/python-core-common.xml +++ b/python/src/META-INF/python-core-common.xml @@ -647,6 +647,7 @@ + @@ -851,4 +852,4 @@ com.jetbrains.python.testing.VFSTestFrameworkListener - \ No newline at end of file + diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index 296d1f23ac5e..40c294df4d42 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -1000,6 +1000,11 @@ public class PyUtil { * @see PyNames#isIdentifier(String) */ public static boolean isPackage(@NotNull PsiDirectory directory, boolean checkSetupToolsPackages, @Nullable PsiElement anchor) { + for (PyCustomPackageIdentifier customPackageIdentifier : PyCustomPackageIdentifier.EP_NAME.getExtensions()) { + if (customPackageIdentifier.isPackage(directory)) { + return true; + } + } if (directory.findFile(PyNames.INIT_DOT_PY) != null) { return true; } @@ -1013,6 +1018,11 @@ public class PyUtil { } public static boolean isPackage(@NotNull PsiFile file) { + for (PyCustomPackageIdentifier customPackageIdentifier : PyCustomPackageIdentifier.EP_NAME.getExtensions()) { + if (customPackageIdentifier.isPackageFile(file)) { + return true; + } + } return PyNames.INIT_DOT_PY.equals(file.getName()); }