public boolean execute()

in flex/src/com/intellij/lang/javascript/flex/flexunit/FlexUnitPrecompileTask.java [62:299]


  public boolean execute(@NotNull CompileContext context) {
    final RunConfiguration runConfiguration = CompileStepBeforeRun.getRunConfiguration(context.getCompileScope());
    if (!(runConfiguration instanceof FlexUnitRunConfiguration)) {
      return true;
    }

    final Ref<Boolean> isDumb = new Ref<>(false);
    final RuntimeConfigurationException validationError =
      ApplicationManager.getApplication().runReadAction((NullableComputable<RuntimeConfigurationException>)() -> {
        if (DumbService.getInstance(myProject).isDumb()) {
          isDumb.set(true);
          return null;
        }
        try {
          runConfiguration.checkConfiguration();
          return null;
        }
        catch (RuntimeConfigurationException e) {
          return e;
        }
      });

    if (isDumb.get()) {
      context.addMessage(CompilerMessageCategory.ERROR, FlexBundle.message("dumb.mode.flex.unit.warning"), null, -1, -1);
      return false;
    }

    if (validationError != null) {
      context
        .addMessage(CompilerMessageCategory.ERROR, FlexBundle.message("configuration.not.valid", validationError.getMessage()), null, -1,
                    -1);
      return false;
    }

    int flexUnitPort = ServerConnectionBase.getFreePort(FLEX_UNIT_PORT_START, PORTS_ATTEMPT_NUMBER);
    if (flexUnitPort == -1) {
      context.addMessage(CompilerMessageCategory.ERROR, FlexBundle.message("no.free.port"), null, -1, -1);
      return false;
    }

    final int socketPolicyPort;
    if (SystemInfo.isWindows && ServerConnectionBase.tryPort(SwfPolicyFileConnection.DEFAULT_PORT)) {
      socketPolicyPort = SwfPolicyFileConnection.DEFAULT_PORT;
    }
    else {
      socketPolicyPort = ServerConnectionBase.getFreePort(SWC_POLICY_PORT_START, PORTS_ATTEMPT_NUMBER);
    }

    if (socketPolicyPort == -1) {
      context.addMessage(CompilerMessageCategory.ERROR, FlexBundle.message("no.free.port"), null, -1, -1);
      return false;
    }

    final FlexUnitRunnerParameters params = ((FlexUnitRunConfiguration)runConfiguration).getRunnerParameters();
    params.setPort(flexUnitPort);
    params.setSocketPolicyPort(socketPolicyPort);

    final Ref<Module> moduleRef = new Ref<>();
    final Ref<FlexBuildConfiguration> bcRef = new Ref<>();
    final Ref<FlexUnitSupport> supportRef = new Ref<>();

    ApplicationManager.getApplication().runReadAction(() -> {
      if (DumbService.getInstance(myProject).isDumb()) return;

      try {
        final Pair<Module, FlexBuildConfiguration> moduleAndBC = params.checkAndGetModuleAndBC(myProject);
        moduleRef.set(moduleAndBC.first);
        bcRef.set(moduleAndBC.second);
        supportRef.set(FlexUnitSupport.getSupport(moduleAndBC.second, moduleAndBC.first));
      }
      catch (RuntimeConfigurationError e) {
        // already checked above, can't happen
        throw new RuntimeException(e);
      }
    });

    final Module module = moduleRef.get();
    final FlexBuildConfiguration bc = bcRef.get();
    final FlexUnitSupport support = supportRef.get();

    if (bc == null || support == null) {
      context.addMessage(CompilerMessageCategory.ERROR, FlexBundle.message("dumb.mode.flex.unit.warning"), null, -1, -1);
      return false;
    }

    final GlobalSearchScope moduleScope = GlobalSearchScope.moduleScope(module);

    StringBuilder imports = new StringBuilder();
    StringBuilder code = new StringBuilder();

    final boolean flexUnit4;
    switch (params.getScope()) {
      case Class -> {
        final Ref<Boolean> isFlexUnit1Suite = new Ref<>();
        final Ref<Boolean> isSuite = new Ref<>();
        Set<String> customRunners = ApplicationManager.getApplication().runReadAction((NullableComputable<Set<String>>)() -> {
          if (DumbService.getInstance(myProject).isDumb()) return null;
          Set<String> result = new HashSet<>();
          final JSClass clazz = (JSClass)ActionScriptClassResolver.findClassByQNameStatic(params.getClassName(), moduleScope);
          collectCustomRunners(result, clazz, support, null);
          isFlexUnit1Suite.set(support.isFlexUnit1SuiteSubclass(clazz));
          isSuite.set(support.isSuite(clazz));
          return result;
        });

        if (customRunners == null) {
          context.addMessage(CompilerMessageCategory.ERROR, FlexBundle.message("dumb.mode.flex.unit.warning"), null, -1, -1);
          return false;
        }
        // FlexUnit4 can't run FlexUnit1 TestSuite subclasses, fallback to FlexUnit1 runner
        flexUnit4 = support.flexUnit4Present && !isFlexUnit1Suite.get();
        generateImportCode(imports, params.getClassName(), customRunners);
        generateTestClassCode(code, params.getClassName(), customRunners, isSuite.get());
      }
      case Method -> {
        Set<String> customRunners = ApplicationManager.getApplication().runReadAction((NullableComputable<Set<String>>)() -> {
          if (DumbService.getInstance(myProject).isDumb()) return null;
          Set<String> result = new HashSet<>();
          final JSClass clazz = (JSClass)ActionScriptClassResolver.findClassByQNameStatic(params.getClassName(), moduleScope);
          collectCustomRunners(result, clazz, support, null);
          return result;
        });
        if (customRunners == null) {
          context.addMessage(CompilerMessageCategory.ERROR, FlexBundle.message("dumb.mode.flex.unit.warning"), null, -1, -1);
          return false;
        }

        flexUnit4 = support.flexUnit4Present;
        generateImportCode(imports, params.getClassName(), customRunners);
        generateTestMethodCode(code, params.getClassName(), params.getMethodName(), customRunners);
      }
      case Package -> {
        final Collection<Pair<String, Set<String>>> classes =
          ApplicationManager.getApplication().runReadAction((NullableComputable<Collection<Pair<String, Set<String>>>>)() -> {
            if (DumbService.getInstance(myProject).isDumb()) return null;

            final Collection<Pair<String, Set<String>>> result = new ArrayList<>();
            JSPackageIndex
              .processElementsInScopeRecursive(params.getPackageName(), new JSPackageIndex.PackageQualifiedElementsProcessor() {
                @Override
                public boolean process(String qualifiedName, JSPackageIndexInfo.Kind kind, boolean isPublic) {
                  if (kind == JSPackageIndexInfo.Kind.CLASS) {
                    PsiElement clazz = ActionScriptClassResolver.findClassByQNameStatic(qualifiedName, moduleScope);
                    if (clazz instanceof JSClass && support.isTestClass((JSClass)clazz, false)) {
                      Set<String> customRunners = new HashSet<>();
                      collectCustomRunners(customRunners, (JSClass)clazz, support, null);
                      result.add(Pair.create(((JSClass)clazz).getQualifiedName(), customRunners));
                    }
                  }
                  return true;
                }
              }, moduleScope, myProject);
            return result;
          });

        if (classes == null) {
          context.addMessage(CompilerMessageCategory.ERROR, FlexBundle.message("dumb.mode.flex.unit.warning"), null, -1, -1);
          return false;
        }

        if (classes.isEmpty()) {
          String message = MessageFormat.format("No tests found in package ''{0}''", params.getPackageName());
          context.addMessage(CompilerMessageCategory.WARNING, message, null, -1, -1);
          return false;
        }

        flexUnit4 = support.flexUnit4Present;
        for (Pair<String, Set<String>> classAndRunner : classes) {
          generateImportCode(imports, classAndRunner.first, classAndRunner.second);
          generateTestClassCode(code, classAndRunner.first, classAndRunner.second, false);
        }
      }
      default -> {
        flexUnit4 = false;
        assert false : "Unknown scope: " + params.getScope();
      }
    }

    if (!flexUnit4 && bc.isPureAs()) {
      context.addMessage(CompilerMessageCategory.ERROR, FlexBundle.message("cant.execute.flexunit1.for.pure.as.bc"), null, -1, -1);
    }

    String launcherText;
    try {
      launcherText = getLauncherTemplate(bc);
    }
    catch (IOException e) {
      context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
      return false;
    }

    final boolean desktop = bc.getTargetPlatform() == TargetPlatform.Desktop;
    if (desktop) {
      generateImportCode(imports, "flash.desktop.NativeApplication");
    }

    launcherText = replace(launcherText, "/*imports*/", imports.toString());
    launcherText =
      replace(launcherText, "/*test_runner*/", flexUnit4 ? FlexCommonUtils.FLEXUNIT_4_TEST_RUNNER : FlexCommonUtils.FLEXUNIT_1_TEST_RUNNER);
    launcherText = replace(launcherText, "/*code*/", code.toString());
    launcherText = replace(launcherText, "/*port*/", String.valueOf(flexUnitPort));
    launcherText = replace(launcherText, "/*socketPolicyPort*/", String.valueOf(socketPolicyPort));
    launcherText = replace(launcherText, "/*module*/", module.getName());
    if (!bc.isPureAs()) {
      final FlexUnitRunnerParameters.OutputLogLevel logLevel = params.getOutputLogLevel();
      launcherText = replace(launcherText, "/*isLogEnabled*/", logLevel != null ? "1" : "0");
      launcherText = replace(launcherText, "/*logLevel*/", logLevel != null
                                                           ? logLevel.getFlexConstant()
                                                           : FlexUnitRunnerParameters.OutputLogLevel.All.getFlexConstant());
    }


    final File tmpDir = new File(getPathToFlexUnitTempDirectory(myProject));
    boolean ok = true;
    if (tmpDir.isFile() && !FileUtil.delete(tmpDir)) ok = false;
    if (!tmpDir.isDirectory() && !tmpDir.mkdirs()) ok = false;
    if (!ok) {
      final String message =
        UIBundle.message("create.new.folder.could.not.create.folder.error.message", FileUtil.toSystemDependentName(tmpDir.getPath()));
      context.addMessage(CompilerMessageCategory.ERROR, message, null, -1, -1);
      return false;
    }

    final String fileName = FlexCommonUtils.FLEX_UNIT_LAUNCHER + FlexCommonUtils.getFlexUnitLauncherExtension(bc.getNature());
    final File launcherFile = new File(tmpDir, fileName);
    FileUtil.delete(launcherFile);

    try {
      FileUtil.writeToFile(launcherFile, launcherText);
    }
    catch (IOException e) {
      context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
      return false;
    }

    context.putUserData(FILES_TO_DELETE, Collections.singletonList(launcherFile.getPath()));
    return true;
  }