Fixed according to reviews
authorIlya.Kazakevich <Ilya.Kazakevich@jetbrains.com>
Fri, 6 Nov 2015 22:28:20 +0000 (01:28 +0300)
committerIlya.Kazakevich <Ilya.Kazakevich@jetbrains.com>
Fri, 6 Nov 2015 22:28:20 +0000 (01:28 +0300)
python/psi-api/src/com/jetbrains/python/codeInsight/PyCustomMember.java
python/psi-api/src/com/jetbrains/python/nameResolver/NameResolverTools.java
python/psi-api/src/com/jetbrains/python/psi/PyCallExpression.java
python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java

index 543d635050d5073dc618af3930b136868f6df719..77218c6457fceaadba013143e3e3737591ed1eee 100644 (file)
@@ -17,11 +17,8 @@ package com.jetbrains.python.codeInsight;
 
 import com.intellij.extapi.psi.ASTWrapperPsiElement;
 import com.intellij.icons.AllIcons;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.UserDataHolderBase;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiReference;
-import com.intellij.psi.util.*;
 import com.intellij.util.Function;
 import com.jetbrains.python.psi.PyClass;
 import com.jetbrains.python.psi.PyFunction;
@@ -37,9 +34,7 @@ import javax.swing.*;
 /**
  * @author Dennis.Ushakov
  */
-public class PyCustomMember extends UserDataHolderBase {
-  private static final Key<ParameterizedCachedValue<PyClass, PsiElement>>
-    RESOLVE = Key.create("resolve");
+public class PyCustomMember {
   private final String myName;
   private final boolean myResolveToInstance;
   private final Function<PsiElement, PyType> myTypeCallback;
@@ -170,26 +165,14 @@ public class PyCustomMember extends UserDataHolderBase {
   }
 
   @Nullable
-  public PsiElement resolve(@NotNull final PsiElement context) {
-
+  public PsiElement resolve(@NotNull PsiElement context) {
     if (myTarget != null) {
       return myTarget;
     }
 
     PyClass targetClass = null;
     if (myTypeName != null) {
-
-      final ParameterizedCachedValueProvider<PyClass, PsiElement> provider = new ParameterizedCachedValueProvider<PyClass, PsiElement>() {
-        @Nullable
-        @Override
-        public CachedValueProvider.Result<PyClass> compute(
-          final PsiElement param) {
-          final PyClass result = PyPsiFacade.getInstance(param.getProject()).createClassByQName(myTypeName, param);
-          return CachedValueProvider.Result.create(result, PsiModificationTracker.MODIFICATION_COUNT);
-        }
-      };
-      targetClass = CachedValuesManager.getManager(context.getProject()).getParameterizedCachedValue(this, RESOLVE,
-                                                                                                     provider, false, context);
+      targetClass = PyPsiFacade.getInstance(context.getProject()).createClassByQName(myTypeName, context);
     }
     final PsiElement resolveTarget = findResolveTarget(context);
     if (resolveTarget instanceof PyFunction && !myAlwaysResolveToCustomElement) {
@@ -229,7 +212,6 @@ public class PyCustomMember extends UserDataHolderBase {
 
   /**
    * Checks if some reference points to this element
-   *
    * @param reference reference to check
    * @return true if reference points to it
    */
index 5118d2cd9edc288c1878e48632f4ab210471247b..86d52efc483a2aea61e7c14683735c7ce87a9716 100644 (file)
@@ -67,7 +67,8 @@ public final class NameResolverTools {
   }
 
   /**
-   * Checks if FQ element name is one of provided names
+   * Checks if FQ element name is one of provided names. May be <strong>heavy</strong>.
+   * It is always better to use less accurate but lighter {@link #isCalleeShortCut(PyCallExpression, FQNamesProvider, TypeEvalContext)}
    *
    * @param element        element to check
    * @param namesProviders some enum that has one or more names
@@ -117,10 +118,7 @@ public final class NameResolverTools {
    */
   public static boolean isCalleeShortCut(@NotNull final PyCallExpression call,
                                          @NotNull final FQNamesProvider function,
-                                         @Nullable final TypeEvalContext context) {
-    if (context == null) {
-      return call.isCallee(function);
-    }
+                                         @NotNull final TypeEvalContext context) {
     final PyExpression callee = call.getCallee();
     if (callee == null) {
       return false;
index da96e7e29b610003e6f370ddb37284bc61d7f1ed..4c5b6a1bd0f7be289d73a00206f03fa77da96f11 100644 (file)
@@ -19,6 +19,7 @@ import com.intellij.psi.PsiElement;
 import com.jetbrains.python.FunctionParameter;
 import com.jetbrains.python.nameResolver.FQNamesProvider;
 import com.jetbrains.python.psi.resolve.PyResolveContext;
+import com.jetbrains.python.psi.types.TypeEvalContext;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -74,7 +75,7 @@ public interface PyCallExpression extends PyCallSiteExpression {
    * Returns the argument if one is present in the list.
    *
    * @param parameter parameter
-   * @param argClass argument expected type
+   * @param argClass  argument expected type
    * @return the argument or null
    */
   @Nullable
@@ -85,6 +86,7 @@ public interface PyCallExpression extends PyCallSiteExpression {
 
   /**
    * TODO: Copy/Paste with {@link PyArgumentList#addArgument(PyExpression)}
+   *
    * @param expression
    */
   void addArgument(PyExpression expression);
@@ -110,7 +112,6 @@ public interface PyCallExpression extends PyCallSiteExpression {
   PyCallable resolveCalleeFunction(PyResolveContext resolveContext);
 
   /**
-   *
    * @param resolveContext the reference resolve context
    * @param implicitOffset known from the context implicit offset
    */
@@ -133,9 +134,13 @@ public interface PyCallExpression extends PyCallSiteExpression {
 
   /**
    * Checks if the qualified name of the callee matches any of the specified names provided by provider.
-   * @see com.jetbrains.python.nameResolver
+   * May be <strong>heavy</strong>.
+   * Use {@link com.jetbrains.python.nameResolver.NameResolverTools#isCalleeShortCut(PyCallExpression, FQNamesProvider, TypeEvalContext)}
+   * if you can.
+   *
    * @param name providers that provides one or more names to check
    * @return true if matches, false otherwise
+   * @see com.jetbrains.python.nameResolver
    */
   boolean isCallee(@NotNull FQNamesProvider... name);
 
@@ -243,8 +248,8 @@ public interface PyCallExpression extends PyCallSiteExpression {
 
     /**
      * @return number of implicitly passed positional parameters; 0 means no parameters are passed implicitly.
-     *         Note that a <tt>*args</tt> is never marked as passed implicitly.
-     *         E.g. for a function like <tt>foo(a, b, *args)</tt> always holds <tt>getImplicitOffset() < 2</tt>.
+     * Note that a <tt>*args</tt> is never marked as passed implicitly.
+     * E.g. for a function like <tt>foo(a, b, *args)</tt> always holds <tt>getImplicitOffset() < 2</tt>.
      */
     public int getImplicitOffset() {
       return myImplicitOffset;
index 7f7b91c58f46f605041b9b13983b78697772c61a..781391c9a2bf94ecd6fd6f6f92aa6bde0b68ae2c 100644 (file)
@@ -733,6 +733,11 @@ public class PyFunctionImpl extends PyBaseElementImpl<PyFunctionStub> implements
   @NotNull
   @Override
   public List<PyAssignmentStatement> findAttributes() {
+    /**
+     * TODO: This method if insanely heavy since it unstubs foreign files.
+     * Need to save stubs and use them somehow.
+     *
+     */
     return CachedValuesManager.getManager(getProject()).getCachedValue(this, ATTRIBUTES_KEY, new CachedValueProvider<List<PyAssignmentStatement>>() {
       @Nullable
       @Override