@NotNull
    private MutableClassDescriptor createClassDescriptorForClass(
        @NotNull JetClass klass, @NotNull DeclarationDescriptor containingDeclaration) {
      ClassKind kind = getClassKind(klass);
      // Kind check is needed in order to not consider enums as inner in any case
      // (otherwise it would be impossible to create a class object in the enum)
      boolean isInner = kind == ClassKind.CLASS && klass.isInner();
      MutableClassDescriptor mutableClassDescriptor =
          new MutableClassDescriptor(
              containingDeclaration,
              outerScope,
              kind,
              isInner,
              JetPsiUtil.safeName(klass.getName()));
      c.getClasses().put(klass, mutableClassDescriptor);
      trace.record(
          FQNAME_TO_CLASS_DESCRIPTOR, JetPsiUtil.getUnsafeFQName(klass), mutableClassDescriptor);

      createClassObjectForEnumClass(mutableClassDescriptor);

      JetScope classScope = mutableClassDescriptor.getScopeForMemberDeclarationResolution();

      prepareForDeferredCall(classScope, mutableClassDescriptor, klass);

      return mutableClassDescriptor;
    }
    @Override
    public void visitObjectDeclaration(@NotNull JetObjectDeclaration declaration) {
      if (declaration.isObjectLiteral()) {
        createClassDescriptorForSingleton(
            declaration, SpecialNames.NO_NAME_PROVIDED, ClassKind.CLASS);
        return;
      }

      MutableClassDescriptor descriptor =
          createClassDescriptorForSingleton(
              declaration, JetPsiUtil.safeName(declaration.getName()), ClassKind.OBJECT);

      owner.addClassifierDescriptor(descriptor);
      trace.record(FQNAME_TO_CLASS_DESCRIPTOR, JetPsiUtil.getUnsafeFQName(declaration), descriptor);

      descriptor.getBuilder().setClassObjectDescriptor(createSyntheticClassObject(descriptor));
    }
    @Override
    public void visitEnumEntry(@NotNull JetEnumEntry declaration) {
      MutableClassDescriptor descriptor =
          createClassDescriptorForSingleton(
              declaration, JetPsiUtil.safeName(declaration.getName()), ClassKind.ENUM_ENTRY);

      owner.addClassifierDescriptor(descriptor);

      descriptor.getBuilder().setClassObjectDescriptor(createSyntheticClassObject(descriptor));
    }
 @Override
 public void visitJetFile(JetFile file) {
   if (file.isScript()) {
     //noinspection ConstantConditions
     final ClassDescriptor classDescriptor =
         bindingContext.get(CLASS_FOR_FUNCTION, bindingContext.get(SCRIPT, file.getScript()));
     classStack.push(classDescriptor);
     //noinspection ConstantConditions
     nameStack.push(classNameForScriptPsi(bindingContext, file.getScript()).getInternalName());
   } else {
     nameStack.push(JetPsiUtil.getFQName(file).getFqName().replace('.', '/'));
   }
   file.acceptChildren(this);
   nameStack.pop();
   if (file.isScript()) {
     classStack.pop();
   }
 }
  @NotNull
  public static Collection<JetFile> allFilesInNamespaces(
      BindingContext bindingContext, Collection<JetFile> files) {
    // todo: we use Set and add given files but ignoring other scripts because something non-clear
    // kept in binding
    // for scripts especially in case of REPL

    HashSet<FqName> names = new HashSet<FqName>();
    for (JetFile file : files) {
      if (!file.isScript()) {
        names.add(JetPsiUtil.getFQName(file));
      }
    }

    HashSet<JetFile> answer = new HashSet<JetFile>();
    answer.addAll(files);

    for (FqName name : names) {
      NamespaceDescriptor namespaceDescriptor =
          bindingContext.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, name);
      Collection<JetFile> jetFiles = bindingContext.get(NAMESPACE_TO_FILES, namespaceDescriptor);
      if (jetFiles != null) answer.addAll(jetFiles);
    }

    List<JetFile> sortedAnswer = new ArrayList<JetFile>(answer);
    Collections.sort(
        sortedAnswer,
        new Comparator<JetFile>() {
          @NotNull
          private String path(JetFile file) {
            VirtualFile virtualFile = file.getVirtualFile();
            assert virtualFile != null : "VirtualFile is null for JetFile: " + file.getName();
            return virtualFile.getPath();
          }

          @Override
          public int compare(JetFile first, JetFile second) {
            return path(first).compareTo(path(second));
          }
        });

    return sortedAnswer;
  }
Example #6
0
  @NotNull
  /*package*/ OverloadResolutionResultsImpl<FunctionDescriptor> resolveFunctionCall(
      @NotNull BasicCallResolutionContext context) {

    ProgressIndicatorProvider.checkCanceled();

    List<ResolutionTask<CallableDescriptor, FunctionDescriptor>> prioritizedTasks;

    JetExpression calleeExpression = context.call.getCalleeExpression();
    JetReferenceExpression functionReference;
    if (calleeExpression instanceof JetSimpleNameExpression) {
      JetSimpleNameExpression expression = (JetSimpleNameExpression) calleeExpression;
      functionReference = expression;

      ExpressionTypingUtils.checkCapturingInClosure(expression, context.trace, context.scope);

      Name name = expression.getReferencedNameAsName();

      prioritizedTasks =
          TaskPrioritizer.<CallableDescriptor, FunctionDescriptor>computePrioritizedTasks(
              context,
              name,
              functionReference,
              CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES);
      ResolutionTask.DescriptorCheckStrategy abstractConstructorCheck =
          new ResolutionTask.DescriptorCheckStrategy() {
            @Override
            public <D extends CallableDescriptor> boolean performAdvancedChecks(
                D descriptor, BindingTrace trace, TracingStrategy tracing) {
              if (descriptor instanceof ConstructorDescriptor) {
                Modality modality =
                    ((ConstructorDescriptor) descriptor).getContainingDeclaration().getModality();
                if (modality == Modality.ABSTRACT) {
                  tracing.instantiationOfAbstractClass(trace);
                  return false;
                }
              }
              return true;
            }
          };
      for (ResolutionTask task : prioritizedTasks) {
        task.setCheckingStrategy(abstractConstructorCheck);
      }
    } else {
      JetValueArgumentList valueArgumentList = context.call.getValueArgumentList();
      PsiElement reportAbsenceOn =
          valueArgumentList == null ? context.call.getCallElement() : valueArgumentList;
      if (calleeExpression instanceof JetConstructorCalleeExpression) {
        assert !context.call.getExplicitReceiver().exists();

        JetConstructorCalleeExpression expression =
            (JetConstructorCalleeExpression) calleeExpression;
        functionReference = expression.getConstructorReferenceExpression();
        if (functionReference == null) {
          return checkArgumentTypesAndFail(context); // No type there
        }
        JetTypeReference typeReference = expression.getTypeReference();
        assert typeReference != null;
        JetType constructedType =
            typeResolver.resolveType(context.scope, typeReference, context.trace, true);

        if (constructedType.isError()) {
          return checkArgumentTypesAndFail(context);
        }

        DeclarationDescriptor declarationDescriptor =
            constructedType.getConstructor().getDeclarationDescriptor();
        if (declarationDescriptor instanceof ClassDescriptor) {
          ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
          Collection<ConstructorDescriptor> constructors = classDescriptor.getConstructors();
          if (constructors.isEmpty()) {
            context.trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn));
            return checkArgumentTypesAndFail(context);
          }
          Collection<ResolutionCandidate<CallableDescriptor>> candidates =
              TaskPrioritizer.<CallableDescriptor>convertWithImpliedThis(
                  context.scope,
                  Collections.<ReceiverValue>singletonList(NO_RECEIVER),
                  constructors);
          prioritizedTasks =
              TaskPrioritizer
                  .<CallableDescriptor, FunctionDescriptor>computePrioritizedTasksFromCandidates(
                      context, functionReference, candidates, null);
        } else {
          context.trace.report(NOT_A_CLASS.on(calleeExpression));
          return checkArgumentTypesAndFail(context);
        }
      } else if (calleeExpression instanceof JetThisReferenceExpression) {
        functionReference = (JetThisReferenceExpression) calleeExpression;
        DeclarationDescriptor containingDeclaration = context.scope.getContainingDeclaration();
        if (containingDeclaration instanceof ConstructorDescriptor) {
          containingDeclaration = containingDeclaration.getContainingDeclaration();
        }
        assert containingDeclaration instanceof ClassDescriptor;
        ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration;

        Collection<ConstructorDescriptor> constructors = classDescriptor.getConstructors();
        if (constructors.isEmpty()) {
          context.trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn));
          return checkArgumentTypesAndFail(context);
        }
        List<ResolutionCandidate<CallableDescriptor>> candidates =
            ResolutionCandidate.<CallableDescriptor>convertCollection(
                constructors, JetPsiUtil.isSafeCall(context.call));
        prioritizedTasks =
            Collections.singletonList(
                new ResolutionTask<CallableDescriptor, FunctionDescriptor>(
                    candidates, functionReference, context)); // !! DataFlowInfo.EMPTY
      } else if (calleeExpression != null) {
        // Here we handle the case where the callee expression must be something of type function,
        // e.g. (foo.bar())(1, 2)
        JetType calleeType =
            expressionTypingServices.safeGetType(
                context.scope,
                calleeExpression,
                NO_EXPECTED_TYPE,
                context.dataFlowInfo,
                context
                    .trace); // We are actually expecting a function, but there seems to be no easy
                             // way of expressing this

        if (!KotlinBuiltIns.getInstance().isFunctionOrExtensionFunctionType(calleeType)) {
          //                    checkTypesWithNoCallee(trace, scope, call);
          if (!calleeType.isError()) {
            context.trace.report(CALLEE_NOT_A_FUNCTION.on(calleeExpression, calleeType));
          }
          return checkArgumentTypesAndFail(context);
        }

        FunctionDescriptorImpl functionDescriptor =
            new ExpressionAsFunctionDescriptor(
                context.scope.getContainingDeclaration(),
                Name.special("<for expression " + calleeExpression.getText() + ">"),
                calleeExpression);
        FunctionDescriptorUtil.initializeFromFunctionType(
            functionDescriptor,
            calleeType,
            NO_RECEIVER_PARAMETER,
            Modality.FINAL,
            Visibilities.LOCAL);
        ResolutionCandidate<CallableDescriptor> resolutionCandidate =
            ResolutionCandidate.<CallableDescriptor>create(
                functionDescriptor, JetPsiUtil.isSafeCall(context.call));
        resolutionCandidate.setReceiverArgument(context.call.getExplicitReceiver());
        resolutionCandidate.setExplicitReceiverKind(ExplicitReceiverKind.RECEIVER_ARGUMENT);

        // strictly speaking, this is a hack:
        // we need to pass a reference, but there's no reference in the PSI,
        // so we wrap what we have into a fake reference and pass it on (unwrap on the other end)
        functionReference = new JetFakeReference(calleeExpression);

        prioritizedTasks =
            Collections.singletonList(
                new ResolutionTask<CallableDescriptor, FunctionDescriptor>(
                    Collections.singleton(resolutionCandidate), functionReference, context));
      } else {
        //                checkTypesWithNoCallee(trace, scope, call);
        return checkArgumentTypesAndFail(context);
      }
    }

    return doResolveCallOrGetCachedResults(
        ResolutionResultsCache.FUNCTION_MEMBER_TYPE,
        context,
        prioritizedTasks,
        CallTransformer.FUNCTION_CALL_TRANSFORMER,
        functionReference);
  }