コード例 #1
0
  @NotNull
  public static PsiElement createCompilerPass(
      @NotNull PhpClass bundleClass, @NotNull String className) throws Exception {

    VirtualFile directory =
        bundleClass.getContainingFile().getContainingDirectory().getVirtualFile();
    if (fileExists(directory, className)) {
      throw new Exception("File already exists");
    }

    PhpPsiElement scopeForUseOperator = PhpCodeInsightUtil.findScopeForUseOperator(bundleClass);
    if (scopeForUseOperator == null) {
      throw new Exception("No 'use' scope found");
    }

    VirtualFile compilerDirectory = getAndCreateCompilerDirectory(directory);
    if (compilerDirectory == null) {
      throw new Exception("Directory creation failed");
    }

    Project project = bundleClass.getProject();

    if (bundleClass.findOwnMethodByName("build") == null) {

      insertUseIfNecessary(
          scopeForUseOperator, "\\Symfony\\Component\\DependencyInjection\\ContainerBuilder");

      Method method =
          PhpPsiElementFactory.createMethod(
              project,
              ""
                  + "public function build(ContainerBuilder $container)\n"
                  + "    {\n"
                  + "        parent::build($container);\n"
                  + "    }");

      PhpCodeEditUtil.insertClassMember(bundleClass, method);
    }

    Method buildMethod = bundleClass.findOwnMethodByName("build");
    if (buildMethod == null) {
      throw new Exception("No 'build' method found");
    }

    String relativePath = VfsUtil.getRelativePath(compilerDirectory, directory);
    if (relativePath == null) {
      throw new Exception("path error");
    }

    MethodReference methodReference =
        PhpPsiElementFactory.createMethodReference(
            project, "$container->addCompilerPass(new " + className + "());");

    String ns = bundleClass.getNamespaceName() + relativePath.replace("/", "\\");
    String nsClass = ns + "\\" + className;

    insertUseIfNecessary(scopeForUseOperator, nsClass);

    GroupStatement groupStatement =
        PhpPsiUtil.getChildByCondition(buildMethod, GroupStatement.INSTANCEOF);
    if (groupStatement != null) {
      PsiElement semicolon = methodReference.getNextSibling();
      groupStatement.addRangeBefore(methodReference, semicolon, groupStatement.getLastChild());
    }

    String COMPILER_TEMPLATE = "/resources/fileTemplates/compiler_pass.php";
    String fileTemplateContent = getFileTemplateContent(COMPILER_TEMPLATE);
    if (fileTemplateContent == null) {
      throw new Exception("Template content error");
    }

    String replace =
        fileTemplateContent
            .replace("{{ ns }}", ns.startsWith("\\") ? ns.substring(1) : ns)
            .replace("{{ class }}", className);
    PsiFile fileFromText =
        PsiFileFactory.getInstance(project)
            .createFileFromText(className + ".php", PhpFileType.INSTANCE, replace);
    CodeStyleManager.getInstance(project).reformat(fileFromText);

    return PsiDirectoryFactory.getInstance(project)
        .createDirectory(compilerDirectory)
        .add(fileFromText);
  }