Пример #1
0
  /**
   * Get tail part of the full fqn by subtracting head part.
   *
   * @param headFQN
   * @param fullFQN
   * @return tail fqn. If first part is not a begging of the full fqn, fullFQN will be returned.
   */
  @NotNull
  public static String tail(@NotNull FqName headFQN, @NotNull FqName fullFQN) {
    if (!isSubpackageOf(fullFQN, headFQN) || headFQN.isRoot()) {
      return fullFQN.getFqName();
    }

    return fullFQN.equals(headFQN)
        ? ""
        : fullFQN.getFqName().substring(headFQN.getFqName().length() + 1); // (headFQN + '.').length
  }
Пример #2
0
  /** Return class names form jet sources in given scope which should be visible as Java classes. */
  @NotNull
  @Override
  public PsiClass[] getClassesByName(
      @NotNull @NonNls String name, @NotNull GlobalSearchScope scope) {
    List<PsiClass> result = new ArrayList<PsiClass>();

    IDELightClassGenerationSupport lightClassGenerationSupport =
        IDELightClassGenerationSupport.getInstanceForIDE(project);
    MultiMap<String, FqName> packageClasses =
        lightClassGenerationSupport.getAllPackageClasses(scope);

    // .namespace classes can not be indexed, since they have no explicit declarations
    Collection<FqName> fqNames = packageClasses.get(name);
    if (!fqNames.isEmpty()) {
      for (FqName fqName : fqNames) {
        PsiClass psiClass =
            JavaElementFinder.getInstance(project).findClass(fqName.getFqName(), scope);
        if (psiClass != null) {
          result.add(psiClass);
        }
      }
    }

    // Quick check for classes from getAllClassNames()
    Collection<JetClassOrObject> classOrObjects =
        JetShortClassNameIndex.getInstance().get(name, project, scope);
    if (classOrObjects.isEmpty()) {
      return result.toArray(new PsiClass[result.size()]);
    }

    for (JetClassOrObject classOrObject : classOrObjects) {
      FqName fqName = JetPsiUtil.getFQName(classOrObject);
      if (fqName != null) {
        assert fqName.shortName().getName().equals(name)
            : "A declaration obtained from index has non-matching name:\n"
                + "in index: "
                + name
                + "\n"
                + "declared: "
                + fqName.shortName()
                + "("
                + fqName
                + ")";
        PsiClass psiClass =
            JavaElementFinder.getInstance(project).findClass(fqName.getFqName(), scope);
        if (psiClass != null) {
          result.add(psiClass);
        }
      }
    }

    return result.toArray(new PsiClass[result.size()]);
  }
Пример #3
0
  @Override
  public void indexFile(PsiJetFileStub stub, IndexSink sink) {
    String packageName = stub.getPackageName();
    FqName fqName = new FqName(packageName == null ? "" : packageName);

    sink.occurrence(JetPackageDeclarationIndex.getInstance().getKey(), fqName.getFqName());

    while (true) {
      sink.occurrence(JetAllPackagesIndex.getInstance().getKey(), fqName.getFqName());
      if (fqName.isRoot()) {
        return;
      }
      fqName = fqName.parent();
    }
  }
Пример #4
0
 // TODO: includeRuntime should be not a flag but a path to runtime
 public static void writeToJar(
     ClassFileFactory factory,
     final OutputStream fos,
     @Nullable FqName mainClass,
     boolean includeRuntime) {
   try {
     Manifest manifest = new Manifest();
     final Attributes mainAttributes = manifest.getMainAttributes();
     mainAttributes.putValue("Manifest-Version", "1.0");
     mainAttributes.putValue("Created-By", "JetBrains Kotlin");
     if (mainClass != null) {
       mainAttributes.putValue("Main-Class", mainClass.getFqName());
     }
     JarOutputStream stream = new JarOutputStream(fos, manifest);
     for (String file : factory.files()) {
       stream.putNextEntry(new JarEntry(file));
       stream.write(factory.asBytes(file));
     }
     if (includeRuntime) {
       writeRuntimeToJar(stream);
     }
     stream.finish();
   } catch (IOException e) {
     throw new CompileEnvironmentException("Failed to generate jar file", e);
   }
 }
Пример #5
0
  public static boolean isSubpackageOf(
      @NotNull final FqName subpackageName, @NotNull FqName packageName) {
    if (subpackageName.equals(packageName)) {
      return true;
    }

    if (packageName.isRoot()) {
      return true;
    }

    String subpackageNameStr = subpackageName.getFqName();
    String packageNameStr = packageName.getFqName();

    return (subpackageNameStr.startsWith(packageNameStr)
        && subpackageNameStr.charAt(packageNameStr.length()) == '.');
  }
Пример #6
0
  @NotNull
  public static FqName withoutFirstSegment(@NotNull FqName fqName) {
    if (fqName.isRoot() || fqName.parent().isRoot()) {
      return FqName.ROOT;
    }

    String fqNameStr = fqName.getFqName();
    return new FqName(fqNameStr.substring(fqNameStr.indexOf('.'), fqNameStr.length()));
  }
Пример #7
0
  public static void addImportDirectiveOrChangeToFqName(
      @NotNull FqName importFqn,
      @NotNull JetFile file,
      int refOffset,
      @NotNull PsiElement targetElement) {
    PsiReference reference = file.findReferenceAt(refOffset);
    if (reference instanceof JetPsiReference) {
      PsiElement target = reference.resolve();
      if (target != null) {
        boolean same = file.getManager().areElementsEquivalent(target, targetElement);

        if (!same) {
          same =
              target instanceof PsiClass
                  && importFqn.getFqName().equals(((PsiClass) target).getQualifiedName());
        }

        if (!same) {
          if (target instanceof PsiMethod) {
            PsiMethod method = (PsiMethod) target;
            same =
                (method.isConstructor()
                    && file.getManager()
                        .areElementsEquivalent(method.getContainingClass(), targetElement));
          }
        }

        if (!same) {
          if (target instanceof JetObjectDeclarationName) {
            same = file.getManager().areElementsEquivalent(target.getParent(), targetElement);
          }
        }

        if (!same) {
          Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
          TextRange refRange = reference.getElement().getTextRange();
          document.replaceString(
              refRange.getStartOffset(), refRange.getEndOffset(), importFqn.getFqName());
        }
        return;
      }
    }
    addImportDirective(new ImportPath(importFqn, false), null, file);
  }
Пример #8
0
  @Override
  public void visitClassType(String name, boolean nullable, boolean forceReal) {
    FqName ourName =
        new FqName(
            name.replace('/', '.').replace('$', '.') // TODO: not sure
            );

    this.classDescriptor = null;
    if (!forceReal) {
      classDescriptor =
          javaSemanticServices
              .getTypeTransformer()
              .getKotlinAnalog(ourName, JavaTypeTransformer.TypeUsage.MEMBER_SIGNATURE_INVARIANT);
    }

    if (classDescriptor == null) {
      // TODO: this is the worst code in Kotlin project
      Matcher matcher = Pattern.compile("jet\\.Function(\\d+)").matcher(ourName.getFqName());
      if (matcher.matches()) {
        classDescriptor = JetStandardClasses.getFunction(Integer.parseInt(matcher.group(1)));
      }
    }

    if (classDescriptor == null) {
      Matcher matcher = Pattern.compile("jet\\.Tuple(\\d+)").matcher(ourName.getFqName());
      if (matcher.matches()) {
        classDescriptor = JetStandardClasses.getTuple(Integer.parseInt(matcher.group(1)));
      }
    }

    if (this.classDescriptor == null) {
      this.classDescriptor =
          javaDescriptorResolver.resolveClass(ourName, DescriptorSearchRule.INCLUDE_KOTLIN);
    }

    if (this.classDescriptor == null) {
      // TODO: report in to trace
      this.errorType = ErrorUtils.createErrorType("class not found by name: " + ourName);
    }
    this.nullable = nullable;
    this.typeArguments = new ArrayList<TypeProjection>();
  }
Пример #9
0
  @Override
  public void indexProperty(PsiJetPropertyStub stub, IndexSink sink) {
    String propertyName = stub.getName();
    if (propertyName != null) {
      if (stub.isTopLevel()) {
        FqName topFQName = stub.getTopFQName();
        if (topFQName != null) {
          sink.occurrence(
              JetTopLevelPropertiesFqnNameIndex.getInstance().getKey(), topFQName.getFqName());
        }
      }

      sink.occurrence(JetShortPropertiesNameIndex.getInstance().getKey(), propertyName);
    }
  }
Пример #10
0
  @Override
  public void indexObject(PsiJetObjectStub stub, IndexSink sink) {
    String name = stub.getName();
    assert name != null;

    sink.occurrence(JetShortClassNameIndex.getInstance().getKey(), name);

    if (stub.isTopLevel()) {
      sink.occurrence(JetTopLevelShortObjectNameIndex.getInstance().getKey(), name);
    }

    FqName fqName = stub.getFQName();
    if (fqName != null) {
      sink.occurrence(JetFullClassNameIndex.getInstance().getKey(), fqName.getFqName());
    }

    recordClassOrObjectByPackage(stub, sink);
  }
Пример #11
0
  @Override
  public void indexFunction(PsiJetFunctionStub stub, IndexSink sink) {
    String name = stub.getName();
    if (name != null) {
      if (stub.isTopLevel()) {
        // Collection only top level functions as only they are expected in completion without
        // explicit import
        if (!stub.isExtension()) {
          sink.occurrence(JetShortFunctionNameIndex.getInstance().getKey(), name);
        } else {
          sink.occurrence(JetExtensionFunctionNameIndex.getInstance().getKey(), name);
        }

        FqName topFQName = stub.getTopFQName();
        if (topFQName != null) {
          sink.occurrence(
              JetTopLevelFunctionsFqnNameIndex.getInstance().getKey(), topFQName.getFqName());
        }
      }

      sink.occurrence(JetAllShortFunctionNameIndex.getInstance().getKey(), name);
    }
  }
Пример #12
0
 public static boolean isOneSegmentFQN(@NotNull FqName fqn) {
   return isOneSegmentFQN(fqn.getFqName());
 }
Пример #13
0
 @NotNull
 private static String fqNameToInternalName(@NotNull FqName fqName) {
   return fqName.getFqName().replace('.', '/');
 }