@Override
    public void visitClassObject(@NotNull JetClassObject classObject) {
      JetObjectDeclaration objectDeclaration = classObject.getObjectDeclaration();

      DeclarationDescriptor container = owner.getOwnerForChildren();

      MutableClassDescriptor classObjectDescriptor =
          createClassDescriptorForSingleton(
              objectDeclaration, getClassObjectName(container.getName()), ClassKind.CLASS_OBJECT);

      PackageLikeBuilder.ClassObjectStatus status =
          isEnumEntry(container)
                  || isObject(container)
                  || c.getTopDownAnalysisParameters().isDeclaredLocally()
              ? PackageLikeBuilder.ClassObjectStatus.NOT_ALLOWED
              : owner.setClassObjectDescriptor(classObjectDescriptor);

      switch (status) {
        case DUPLICATE:
          trace.report(MANY_CLASS_OBJECTS.on(classObject));
          break;
        case NOT_ALLOWED:
          trace.report(CLASS_OBJECT_NOT_ALLOWED.on(classObject));
          break;
        case OK:
          // Everything is OK so no errors to trace.
          break;
      }
    }
示例#2
0
  public void checkRedeclarationsInInnerClassNames(@NotNull TopDownAnalysisContext c) {
    for (ClassDescriptorWithResolutionScopes classDescriptor : c.getDeclaredClasses().values()) {
      if (classDescriptor.getKind() == ClassKind.CLASS_OBJECT) {
        // Class objects should be considered during analysing redeclarations in classes
        continue;
      }

      Collection<DeclarationDescriptor> allDescriptors =
          classDescriptor.getScopeForMemberLookup().getOwnDeclaredDescriptors();

      ClassDescriptorWithResolutionScopes classObj = classDescriptor.getClassObjectDescriptor();
      if (classObj != null) {
        Collection<DeclarationDescriptor> classObjDescriptors =
            classObj.getScopeForMemberLookup().getOwnDeclaredDescriptors();
        if (!classObjDescriptors.isEmpty()) {
          allDescriptors = Lists.newArrayList(allDescriptors);
          allDescriptors.addAll(classObjDescriptors);
        }
      }

      Multimap<Name, DeclarationDescriptor> descriptorMap = HashMultimap.create();
      for (DeclarationDescriptor desc : allDescriptors) {
        if (desc instanceof ClassDescriptor || desc instanceof PropertyDescriptor) {
          descriptorMap.put(desc.getName(), desc);
        }
      }

      reportRedeclarations(descriptorMap);
    }
  }
 @Nullable
 private static AnnotationDescriptor getDeprecated(DeclarationDescriptor descriptor) {
   AnnotationDescriptor kotlinDeprecated =
       descriptor.getAnnotations().findAnnotation(KOTLIN_DEPRECATED);
   return kotlinDeprecated != null
       ? kotlinDeprecated
       : descriptor.getAnnotations().findAnnotation(JAVA_DEPRECATED);
 }
  private static String getJvmInternalFQNameImpl(
      BindingTrace bindingTrace, DeclarationDescriptor descriptor) {
    if (descriptor instanceof FunctionDescriptor) {
      throw new IllegalStateException("requested fq name for function: " + descriptor);
    }

    if (descriptor.getContainingDeclaration() instanceof ModuleDescriptor
        || descriptor instanceof ScriptDescriptor) {
      return "";
    }

    if (descriptor instanceof ModuleDescriptor) {
      throw new IllegalStateException("missed something");
    }

    if (descriptor instanceof ClassDescriptor) {
      ClassDescriptor klass = (ClassDescriptor) descriptor;
      if (klass.getKind() == ClassKind.OBJECT || klass.getKind() == ClassKind.CLASS_OBJECT) {
        if (klass.getContainingDeclaration() instanceof ClassDescriptor) {
          ClassDescriptor containingKlass = (ClassDescriptor) klass.getContainingDeclaration();
          if (containingKlass.getKind() == ClassKind.ENUM_CLASS) {
            return getJvmInternalName(bindingTrace, containingKlass).getInternalName();
          } else {
            return getJvmInternalName(bindingTrace, containingKlass).getInternalName()
                + JvmAbi.CLASS_OBJECT_SUFFIX;
          }
        }
      }

      JvmClassName name = bindingTrace.getBindingContext().get(FQN, descriptor);
      if (name != null) {
        return name.getInternalName();
      }
    }

    DeclarationDescriptor container = descriptor.getContainingDeclaration();

    if (container == null) {
      throw new IllegalStateException("descriptor has no container: " + descriptor);
    }

    Name name = descriptor.getName();

    String baseName = getJvmInternalName(bindingTrace, container).getInternalName();
    if (!baseName.isEmpty()) {
      return baseName
          + (container instanceof NamespaceDescriptor ? "/" : "$")
          + name.getIdentifier();
    }

    return name.getIdentifier();
  }
 private void checkConstructorDescriptor(
     @NotNull JetExpression expression, @NotNull DeclarationDescriptor target) {
   // Deprecated for Class and for Constructor
   DeclarationDescriptor containingDeclaration = target.getContainingDeclaration();
   if (containingDeclaration != null) {
     if (!reportAnnotationIfNeeded(expression, containingDeclaration)) {
       reportAnnotationIfNeeded(expression, target);
     }
   }
 }
示例#6
0
  private void checkRedeclarationsInPackages(@NotNull TopDownAnalysisContext c) {
    for (MutablePackageFragmentDescriptor packageFragment :
        Sets.newHashSet(c.getPackageFragments().values())) {
      PackageViewDescriptor packageView =
          packageFragment.getContainingDeclaration().getPackage(packageFragment.getFqName());
      JetScope packageViewScope = packageView.getMemberScope();
      Multimap<Name, DeclarationDescriptor> simpleNameDescriptors =
          packageFragment.getMemberScope().getDeclaredDescriptorsAccessibleBySimpleName();
      for (Name name : simpleNameDescriptors.keySet()) {
        // Keep only properties with no receiver
        Collection<DeclarationDescriptor> descriptors =
            Collections2.filter(
                simpleNameDescriptors.get(name),
                new Predicate<DeclarationDescriptor>() {
                  @Override
                  public boolean apply(@Nullable DeclarationDescriptor descriptor) {
                    if (descriptor instanceof PropertyDescriptor) {
                      PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
                      return propertyDescriptor.getReceiverParameter() == null;
                    }
                    return true;
                  }
                });
        ContainerUtil.addIfNotNull(descriptors, packageViewScope.getPackage(name));

        if (descriptors.size() > 1) {
          for (DeclarationDescriptor declarationDescriptor : descriptors) {
            for (PsiElement declaration : getDeclarationsByDescriptor(declarationDescriptor)) {
              assert declaration != null
                  : "Null declaration for descriptor: "
                      + declarationDescriptor
                      + " "
                      + (declarationDescriptor != null
                          ? DescriptorRenderer.FQ_NAMES_IN_TYPES.render(declarationDescriptor)
                          : "");
              trace.report(
                  REDECLARATION.on(declaration, declarationDescriptor.getName().asString()));
            }
          }
        }
      }
    }
  }
 private static String getDescriptorString(@NotNull DeclarationDescriptor descriptor) {
   if (descriptor instanceof ClassDescriptor) {
     return DescriptorUtils.getFqName(descriptor).asString();
   } else if (descriptor instanceof ConstructorDescriptor) {
     DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
     assert containingDeclaration != null;
     return "constructor for " + containingDeclaration.getName();
   } else if (descriptor instanceof PropertyGetterDescriptor) {
     return "getter for "
         + ((PropertyGetterDescriptor) descriptor).getCorrespondingProperty().getName();
   } else if (descriptor instanceof PropertySetterDescriptor) {
     return "setter for "
         + ((PropertySetterDescriptor) descriptor).getCorrespondingProperty().getName();
   } else if (descriptor instanceof PropertyDescriptor) {
     if (((PropertyDescriptor) descriptor).isVar()) {
       return "var " + descriptor.getName();
     }
     return "val " + descriptor.getName();
   } else if (descriptor instanceof FunctionDescriptor) {
     return "fun "
         + descriptor.getName()
         + DescriptorRenderer.FQ_NAMES_IN_TYPES.renderFunctionParameters(
             (FunctionDescriptor) descriptor);
   }
   return DescriptorRenderer.FQ_NAMES_IN_TYPES.render(descriptor);
 }
  @NotNull
  public static JvmClassName getJvmInternalName(
      BindingTrace bindingTrace, @NotNull DeclarationDescriptor descriptor) {
    descriptor = descriptor.getOriginal();
    JvmClassName name = bindingTrace.getBindingContext().get(FQN, descriptor);
    if (name != null) {
      return name;
    }

    name = JvmClassName.byInternalName(getJvmInternalFQNameImpl(bindingTrace, descriptor));

    assert PsiCodegenPredictor.checkPredictedNameFromPsi(bindingTrace, descriptor, name);
    bindingTrace.record(FQN, descriptor, name);
    return name;
  }
示例#9
0
  private void reportRedeclarations(@NotNull Multimap<Name, DeclarationDescriptor> descriptorMap) {
    Set<Pair<PsiElement, Name>> redeclarations = Sets.newHashSet();
    for (Name name : descriptorMap.keySet()) {
      Collection<DeclarationDescriptor> descriptors = descriptorMap.get(name);
      if (descriptors.size() > 1) {
        // We mustn't compare PropertyDescriptor with PropertyDescriptor because we do this at
        // OverloadResolver
        for (DeclarationDescriptor descriptor : descriptors) {
          if (descriptor instanceof ClassDescriptor) {
            for (DeclarationDescriptor descriptor2 : descriptors) {
              if (descriptor == descriptor2) {
                continue;
              }

              redeclarations.add(
                  Pair.create(
                      BindingContextUtils.classDescriptorToDeclaration(
                          trace.getBindingContext(), (ClassDescriptor) descriptor),
                      descriptor.getName()));
              if (descriptor2 instanceof PropertyDescriptor) {
                redeclarations.add(
                    Pair.create(
                        BindingContextUtils.descriptorToDeclaration(
                            trace.getBindingContext(), descriptor2),
                        descriptor2.getName()));
              }
            }
          }
        }
      }
    }
    for (Pair<PsiElement, Name> redeclaration : redeclarations) {
      trace.report(
          REDECLARATION.on(redeclaration.getFirst(), redeclaration.getSecond().asString()));
    }
  }
示例#10
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);
  }