private static void doCollectResourceDirs(
      AndroidFacet facet,
      boolean collectResCacheDirs,
      List<String> result,
      CompileContext context) {
    final Module module = facet.getModule();

    if (collectResCacheDirs) {
      final AndroidPlatform platform = facet.getConfiguration().getAndroidPlatform();
      final int platformToolsRevision =
          platform != null ? platform.getSdk().getPlatformToolsRevision() : -1;

      if (platformToolsRevision < 0 || platformToolsRevision > 7) {
        // png cache is supported since platform-tools-r8
        final String resCacheDirOsPath = findResourcesCacheDirectory(module, false, context);
        if (resCacheDirOsPath != null) {
          result.add(resCacheDirOsPath);
        } else {
          LOG.info("PNG cache not found for module " + module.getName());
        }
      }
    }

    final VirtualFile resourcesDir = AndroidAptCompiler.getResourceDirForApkCompiler(module, facet);
    if (resourcesDir != null) {
      result.add(resourcesDir.getPath());
    }
  }
 private static void addItem(
     @NotNull final Collection<VirtualFile> sourceFiles,
     @NotNull final AndroidFacet facet,
     @NotNull final String resourceDirPath,
     @NotNull String sdkLocation,
     @NotNull final IAndroidTarget target,
     @NotNull final List<GenerationItem> items) {
   final String sourceRootPath = AndroidRootUtil.getRenderscriptGenSourceRootPath(facet);
   if (sourceRootPath == null) {
     return;
   }
   final String rawDirPath = resourceDirPath + '/' + AndroidConstants.FD_RES_RAW;
   items.add(
       new MyGenerationItem(facet.getModule(), sourceFiles, rawDirPath, sdkLocation, target));
 }
 private static VirtualFile[] getFilesToCheckReadonlyStatus(
     GeneratingCompiler.GenerationItem[] items) {
   List<VirtualFile> filesToCheck = new ArrayList<VirtualFile>();
   for (GeneratingCompiler.GenerationItem item : items) {
     if (item instanceof AndroidAptCompiler.AptGenerationItem) {
       final Set<File> generatedFiles =
           ((AndroidAptCompiler.AptGenerationItem) item).getGeneratedFiles().keySet();
       for (File generatedFile : generatedFiles) {
         if (generatedFile.exists()) {
           VirtualFile generatedVFile =
               LocalFileSystem.getInstance().findFileByIoFile(generatedFile);
           if (generatedVFile != null) {
             filesToCheck.add(generatedVFile);
           }
         }
       }
     }
   }
   return VfsUtil.toVirtualFileArray(filesToCheck);
 }
Ejemplo n.º 4
0
 @Nullable
 private File getOutputDirsToCompileTo(ModuleChunk chunk, final List<OutputDir> dirs)
     throws IOException {
   File fileToDelete = null;
   if (chunk.getModuleCount() == 1) { // optimization
     final Module module = chunk.getModules()[0];
     ApplicationManager.getApplication()
         .runReadAction(
             new Runnable() {
               public void run() {
                 final String sourcesOutputDir = getOutputDir(module);
                 if (shouldCompileTestsSeparately(module)) {
                   if (sourcesOutputDir != null) {
                     dirs.add(new OutputDir(sourcesOutputDir, ModuleChunk.SOURCES));
                   }
                   final String testsOutputDir = getTestsOutputDir(module);
                   if (testsOutputDir == null) {
                     LOG.error("Tests output dir is null for module \"" + module.getName() + "\"");
                   } else {
                     dirs.add(new OutputDir(testsOutputDir, ModuleChunk.TEST_SOURCES));
                   }
                 } else { // both sources and test sources go into the same output
                   if (sourcesOutputDir == null) {
                     LOG.error(
                         "Sources output dir is null for module \"" + module.getName() + "\"");
                   } else {
                     dirs.add(new OutputDir(sourcesOutputDir, ModuleChunk.ALL_SOURCES));
                   }
                 }
               }
             });
   } else { // chunk has several modules
     final File outputDir = FileUtil.createTempDirectory("compile", "output");
     fileToDelete = outputDir;
     dirs.add(new OutputDir(outputDir.getPath(), ModuleChunk.ALL_SOURCES));
   }
   return fileToDelete;
 }
Ejemplo n.º 5
0
  @Nullable
  private Pair<String, String> moveToRealLocation(
      String tempOutputDir,
      String pathToClass,
      VirtualFile sourceFile,
      final List<File> filesToRefresh) {
    final Module module = myCompileContext.getModuleByFile(sourceFile);
    if (module == null) {
      final String message =
          "Cannot determine module for source file: "
              + sourceFile.getPresentableUrl()
              + ";\nCorresponding output file: "
              + pathToClass;
      LOG.info(message);
      myCompileContext.addMessage(
          CompilerMessageCategory.WARNING, message, sourceFile.getUrl(), -1, -1);
      // do not move: looks like source file has been invalidated, need recompilation
      return new Pair<String, String>(tempOutputDir, pathToClass);
    }
    final String realOutputDir;
    if (myCompileContext.isInTestSourceContent(sourceFile)) {
      realOutputDir = getTestsOutputDir(module);
      LOG.assertTrue(realOutputDir != null);
    } else {
      realOutputDir = getOutputDir(module);
      LOG.assertTrue(realOutputDir != null);
    }

    if (FileUtil.pathsEqual(tempOutputDir, realOutputDir)) { // no need to move
      filesToRefresh.add(new File(pathToClass));
      return new Pair<String, String>(realOutputDir, pathToClass);
    }

    final String realPathToClass = realOutputDir + pathToClass.substring(tempOutputDir.length());
    final File fromFile = new File(pathToClass);
    final File toFile = new File(realPathToClass);

    boolean success = fromFile.renameTo(toFile);
    if (!success) {
      // assuming cause of the fail: intermediate dirs do not exist
      FileUtil.createParentDirs(toFile);
      // retry after making non-existent dirs
      success = fromFile.renameTo(toFile);
    }
    if (!success) { // failed to move the file: e.g. because source and destination reside on
                    // different mountpoints.
      try {
        FileUtil.copy(fromFile, toFile);
        FileUtil.delete(fromFile);
        success = true;
      } catch (IOException e) {
        LOG.info(e);
        success = false;
      }
    }
    if (success) {
      filesToRefresh.add(toFile);
      return new Pair<String, String>(realOutputDir, realPathToClass);
    }
    return null;
  }
  private static GenerationItem[] doGenerate(
      @NotNull final CompileContext context,
      @NotNull final GenerationItem[] items,
      VirtualFile outputRootDirectory) {
    if (context.getProject().isDisposed()) {
      return EMPTY_GENERATION_ITEM_ARRAY;
    }

    // we have one item per module there, so clear output directory
    final String genRootPath = FileUtil.toSystemDependentName(outputRootDirectory.getPath());
    final File genRootDir = new File(genRootPath);
    if (genRootDir.exists()) {
      if (!FileUtil.delete(genRootDir)) {
        context.addMessage(
            CompilerMessageCategory.ERROR, "Cannot delete directory " + genRootPath, null, -1, -1);
        return EMPTY_GENERATION_ITEM_ARRAY;
      }
      if (!genRootDir.mkdir()) {
        context.addMessage(
            CompilerMessageCategory.ERROR, "Cannot create directory " + genRootPath, null, -1, -1);
        return EMPTY_GENERATION_ITEM_ARRAY;
      }
    }

    final List<GenerationItem> results = new ArrayList<GenerationItem>(items.length);
    for (final GenerationItem item : items) {
      if (item instanceof MyGenerationItem) {
        final MyGenerationItem genItem = (MyGenerationItem) item;

        if (!AndroidCompileUtil.isModuleAffected(context, genItem.myModule)) {
          continue;
        }

        boolean success = true;

        for (final VirtualFile sourceFile : genItem.myFiles) {
          final String depFolderOsPath =
              getDependencyFolder(context.getProject(), sourceFile, outputRootDirectory);

          try {
            final Map<CompilerMessageCategory, List<String>> messages =
                AndroidCompileUtil.toCompilerMessageCategoryKeys(
                    AndroidRenderscript.execute(
                        genItem.mySdkLocation,
                        genItem.myAndroidTarget,
                        sourceFile.getPath(),
                        genRootPath,
                        depFolderOsPath,
                        genItem.myRawDirPath));

            ApplicationManager.getApplication()
                .runReadAction(
                    new Runnable() {
                      public void run() {
                        if (context.getProject().isDisposed()) {
                          return;
                        }
                        addMessages(context, messages, sourceFile.getUrl());
                      }
                    });

            if (messages.get(CompilerMessageCategory.ERROR).size() > 0) {
              success = false;
            }
          } catch (final IOException e) {
            ApplicationManager.getApplication()
                .runReadAction(
                    new Runnable() {
                      public void run() {
                        if (context.getProject().isDisposed()) return;
                        context.addMessage(
                            CompilerMessageCategory.ERROR,
                            e.getMessage(),
                            sourceFile.getUrl(),
                            -1,
                            -1);
                      }
                    });
            success = false;
          }
        }

        if (success) {
          results.add(genItem);
        }
      }
    }
    outputRootDirectory.refresh(false, true);
    return results.toArray(new GenerationItem[results.size()]);
  }
  public static void generate(GeneratingCompiler compiler, final CompileContext context) {
    if (context == null) {
      return;
    }

    final Set<Module> affectedModules = new HashSet<Module>();
    Collections.addAll(affectedModules, context.getCompileScope().getAffectedModules());

    ApplicationManager.getApplication()
        .invokeAndWait(
            new Runnable() {
              @Override
              public void run() {
                for (Module module : affectedModules) {
                  if (module.isDisposed() || module.getProject().isDisposed()) {
                    continue;
                  }

                  final AndroidFacet facet = AndroidFacet.getInstance(module);
                  if (facet != null) {
                    AndroidCompileUtil.createGenModulesAndSourceRoots(facet);
                  }
                }
              }
            },
            ModalityState.defaultModalityState());

    List<GeneratingCompiler.GenerationItem> itemsToGenerate =
        new ArrayList<GeneratingCompiler.GenerationItem>();
    for (GeneratingCompiler.GenerationItem item : compiler.getGenerationItems(context)) {
      if (affectedModules.contains(item.getModule())) {
        itemsToGenerate.add(item);
      }
    }

    GeneratingCompiler.GenerationItem[] items =
        itemsToGenerate.toArray(new GeneratingCompiler.GenerationItem[itemsToGenerate.size()]);

    final boolean[] run = {true};
    final VirtualFile[] files = getFilesToCheckReadonlyStatus(items);
    if (files.length > 0) {
      ApplicationManager.getApplication()
          .invokeAndWait(
              new Runnable() {
                @Override
                public void run() {
                  ApplicationManager.getApplication()
                      .runReadAction(
                          new Runnable() {
                            @Override
                            public void run() {
                              final Project project = context.getProject();
                              run[0] =
                                  !project.isDisposed()
                                      && ReadonlyStatusHandler.ensureFilesWritable(project, files);
                            }
                          });
                }
              },
              ModalityState.defaultModalityState());
    }

    if (run[0]) {
      compiler.generate(context, items, null);
    }
  }