Exemplo n.º 1
0
 @Nullable
 @Deprecated // Use JetPsiUtil.deparenthesize() or ExpressionTypingServices.deparenthesize()
 public static JetExpression deparenthesizeWithResolutionStrategy(
     @Nullable JetExpression expression,
     boolean deparenthesizeBinaryExpressionWithTypeRHS,
     @Nullable Function<JetTypeReference, Void> typeResolutionStrategy) {
   if (deparenthesizeBinaryExpressionWithTypeRHS
       && expression instanceof JetBinaryExpressionWithTypeRHS) {
     JetBinaryExpressionWithTypeRHS binaryExpression = (JetBinaryExpressionWithTypeRHS) expression;
     JetSimpleNameExpression operationSign = binaryExpression.getOperationReference();
     if (JetTokens.COLON.equals(operationSign.getReferencedNameElementType())) {
       expression = binaryExpression.getLeft();
       JetTypeReference typeReference = binaryExpression.getRight();
       if (typeResolutionStrategy != null && typeReference != null) {
         typeResolutionStrategy.apply(typeReference);
       }
     }
   } else if (expression instanceof JetPrefixExpression) {
     JetExpression baseExpression =
         getBaseExpressionIfLabeledExpression((JetPrefixExpression) expression);
     if (baseExpression != null) {
       expression = baseExpression;
     }
   } else if (expression instanceof JetExpressionWrapper) {
     expression = ((JetExpressionWrapper) expression).getBaseExpression();
   }
   if (expression instanceof JetParenthesizedExpression) {
     JetExpression innerExpression = ((JetParenthesizedExpression) expression).getExpression();
     return innerExpression != null
         ? deparenthesizeWithResolutionStrategy(
             innerExpression, deparenthesizeBinaryExpressionWithTypeRHS, typeResolutionStrategy)
         : null;
   }
   return expression;
 }
Exemplo n.º 2
0
 @Nullable
 public static JetToken getOperationToken(@NotNull JetOperationExpression expression) {
   JetSimpleNameExpression operationExpression = expression.getOperationReference();
   IElementType elementType = operationExpression.getReferencedNameElementType();
   assert elementType == null || elementType instanceof JetToken
       : "JetOperationExpression should have operation token of type JetToken: " + expression;
   return (JetToken) elementType;
 }
Exemplo n.º 3
0
  @Nullable
  public static Name getAliasName(@NotNull JetImportDirective importDirective) {
    String aliasName = importDirective.getAliasName();
    JetExpression importedReference = importDirective.getImportedReference();
    if (importedReference == null) {
      return null;
    }
    JetSimpleNameExpression referenceExpression = getLastReference(importedReference);
    if (aliasName == null) {
      aliasName = referenceExpression != null ? referenceExpression.getReferencedName() : null;
    }

    return aliasName != null && !aliasName.isEmpty() ? Name.identifier(aliasName) : null;
  }
Exemplo n.º 4
0
  // TODO: Make it work for properties
  public Collection<DeclarationDescriptor> getJetCallableExtensions(
      @NotNull Condition<String> acceptedNameCondition,
      @NotNull JetSimpleNameExpression expression,
      @NotNull ResolveSession resolveSession,
      @NotNull GlobalSearchScope searchScope) {
    Collection<DeclarationDescriptor> resultDescriptors = new ArrayList<DeclarationDescriptor>();

    BindingContext context = ResolveSessionUtils.resolveToExpression(resolveSession, expression);
    JetExpression receiverExpression = expression.getReceiverExpression();

    if (receiverExpression != null) {
      JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
      JetScope scope = context.get(BindingContext.RESOLUTION_SCOPE, receiverExpression);

      if (expressionType != null && scope != null) {
        Collection<String> extensionFunctionsNames = getAllJetExtensionFunctionsNames(searchScope);

        Set<FqName> functionFQNs = new java.util.HashSet<FqName>();

        // Collect all possible extension function qualified names
        for (String name : extensionFunctionsNames) {
          if (acceptedNameCondition.value(name)) {
            Collection<PsiElement> extensionFunctions =
                getJetExtensionFunctionsByName(name, searchScope);

            for (PsiElement extensionFunction : extensionFunctions) {
              if (extensionFunction instanceof JetNamedFunction) {
                functionFQNs.add(JetPsiUtil.getFQName((JetNamedFunction) extensionFunction));
              } else if (extensionFunction instanceof PsiMethod) {
                FqName functionFQN =
                    JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN(
                        (PsiMethod) extensionFunction);
                if (functionFQN != null) {
                  functionFQNs.add(functionFQN);
                }
              }
            }
          }
        }

        // Iterate through the function with attempt to resolve found functions
        for (FqName functionFQN : functionFQNs) {
          for (CallableDescriptor functionDescriptor :
              ExpressionTypingUtils.canFindSuitableCall(
                  functionFQN,
                  project,
                  receiverExpression,
                  expressionType,
                  scope,
                  resolveSession.getModuleConfiguration())) {

            resultDescriptors.add(functionDescriptor);
          }
        }
      }
    }

    return resultDescriptors;
  }
Exemplo n.º 5
0
  @Nullable
  public static Name getConventionName(@NotNull JetSimpleNameExpression simpleNameExpression) {
    if (simpleNameExpression.getIdentifier() != null) {
      return simpleNameExpression.getReferencedNameAsName();
    }

    PsiElement firstChild = simpleNameExpression.getFirstChild();
    if (firstChild != null) {
      IElementType elementType = firstChild.getNode().getElementType();
      if (elementType instanceof JetToken) {
        JetToken jetToken = (JetToken) elementType;
        return OperatorConventions.getNameForOperationSymbol(jetToken);
      }
    }

    return null;
  }
Exemplo n.º 6
0
  @Nullable
  private static FqName getFQName(@Nullable JetExpression expression) {
    if (expression == null) {
      return null;
    }

    if (expression instanceof JetDotQualifiedExpression) {
      JetDotQualifiedExpression dotQualifiedExpression = (JetDotQualifiedExpression) expression;
      FqName parentFqn = getFQName(dotQualifiedExpression.getReceiverExpression());
      Name child = getName(dotQualifiedExpression.getSelectorExpression());

      return parentFqn != null && child != null ? parentFqn.child(child) : null;
    } else if (expression instanceof JetSimpleNameExpression) {
      JetSimpleNameExpression simpleNameExpression = (JetSimpleNameExpression) expression;
      return FqName.topLevel(simpleNameExpression.getReferencedNameAsName());
    } else {
      throw new IllegalArgumentException(
          "Can't construct fqn for: " + expression.getClass().toString());
    }
  }
Exemplo n.º 7
0
  public static boolean isSelectorInQualified(@NotNull JetSimpleNameExpression nameExpression) {
    PsiElement nameExpressionParent = nameExpression.getParent();

    if (nameExpressionParent instanceof JetUserType) {
      assert ((JetUserType) nameExpressionParent).getReferenceExpression() == nameExpression;
      return ((JetUserType) nameExpressionParent).getQualifier() != null;
    }

    JetExpression selector = nameExpression;
    if (nameExpressionParent instanceof JetCallExpression
        && ((JetCallExpression) nameExpressionParent).getCalleeExpression() == nameExpression) {
      selector = (JetCallExpression) nameExpressionParent;
    }

    PsiElement selectorParent = selector.getParent();
    return selectorParent instanceof JetQualifiedExpression
        && (((JetQualifiedExpression) selectorParent).getSelectorExpression() == selector);
  }
  private static JetValueArgumentList findCall(CreateParameterInfoContext context) {
    // todo: calls to this constructors, when we will have auxiliary constructors
    PsiFile file = context.getFile();
    if (!(file instanceof JetFile)) {
      return null;
    }

    JetValueArgumentList argumentList =
        PsiTreeUtil.getParentOfType(
            file.findElementAt(context.getOffset()), JetValueArgumentList.class);
    if (argumentList == null) {
      return null;
    }

    final JetSimpleNameExpression callNameExpression = getCallSimpleNameExpression(argumentList);
    if (callNameExpression == null) {
      return null;
    }

    PsiReference[] references = callNameExpression.getReferences();
    if (references.length == 0) {
      return null;
    }

    ResolutionFacade resolutionFacade =
        ResolvePackage.getResolutionFacade(callNameExpression.getContainingJetFile());
    final BindingContext bindingContext =
        resolutionFacade.analyze(callNameExpression, BodyResolveMode.FULL);
    ModuleDescriptor moduleDescriptor = resolutionFacade.findModuleDescriptor(callNameExpression);

    JetScope scope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, callNameExpression);
    final DeclarationDescriptor placeDescriptor;
    if (scope != null) {
      placeDescriptor = scope.getContainingDeclaration();
    } else {
      placeDescriptor = null;
    }
    Function1<DeclarationDescriptor, Boolean> visibilityFilter =
        new Function1<DeclarationDescriptor, Boolean>() {
          @Override
          public Boolean invoke(DeclarationDescriptor descriptor) {
            if (placeDescriptor == null) return true;
            if (!(descriptor instanceof DeclarationDescriptorWithVisibility)) return true;
            return CorePackage.isVisible(
                (DeclarationDescriptorWithVisibility) descriptor,
                placeDescriptor,
                bindingContext,
                callNameExpression);
          }
        };

    final Name refName = callNameExpression.getReferencedNameAsName();

    Function1<Name, Boolean> nameFilter =
        new Function1<Name, Boolean>() {
          @Override
          public Boolean invoke(Name name) {
            return name.equals(refName);
          }
        };
    Collection<DeclarationDescriptor> variants =
        new ReferenceVariantsHelper(
                bindingContext, moduleDescriptor, file.getProject(), visibilityFilter)
            .getReferenceVariants(
                callNameExpression,
                new DescriptorKindFilter(
                    DescriptorKindFilter.FUNCTIONS_MASK | DescriptorKindFilter.CLASSIFIERS_MASK,
                    Collections.<DescriptorKindExclude>emptyList()),
                nameFilter,
                false,
                false);

    Collection<Pair<? extends DeclarationDescriptor, ResolutionFacade>> itemsToShow =
        new ArrayList<Pair<? extends DeclarationDescriptor, ResolutionFacade>>();
    for (DeclarationDescriptor variant : variants) {
      if (variant instanceof FunctionDescriptor) {
        // todo: renamed functions?
        itemsToShow.add(Pair.create((FunctionDescriptor) variant, resolutionFacade));
      } else if (variant instanceof ClassDescriptor) {
        // todo: renamed classes?
        for (ConstructorDescriptor constructorDescriptor :
            ((ClassDescriptor) variant).getConstructors()) {
          itemsToShow.add(Pair.create(constructorDescriptor, resolutionFacade));
        }
      }
    }

    context.setItemsToShow(ArrayUtil.toObjectArray(itemsToShow));
    return argumentList;
  }
  @Override
  public void updateUI(
      Pair<? extends FunctionDescriptor, ResolutionFacade> itemToShow,
      @NotNull ParameterInfoUIContext context) {
    // todo: when we will have ability to pass Array as vararg, implement such feature here too?
    if (context == null
        || context.getParameterOwner() == null
        || !context.getParameterOwner().isValid()) {
      context.setUIComponentEnabled(false);
      return;
    }

    PsiElement parameterOwner = context.getParameterOwner();
    if (!(parameterOwner instanceof JetValueArgumentList)) {
      context.setUIComponentEnabled(false);
      return;
    }

    JetValueArgumentList argumentList = (JetValueArgumentList) parameterOwner;

    FunctionDescriptor functionDescriptor = itemToShow.first;
    ResolutionFacade resolutionFacade = itemToShow.second;

    List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters();
    List<JetValueArgument> valueArguments = argumentList.getArguments();

    int currentParameterIndex = context.getCurrentParameterIndex();
    int boldStartOffset = -1;
    int boldEndOffset = -1;
    boolean isGrey = false;
    boolean isDeprecated = KotlinBuiltIns.isDeprecated(functionDescriptor);

    boolean[] usedIndexes = new boolean[valueParameters.size()];
    Arrays.fill(usedIndexes, false);

    boolean namedMode = false;

    if (!isIndexValid(valueParameters, currentParameterIndex)) {
      isGrey = true;
    }

    StringBuilder builder = new StringBuilder();

    PsiElement owner = context.getParameterOwner();
    BindingContext bindingContext =
        resolutionFacade.analyze((JetElement) owner, BodyResolveMode.FULL);

    for (int i = 0; i < valueParameters.size(); ++i) {
      if (i != 0) {
        builder.append(", ");
      }

      boolean highlightParameter =
          i == currentParameterIndex
              || (!namedMode
                  && i < currentParameterIndex
                  && Iterables.getLast(valueParameters).getVarargElementType() != null);

      if (highlightParameter) {
        boldStartOffset = builder.length();
      }

      if (!namedMode) {
        if (valueArguments.size() > i) {
          JetValueArgument argument = valueArguments.get(i);
          if (argument.isNamed()) {
            namedMode = true;
          } else {
            ValueParameterDescriptor param = valueParameters.get(i);
            builder.append(renderParameter(param, false));
            if (i <= currentParameterIndex
                && !isArgumentTypeValid(bindingContext, argument, param)) {
              isGrey = true;
            }
            usedIndexes[i] = true;
          }
        } else {
          ValueParameterDescriptor param = valueParameters.get(i);
          builder.append(renderParameter(param, false));
        }
      }

      if (namedMode) {
        boolean takeAnyArgument = true;
        if (valueArguments.size() > i) {
          JetValueArgument argument = valueArguments.get(i);
          if (argument.isNamed()) {
            for (int j = 0; j < valueParameters.size(); ++j) {
              JetSimpleNameExpression referenceExpression =
                  argument.getArgumentName().getReferenceExpression();
              ValueParameterDescriptor param = valueParameters.get(j);
              if (referenceExpression != null
                  && !usedIndexes[j]
                  && param.getName().equals(referenceExpression.getReferencedNameAsName())) {
                takeAnyArgument = false;
                usedIndexes[j] = true;
                builder.append(renderParameter(param, true));
                if (i < currentParameterIndex
                    && !isArgumentTypeValid(bindingContext, argument, param)) {
                  isGrey = true;
                }
                break;
              }
            }
          }
        }

        if (takeAnyArgument) {
          if (i < currentParameterIndex) {
            isGrey = true;
          }

          for (int j = 0; j < valueParameters.size(); ++j) {
            ValueParameterDescriptor param = valueParameters.get(j);
            if (!usedIndexes[j]) {
              usedIndexes[j] = true;
              builder.append(renderParameter(param, true));
              break;
            }
          }
        }
      }

      if (highlightParameter) {
        boldEndOffset = builder.length();
      }
    }

    if (valueParameters.size() == 0) {
      builder.append(CodeInsightBundle.message("parameter.info.no.parameters"));
    }

    assert !builder.toString().isEmpty()
        : "A message about 'no parameters' or some parameters should be present: "
            + functionDescriptor;

    Color color =
        isResolvedToDescriptor(argumentList, functionDescriptor, bindingContext)
            ? GREEN_BACKGROUND
            : context.getDefaultParameterColor();
    context.setupUIComponentPresentation(
        builder.toString(), boldStartOffset, boldEndOffset, isGrey, isDeprecated, false, color);
  }
 private static JetValueArgumentList findCall(CreateParameterInfoContext context) {
   // todo: calls to this constructors, when we will have auxiliary constructors
   PsiFile file = context.getFile();
   if (!(file instanceof JetFile)) return null;
   PsiElement element = file.findElementAt(context.getOffset());
   while (element != null && !(element instanceof JetValueArgumentList)) {
     element = element.getParent();
   }
   if (element == null) return null;
   JetValueArgumentList argumentList = (JetValueArgumentList) element;
   JetCallElement callExpression;
   if (element.getParent() instanceof JetCallElement) {
     callExpression = (JetCallElement) element.getParent();
   } else {
     return null;
   }
   BindingContext bindingContext = AnalyzeSingleFileUtil.getContextForSingleFile((JetFile) file);
   JetExpression calleeExpression = callExpression.getCalleeExpression();
   if (calleeExpression == null) return null;
   JetSimpleNameExpression refExpression = null;
   if (calleeExpression instanceof JetSimpleNameExpression) {
     refExpression = (JetSimpleNameExpression) calleeExpression;
   } else if (calleeExpression instanceof JetConstructorCalleeExpression) {
     JetConstructorCalleeExpression constructorCalleeExpression =
         (JetConstructorCalleeExpression) calleeExpression;
     if (constructorCalleeExpression.getConstructorReferenceExpression()
         instanceof JetSimpleNameExpression) {
       refExpression =
           (JetSimpleNameExpression)
               constructorCalleeExpression.getConstructorReferenceExpression();
     }
   }
   if (refExpression != null) {
     JetScope scope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, refExpression);
     DeclarationDescriptor placeDescriptor = null;
     if (scope != null) {
       placeDescriptor = scope.getContainingDeclaration();
     }
     Collection<DeclarationDescriptor> variants =
         TipsManager.getReferenceVariants(refExpression, bindingContext);
     Name refName = refExpression.getReferencedNameAsName();
     PsiReference[] references = refExpression.getReferences();
     if (references.length == 0) return null;
     ArrayList<DeclarationDescriptor> itemsToShow = new ArrayList<DeclarationDescriptor>();
     for (DeclarationDescriptor variant : variants) {
       if (variant instanceof FunctionDescriptor) {
         FunctionDescriptor functionDescriptor = (FunctionDescriptor) variant;
         if (functionDescriptor.getName().equals(refName)) {
           // todo: renamed functions?
           if (placeDescriptor != null
               && !JetVisibilityChecker.isVisible(placeDescriptor, functionDescriptor)) continue;
           itemsToShow.add(functionDescriptor);
         }
       } else if (variant instanceof ClassDescriptor) {
         ClassDescriptor classDescriptor = (ClassDescriptor) variant;
         if (classDescriptor.getName().equals(refName)) {
           // todo: renamed classes?
           for (ConstructorDescriptor constructorDescriptor : classDescriptor.getConstructors()) {
             if (placeDescriptor != null
                 && !JetVisibilityChecker.isVisible(placeDescriptor, constructorDescriptor))
               continue;
             itemsToShow.add(constructorDescriptor);
           }
         }
       }
     }
     context.setItemsToShow(ArrayUtil.toObjectArray(itemsToShow));
     return argumentList;
   }
   return null;
 }
  @Override
  public void updateUI(Object descriptor, ParameterInfoUIContext context) {
    // todo: when we will have ability to pass Array as vararg, implement such feature here too?
    if (context == null
        || context.getParameterOwner() == null
        || !context.getParameterOwner().isValid()) {
      return;
    }
    PsiElement parameterOwner = context.getParameterOwner();
    if (parameterOwner instanceof JetValueArgumentList) {
      JetValueArgumentList argumentList = (JetValueArgumentList) parameterOwner;
      if (descriptor instanceof FunctionDescriptor) {
        JetFile file = (JetFile) argumentList.getContainingFile();
        BindingContext bindingContext = AnalyzeSingleFileUtil.getContextForSingleFile(file);
        FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
        StringBuilder builder = new StringBuilder();
        List<ValueParameterDescriptor> valueParameters = functionDescriptor.getValueParameters();
        List<JetValueArgument> valueArguments = argumentList.getArguments();
        int currentParameterIndex = context.getCurrentParameterIndex();
        int boldStartOffset = -1;
        int boldEndOffset = -1;
        boolean isGrey = false;
        boolean isDeprecated = false; // todo: add deprecation check
        Color color = context.getDefaultParameterColor();
        PsiElement parent = argumentList.getParent();
        if (parent instanceof JetCallElement) {
          JetCallElement callExpression = (JetCallElement) parent;
          JetExpression calleeExpression = callExpression.getCalleeExpression();
          JetSimpleNameExpression refExpression = null;
          if (calleeExpression instanceof JetSimpleNameExpression) {
            refExpression = (JetSimpleNameExpression) calleeExpression;
          } else if (calleeExpression instanceof JetConstructorCalleeExpression) {
            JetConstructorCalleeExpression constructorCalleeExpression =
                (JetConstructorCalleeExpression) calleeExpression;
            if (constructorCalleeExpression.getConstructorReferenceExpression()
                instanceof JetSimpleNameExpression) {
              refExpression =
                  (JetSimpleNameExpression)
                      constructorCalleeExpression.getConstructorReferenceExpression();
            }
          }
          if (refExpression != null) {
            DeclarationDescriptor declarationDescriptor =
                bindingContext.get(BindingContext.REFERENCE_TARGET, refExpression);
            if (declarationDescriptor != null) {
              if (declarationDescriptor == functionDescriptor) {
                color = GREEN_BACKGROUND;
              }
            }
          }
        }

        boolean[] usedIndexes = new boolean[valueParameters.size()];
        boolean namedMode = false;
        Arrays.fill(usedIndexes, false);
        if ((currentParameterIndex >= valueParameters.size()
                && (valueParameters.size() > 0 || currentParameterIndex > 0))
            && (valueParameters.size() == 0
                || valueParameters.get(valueParameters.size() - 1).getVarargElementType()
                    == null)) {
          isGrey = true;
        }
        if (valueParameters.size() == 0)
          builder.append(CodeInsightBundle.message("parameter.info.no.parameters"));
        for (int i = 0; i < valueParameters.size(); ++i) {
          if (i != 0) builder.append(", ");
          boolean highlightParameter =
              i == currentParameterIndex
                  || (!namedMode
                      && i < currentParameterIndex
                      && valueParameters.get(valueParameters.size() - 1).getVarargElementType()
                          != null);
          if (highlightParameter) boldStartOffset = builder.length();
          if (!namedMode) {
            if (valueArguments.size() > i) {
              JetValueArgument argument = valueArguments.get(i);
              if (argument.isNamed()) {
                namedMode = true;
              } else {
                ValueParameterDescriptor param = valueParameters.get(i);
                builder.append(renderParameter(param, false, bindingContext));
                if (i < currentParameterIndex) {
                  if (argument.getArgumentExpression() != null) {
                    // check type
                    JetType paramType = getActualParameterType(param);
                    JetType exprType =
                        bindingContext.get(
                            BindingContext.EXPRESSION_TYPE, argument.getArgumentExpression());
                    if (exprType != null
                        && !JetTypeChecker.INSTANCE.isSubtypeOf(exprType, paramType)) isGrey = true;
                  } else isGrey = true;
                }
                usedIndexes[i] = true;
              }
            } else {
              ValueParameterDescriptor param = valueParameters.get(i);
              builder.append(renderParameter(param, false, bindingContext));
            }
          }
          if (namedMode) {
            boolean takeAnyArgument = true;
            if (valueArguments.size() > i) {
              JetValueArgument argument = valueArguments.get(i);
              if (argument.isNamed()) {
                for (int j = 0; j < valueParameters.size(); ++j) {
                  JetSimpleNameExpression referenceExpression =
                      argument.getArgumentName().getReferenceExpression();
                  ValueParameterDescriptor param = valueParameters.get(j);
                  if (referenceExpression != null
                      && !usedIndexes[j]
                      && param.getName().equals(referenceExpression.getReferencedNameAsName())) {
                    takeAnyArgument = false;
                    usedIndexes[j] = true;
                    builder.append(renderParameter(param, true, bindingContext));
                    if (i < currentParameterIndex) {
                      if (argument.getArgumentExpression() != null) {
                        // check type
                        JetType paramType = getActualParameterType(param);
                        JetType exprType =
                            bindingContext.get(
                                BindingContext.EXPRESSION_TYPE, argument.getArgumentExpression());
                        if (exprType != null
                            && !JetTypeChecker.INSTANCE.isSubtypeOf(exprType, paramType))
                          isGrey = true;
                      } else isGrey = true;
                    }
                    break;
                  }
                }
              }
            }

            if (takeAnyArgument) {
              if (i < currentParameterIndex) isGrey = true;

              for (int j = 0; j < valueParameters.size(); ++j) {
                ValueParameterDescriptor param = valueParameters.get(j);
                if (!usedIndexes[j]) {
                  usedIndexes[j] = true;
                  builder.append(renderParameter(param, true, bindingContext));
                  break;
                }
              }
            }
          }
          if (highlightParameter) boldEndOffset = builder.length();
        }
        if (builder.toString().isEmpty()) context.setUIComponentEnabled(false);
        else
          context.setupUIComponentPresentation(
              builder.toString(),
              boldStartOffset,
              boldEndOffset,
              isGrey,
              isDeprecated,
              false,
              color);
      } else context.setUIComponentEnabled(false);
    }
  }
Exemplo n.º 12
0
  @NotNull
  public Collection<FunctionDescriptor> getTopLevelFunctionDescriptorsByName(
      @NotNull String name,
      @NotNull JetSimpleNameExpression expression,
      @NotNull ResolveSession resolveSession,
      @NotNull GlobalSearchScope scope) {
    // name parameter can differ from expression.getReferenceName() when expression contains
    // completion suffix
    Name referenceName =
        expression.getIdentifier() == null
            ? JetPsiUtil.getConventionName(expression)
            : Name.identifier(name);
    if (referenceName == null || referenceName.toString().isEmpty()) {
      return Collections.emptyList();
    }

    BindingContext context = ResolveSessionUtils.resolveToExpression(resolveSession, expression);
    JetScope jetScope = context.get(BindingContext.RESOLUTION_SCOPE, expression);

    if (jetScope == null) {
      return Collections.emptyList();
    }

    Set<FunctionDescriptor> result = Sets.newHashSet();

    Collection<PsiMethod> topLevelFunctionPrototypes =
        JetFromJavaDescriptorHelper.getTopLevelFunctionPrototypesByName(
            referenceName.getName(), project, scope);
    for (PsiMethod method : topLevelFunctionPrototypes) {
      FqName functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN(method);
      if (functionFQN != null) {
        JetImportDirective importDirective =
            JetPsiFactory.createImportDirective(project, new ImportPath(functionFQN, false));
        Collection<? extends DeclarationDescriptor> declarationDescriptors =
            new QualifiedExpressionResolver()
                .analyseImportReference(
                    importDirective,
                    jetScope,
                    new BindingTraceContext(),
                    resolveSession.getModuleConfiguration());
        for (DeclarationDescriptor declarationDescriptor : declarationDescriptors) {
          if (declarationDescriptor instanceof FunctionDescriptor) {
            result.add((FunctionDescriptor) declarationDescriptor);
          }
        }
      }
    }

    Set<FqName> affectedPackages = Sets.newHashSet();
    Collection<JetNamedFunction> jetNamedFunctions =
        JetShortFunctionNameIndex.getInstance().get(referenceName.getName(), project, scope);
    for (JetNamedFunction jetNamedFunction : jetNamedFunctions) {
      PsiFile containingFile = jetNamedFunction.getContainingFile();
      if (containingFile instanceof JetFile) {
        JetFile jetFile = (JetFile) containingFile;
        String packageName = jetFile.getPackageName();
        if (packageName != null) {
          affectedPackages.add(new FqName(packageName));
        }
      }
    }

    for (FqName affectedPackage : affectedPackages) {
      NamespaceDescriptor packageDescriptor =
          resolveSession.getPackageDescriptorByFqName(affectedPackage);
      assert packageDescriptor != null
          : "There's a function in stub index with invalid package: " + affectedPackage;
      JetScope memberScope = packageDescriptor.getMemberScope();
      result.addAll(memberScope.getFunctions(referenceName));
    }

    return result;
  }
Exemplo n.º 13
0
 public static boolean isBackingFieldReference(@NotNull JetSimpleNameExpression expression) {
   return expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER;
 }
  private static JetValueArgumentList findCall(CreateParameterInfoContext context) {
    // todo: calls to this constructors, when we will have auxiliary constructors
    PsiFile file = context.getFile();
    if (!(file instanceof JetFile)) {
      return null;
    }

    JetValueArgumentList argumentList =
        PsiTreeUtil.getParentOfType(
            file.findElementAt(context.getOffset()), JetValueArgumentList.class);
    if (argumentList == null) {
      return null;
    }

    JetSimpleNameExpression callNameExpression = getCallSimpleNameExpression(argumentList);
    if (callNameExpression == null) {
      return null;
    }

    PsiReference[] references = callNameExpression.getReferences();
    if (references.length == 0) {
      return null;
    }

    CancelableResolveSession resolveSession =
        WholeProjectAnalyzerFacade.getLazyResolveResultForFile(
            (JetFile) callNameExpression.getContainingFile());
    BindingContext bindingContext = resolveSession.resolveToElement(callNameExpression);

    JetScope scope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, callNameExpression);
    DeclarationDescriptor placeDescriptor = null;
    if (scope != null) {
      placeDescriptor = scope.getContainingDeclaration();
    }

    Collection<DeclarationDescriptor> variants =
        TipsManager.getReferenceVariants(callNameExpression, bindingContext);

    Name refName = callNameExpression.getReferencedNameAsName();

    Collection<Pair<? extends DeclarationDescriptor, CancelableResolveSession>> itemsToShow =
        new ArrayList<Pair<? extends DeclarationDescriptor, CancelableResolveSession>>();
    for (DeclarationDescriptor variant : variants) {
      if (variant instanceof FunctionDescriptor) {
        FunctionDescriptor functionDescriptor = (FunctionDescriptor) variant;
        if (functionDescriptor.getName().equals(refName)) {
          // todo: renamed functions?
          if (placeDescriptor != null
              && !JetVisibilityChecker.isVisible(placeDescriptor, functionDescriptor)) {
            continue;
          }
          itemsToShow.add(Pair.create(functionDescriptor, resolveSession));
        }
      } else if (variant instanceof ClassDescriptor) {
        ClassDescriptor classDescriptor = (ClassDescriptor) variant;
        if (classDescriptor.getName().equals(refName)) {
          // todo: renamed classes?
          for (ConstructorDescriptor constructorDescriptor : classDescriptor.getConstructors()) {
            if (placeDescriptor != null
                && !JetVisibilityChecker.isVisible(placeDescriptor, constructorDescriptor)) {
              continue;
            }
            itemsToShow.add(Pair.create(constructorDescriptor, resolveSession));
          }
        }
      }
    }

    context.setItemsToShow(ArrayUtil.toObjectArray(itemsToShow));
    return argumentList;
  }