예제 #1
0
  private static List<FunctionDescriptor> getSuperFunctionsForMethod(
      @NotNull PsiMethodWrapper method,
      @NotNull BindingTrace trace,
      @NotNull ClassDescriptor containingClass) {
    List<FunctionDescriptor> superFunctions = Lists.newArrayList();

    Map<ClassDescriptor, JetType> superclassToSupertype =
        getSuperclassToSupertypeMap(containingClass);

    Multimap<FqName, Pair<FunctionDescriptor, PsiMethod>> superclassToFunctions =
        getSuperclassToFunctionsMultimap(method, trace.getBindingContext(), containingClass);

    for (HierarchicalMethodSignature superSignature :
        method.getPsiMethod().getHierarchicalMethodSignature().getSuperSignatures()) {
      PsiMethod superMethod = superSignature.getMethod();

      PsiClass psiClass = superMethod.getContainingClass();
      assert psiClass != null;
      String classFqNameString = psiClass.getQualifiedName();
      assert classFqNameString != null;
      FqName classFqName = new FqName(classFqNameString);

      if (!JavaToKotlinClassMap.getInstance().mapPlatformClass(classFqName).isEmpty()) {
        for (FunctionDescriptor superFun :
            JavaToKotlinMethodMap.INSTANCE.getFunctions(superMethod, containingClass)) {
          superFunctions.add(substituteSuperFunction(superclassToSupertype, superFun));
        }
        continue;
      }

      DeclarationDescriptor superFun =
          superMethod instanceof JetClsMethod
              ? trace.get(
                  BindingContext.DECLARATION_TO_DESCRIPTOR,
                  ((JetClsMethod) superMethod).getOrigin())
              : findSuperFunction(superclassToFunctions.get(classFqName), superMethod);
      if (superFun == null) {
        reportCantFindSuperFunction(method);
        continue;
      }

      assert superFun instanceof FunctionDescriptor : superFun.getClass().getName();

      superFunctions.add(
          substituteSuperFunction(superclassToSupertype, (FunctionDescriptor) superFun));
    }

    // sorting for diagnostic stability
    Collections.sort(
        superFunctions,
        new Comparator<FunctionDescriptor>() {
          @Override
          public int compare(FunctionDescriptor fun1, FunctionDescriptor fun2) {
            FqNameUnsafe fqName1 = getFQName(fun1.getContainingDeclaration());
            FqNameUnsafe fqName2 = getFQName(fun2.getContainingDeclaration());
            return fqName1.getFqName().compareTo(fqName2.getFqName());
          }
        });
    return superFunctions;
  }
예제 #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);
    }
  }
예제 #3
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()));
            }
          }
        }
      }
    }
  }
예제 #4
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()));
    }
  }