private static JetScope getExpressionResolutionScope(
     @NotNull ResolveSession resolveSession, @NotNull JetExpression expression) {
   ScopeProvider provider = resolveSession.getInjector().getScopeProvider();
   JetDeclaration parentDeclaration =
       PsiTreeUtil.getParentOfType(expression, JetDeclaration.class);
   if (parentDeclaration == null) {
     return provider.getFileScopeWithAllImported((JetFile) expression.getContainingFile());
   }
   return provider.getResolutionScopeForDeclaration(parentDeclaration);
 }
  public static @NotNull BindingContext resolveToExpression(
      @NotNull final ResolveSession resolveSession, @NotNull JetExpression expression) {
    final DelegatingBindingTrace trace =
        new DelegatingBindingTrace(
            resolveSession.getBindingContext(), "trace to resolve expression", expression);
    JetFile file = (JetFile) expression.getContainingFile();

    @SuppressWarnings("unchecked")
    PsiElement topmostCandidateForAdditionalResolve =
        JetPsiUtil.getTopmostParentOfTypes(
            expression,
            JetNamedFunction.class,
            JetClassInitializer.class,
            JetProperty.class,
            JetDelegationSpecifierList.class);

    if (topmostCandidateForAdditionalResolve != null) {
      if (topmostCandidateForAdditionalResolve instanceof JetNamedFunction) {
        functionAdditionalResolve(
            resolveSession, (JetNamedFunction) topmostCandidateForAdditionalResolve, trace, file);
      } else if (topmostCandidateForAdditionalResolve instanceof JetClassInitializer) {
        initializerAdditionalResolve(
            resolveSession,
            (JetClassInitializer) topmostCandidateForAdditionalResolve,
            trace,
            file);
      } else if (topmostCandidateForAdditionalResolve instanceof JetProperty) {
        propertyAdditionalResolve(
            resolveSession, (JetProperty) topmostCandidateForAdditionalResolve, trace, file);
      } else if (topmostCandidateForAdditionalResolve instanceof JetDelegationSpecifierList) {
        delegationSpecifierAdditionalResolve(
            resolveSession,
            (JetDelegationSpecifierList) topmostCandidateForAdditionalResolve,
            trace,
            file);
      } else {
        assert false : "Invalid type of the topmost parent";
      }

      return trace.getBindingContext();
    }

    // Setup resolution scope explicitly
    if (trace.getBindingContext().get(BindingContext.RESOLUTION_SCOPE, expression) == null) {
      JetScope scope = getExpressionMemberScope(resolveSession, expression);
      if (scope != null) {
        trace.record(BindingContext.RESOLUTION_SCOPE, expression, scope);
      }
    }

    return trace.getBindingContext();
  }
示例#3
0
  /**
   * Name suggestion types: 1. According to type: 1a. Primitive types to some short name 1b. Class
   * types according to class name camel humps: (AbCd => {abCd, cd}) 1c. Arrays => arrayOfInnerType
   * 2. Reference expressions according to reference name camel humps 3. Method call expression
   * according to method callee expression
   *
   * @param expression to suggest name for variable
   * @param validator to check scope for such names
   * @return possible names
   */
  public static String[] suggestNames(JetExpression expression, JetNameValidator validator) {
    ArrayList<String> result = new ArrayList<String>();

    BindingContext bindingContext =
        AnalyzeSingleFileUtil.getContextForSingleFile((JetFile) expression.getContainingFile());
    JetType jetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, expression);
    if (jetType != null) {
      addNamesForType(result, jetType, validator);
    }
    addNamesForExpression(result, expression, validator);

    if (result.isEmpty()) addName(result, "value", validator);
    return ArrayUtil.toStringArray(result);
  }
  public static JetScope getExpressionMemberScope(
      @NotNull ResolveSession resolveSession, @NotNull JetExpression expression) {
    DelegatingBindingTrace trace =
        new DelegatingBindingTrace(
            resolveSession.getBindingContext(),
            "trace to resolve a member scope of expression",
            expression);

    if (expression instanceof JetReferenceExpression) {
      QualifiedExpressionResolver qualifiedExpressionResolver =
          resolveSession.getInjector().getQualifiedExpressionResolver();

      // In some type declaration
      if (expression.getParent() instanceof JetUserType) {
        JetUserType qualifier = ((JetUserType) expression.getParent()).getQualifier();
        if (qualifier != null) {
          Collection<? extends DeclarationDescriptor> descriptors =
              qualifiedExpressionResolver.lookupDescriptorsForUserType(
                  qualifier, getExpressionResolutionScope(resolveSession, expression), trace);

          for (DeclarationDescriptor descriptor : descriptors) {
            if (descriptor instanceof LazyPackageDescriptor) {
              return ((LazyPackageDescriptor) descriptor).getMemberScope();
            }
          }
        }
      }

      // Inside import
      if (PsiTreeUtil.getParentOfType(expression, JetImportDirective.class, false) != null) {
        NamespaceDescriptor rootPackage = resolveSession.getPackageDescriptorByFqName(FqName.ROOT);
        assert rootPackage != null;

        if (expression.getParent() instanceof JetDotQualifiedExpression) {
          JetExpression element =
              ((JetDotQualifiedExpression) expression.getParent()).getReceiverExpression();
          String name = ((JetFile) expression.getContainingFile()).getPackageName();

          NamespaceDescriptor filePackage =
              name != null
                  ? resolveSession.getPackageDescriptorByFqName(new FqName(name))
                  : rootPackage;
          assert filePackage != null : "File package should be already resolved and be found";

          JetScope scope = filePackage.getMemberScope();
          Collection<? extends DeclarationDescriptor> descriptors;

          if (element instanceof JetDotQualifiedExpression) {
            descriptors =
                qualifiedExpressionResolver.lookupDescriptorsForQualifiedExpression(
                    (JetDotQualifiedExpression) element,
                    rootPackage.getMemberScope(),
                    scope,
                    trace,
                    false,
                    false);
          } else {
            descriptors =
                qualifiedExpressionResolver.lookupDescriptorsForSimpleNameReference(
                    (JetSimpleNameExpression) element,
                    rootPackage.getMemberScope(),
                    scope,
                    trace,
                    false,
                    false,
                    false);
          }

          for (DeclarationDescriptor descriptor : descriptors) {
            if (descriptor instanceof NamespaceDescriptor) {
              return ((NamespaceDescriptor) descriptor).getMemberScope();
            }
          }
        } else {
          return rootPackage.getMemberScope();
        }
      }

      // Inside package declaration
      JetNamespaceHeader namespaceHeader =
          PsiTreeUtil.getParentOfType(expression, JetNamespaceHeader.class, false);
      if (namespaceHeader != null) {
        NamespaceDescriptor packageDescriptor =
            resolveSession.getPackageDescriptorByFqName(
                namespaceHeader.getParentFqName((JetReferenceExpression) expression));
        if (packageDescriptor != null) {
          return packageDescriptor.getMemberScope();
        }
      }
    }

    return null;
  }