private static void takeLine(
      final Project project,
      String line,
      StringBuilder sb,
      GitLogParser parser,
      SymbolicRefsI refs,
      VirtualFile root,
      VcsException[] exc,
      GitLineHandler h,
      AsynchConsumer<GitCommit> gitCommitConsumer) {
    final String text = sb.toString();
    sb.setLength(0);
    sb.append(line);
    if (text.length() == 0) return;
    GitLogRecord record = parser.parseOneRecord(text);

    final GitCommit gitCommit;
    try {
      gitCommit = createCommit(project, refs, root, record);
    } catch (VcsException e) {
      exc[0] = e;
      h.cancel();
      return;
    }
    gitCommitConsumer.consume(gitCommit);
  }
  public static String getUnescapedText(
      PsiFile file,
      @Nullable final PsiElement startElement,
      @Nullable final PsiElement endElement) {
    final InjectedLanguageManager manager = InjectedLanguageManager.getInstance(file.getProject());
    if (manager.getInjectionHost(file) == null) {
      return file.getText()
          .substring(
              startElement == null ? 0 : startElement.getTextRange().getStartOffset(),
              endElement == null
                  ? file.getTextLength()
                  : endElement.getTextRange().getStartOffset());
    }
    final StringBuilder sb = new StringBuilder();
    file.accept(
        new PsiRecursiveElementWalkingVisitor() {

          Boolean myState = startElement == null ? Boolean.TRUE : null;

          @Override
          public void visitElement(PsiElement element) {
            if (element == startElement) myState = Boolean.TRUE;
            if (element == endElement) myState = Boolean.FALSE;
            if (Boolean.FALSE == myState) return;
            if (Boolean.TRUE == myState && element.getFirstChild() == null) {
              sb.append(getUnescapedLeafText(element, false));
            } else {
              super.visitElement(element);
            }
          }
        });
    return sb.toString();
  }
  private static Couple<Integer> composeText(
      StringBuilder sb,
      List<Pair<String, HighlightInfo>> list,
      int index,
      String text,
      int endPos,
      int startPos) {
    int i = index;
    while (i < list.size()) {
      Pair<String, HighlightInfo> pair = list.get(i);
      HighlightInfo info = pair.second;
      if (info.endOffset <= startPos) {
        break;
      }

      String severity = pair.first;
      HighlightInfo prev = i < list.size() - 1 ? list.get(i + 1).second : null;

      sb.insert(0, text.substring(info.endOffset, endPos));
      sb.insert(0, "</" + severity + ">");
      endPos = info.endOffset;
      if (prev != null && prev.endOffset > info.startOffset) {
        Couple<Integer> result = composeText(sb, list, i + 1, text, endPos, info.startOffset);
        i = result.first - 1;
        endPos = result.second;
      }
      sb.insert(0, text.substring(info.startOffset, endPos));
      sb.insert(0, "<" + severity + " descr=\"" + info.getDescription() + "\">");

      endPos = info.startOffset;
      i++;
    }

    return Couple.newOne(i, endPos);
  }
    private static void appendAbbreviated(
        StringBuilder to,
        String text,
        int start,
        int end,
        FontMetrics metrics,
        int maxWidth,
        boolean replaceLineTerminators) {
      int abbreviationLength =
          abbreviationLength(text, start, end, metrics, maxWidth, replaceLineTerminators);

      if (!replaceLineTerminators) {
        to.append(text, start, start + abbreviationLength);
      } else {
        CharSequenceSubSequence subSeq =
            new CharSequenceSubSequence(text, start, start + abbreviationLength);
        for (LineTokenizer lt = new LineTokenizer(subSeq); !lt.atEnd(); lt.advance()) {
          to.append(subSeq, lt.getOffset(), lt.getOffset() + lt.getLength());
          if (lt.getLineSeparatorLength() > 0) {
            to.append(RETURN_SYMBOL);
          }
        }
      }

      if (abbreviationLength != end - start) {
        to.append(ABBREVIATION_SUFFIX);
      }
    }
Beispiel #5
0
 public static String getLocationMethodQName(@NotNull Location location) {
   StringBuilder res = new StringBuilder();
   ReferenceType type = location.declaringType();
   if (type != null) {
     res.append(type.name()).append('.');
   }
   res.append(location.method().name());
   return res.toString();
 }
  public static String composeText(
      final Map<String, ExpectedHighlightingSet> types,
      Collection<HighlightInfo> infos,
      String text) {
    // filter highlighting data and map each highlighting to a tag name
    List<Pair<String, HighlightInfo>> list =
        ContainerUtil.mapNotNull(
            infos,
            new NullableFunction<HighlightInfo, Pair<String, HighlightInfo>>() {
              @Override
              public Pair<String, HighlightInfo> fun(HighlightInfo info) {
                for (Map.Entry<String, ExpectedHighlightingSet> entry : types.entrySet()) {
                  final ExpectedHighlightingSet set = entry.getValue();
                  if (set.enabled
                      && set.severity == info.getSeverity()
                      && set.endOfLine == info.isAfterEndOfLine()) {
                    return Pair.create(entry.getKey(), info);
                  }
                }
                return null;
              }
            });

    // sort filtered highlighting data by end offset in descending order
    Collections.sort(
        list,
        new Comparator<Pair<String, HighlightInfo>>() {
          @Override
          public int compare(Pair<String, HighlightInfo> o1, Pair<String, HighlightInfo> o2) {
            HighlightInfo i1 = o1.second;
            HighlightInfo i2 = o2.second;

            int byEnds = i2.endOffset - i1.endOffset;
            if (byEnds != 0) return byEnds;

            if (!i1.isAfterEndOfLine() && !i2.isAfterEndOfLine()) {
              int byStarts = i1.startOffset - i2.startOffset;
              if (byStarts != 0) return byStarts;
            } else {
              int byEOL = Comparing.compare(i2.isAfterEndOfLine(), i1.isAfterEndOfLine());
              if (byEOL != 0) return byEOL;
            }

            int bySeverity = i2.getSeverity().compareTo(i1.getSeverity());
            if (bySeverity != 0) return bySeverity;

            return Comparing.compare(i1.getDescription(), i2.getDescription());
          }
        });

    // combine highlighting data with original text
    StringBuilder sb = new StringBuilder();
    Couple<Integer> result = composeText(sb, list, 0, text, text.length(), 0);
    sb.insert(0, text.substring(0, result.second));
    return sb.toString();
  }
 private void commitToOriginalInner() {
   final String text = myNewDocument.getText();
   final Map<
           PsiLanguageInjectionHost,
           Set<Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer>>>
       map =
           ContainerUtil.classify(
               myMarkers.iterator(),
               new Convertor<
                   Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer>,
                   PsiLanguageInjectionHost>() {
                 @Override
                 public PsiLanguageInjectionHost convert(
                     final Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer> o) {
                   final PsiElement element = o.third.getElement();
                   return (PsiLanguageInjectionHost) element;
                 }
               });
   PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
   documentManager.commitDocument(myOrigDocument); // commit here and after each manipulator update
   int localInsideFileCursor = 0;
   for (PsiLanguageInjectionHost host : map.keySet()) {
     if (host == null) continue;
     String hostText = host.getText();
     ProperTextRange insideHost = null;
     StringBuilder sb = new StringBuilder();
     for (Trinity<RangeMarker, RangeMarker, SmartPsiElementPointer> entry : map.get(host)) {
       RangeMarker origMarker = entry.first; // check for validity?
       int hostOffset = host.getTextRange().getStartOffset();
       ProperTextRange localInsideHost =
           new ProperTextRange(
               origMarker.getStartOffset() - hostOffset, origMarker.getEndOffset() - hostOffset);
       RangeMarker rangeMarker = entry.second;
       ProperTextRange localInsideFile =
           new ProperTextRange(
               Math.max(localInsideFileCursor, rangeMarker.getStartOffset()),
               rangeMarker.getEndOffset());
       if (insideHost != null) {
         // append unchanged inter-markers fragment
         sb.append(
             hostText.substring(insideHost.getEndOffset(), localInsideHost.getStartOffset()));
       }
       sb.append(
           localInsideFile.getEndOffset() <= text.length() && !localInsideFile.isEmpty()
               ? localInsideFile.substring(text)
               : "");
       localInsideFileCursor = localInsideFile.getEndOffset();
       insideHost = insideHost == null ? localInsideHost : insideHost.union(localInsideHost);
     }
     assert insideHost != null;
     ElementManipulators.getManipulator(host).handleContentChange(host, insideHost, sb.toString());
     documentManager.commitDocument(myOrigDocument);
   }
 }
  private static Couple<Integer> composeText(
      StringBuilder sb,
      List<Pair<String, HighlightInfo>> list,
      int index,
      String text,
      int endPos,
      int startPos,
      boolean showAttributesKeys) {
    int i = index;
    while (i < list.size()) {
      Pair<String, HighlightInfo> pair = list.get(i);
      HighlightInfo info = pair.second;
      if (info.endOffset <= startPos) {
        break;
      }

      String severity = pair.first;
      HighlightInfo prev = i < list.size() - 1 ? list.get(i + 1).second : null;

      sb.insert(0, text.substring(info.endOffset, endPos));
      sb.insert(0, "</" + severity + ">");
      endPos = info.endOffset;
      if (prev != null && prev.endOffset > info.startOffset) {
        Couple<Integer> result =
            composeText(sb, list, i + 1, text, endPos, info.startOffset, showAttributesKeys);
        i = result.first - 1;
        endPos = result.second;
      }
      sb.insert(0, text.substring(info.startOffset, endPos));

      String str =
          "<"
              + severity
              + " descr=\""
              + StringUtil.escapeQuotes(String.valueOf(info.getDescription()))
              + "\"";
      if (showAttributesKeys) {
        str += " textAttributesKey=\"" + info.forcedTextAttributesKey + "\"";
      }
      str += ">";
      sb.insert(0, str);

      endPos = info.startOffset;
      i++;
    }

    return Couple.of(i, endPos);
  }
 @NotNull
 private String calcText() {
   StringBuilder text = new StringBuilder();
   CharSequence hostText = myDelegate.getCharsSequence();
   synchronized (myLock) {
     for (PsiLanguageInjectionHost.Shred shred : myShreds) {
       Segment hostRange = shred.getHostRangeMarker();
       if (hostRange != null) {
         text.append(shred.getPrefix());
         text.append(hostText, hostRange.getStartOffset(), hostRange.getEndOffset());
         text.append(shred.getSuffix());
       }
     }
   }
   return text.toString();
 }
    @Nullable
    public GitLogRecord acceptLine(String s) {
      final boolean lineEnd = s.startsWith(GitLogParser.RECORD_START);
      if (lineEnd && (!myNotStarted)) {
        final String line = myBuffer.toString();
        myBuffer.setLength(0);
        myBuffer.append(s.substring(GitLogParser.RECORD_START.length()));

        return processResult(line);
      } else {
        myBuffer.append(lineEnd ? s.substring(GitLogParser.RECORD_START.length()) : s);
        myBuffer.append("\n");
      }
      myNotStarted = false;

      return null;
    }
Beispiel #11
0
    @NonNls
    String getSignature() {
      if (eof()) return "";

      switch (get()) {
        case 'Z':
          return "boolean";
        case 'B':
          return "byte";
        case 'C':
          return "char";
        case 'S':
          return "short";
        case 'I':
          return "int";
        case 'J':
          return "long";
        case 'F':
          return "float";
        case 'D':
          return "double";
        case 'V':
          return "void";
        case 'L':
          int start = pos;
          pos = buffer.indexOf(';', start) + 1;
          LOG.assertTrue(pos > 0);
          return buffer.substring(start, pos - 1).replace('/', '.');
        case '[':
          return getSignature() + "[]";
        case '(':
          StringBuilder result = new StringBuilder("(");
          String separator = "";
          while (peek() != ')') {
            result.append(separator);
            result.append(getSignature());
            separator = ", ";
          }
          get();
          result.append(")");
          return getSignature() + " " + getClassName() + "." + getMethodName() + " " + result;
        default:
          //          LOG.assertTrue(false, "unknown signature " + buffer);
          return null;
      }
    }
  @NonNls
  public static String toString(Iterable<?> collection) {
    if (!collection.iterator().hasNext()) {
      return "<empty>";
    }

    final StringBuilder builder = new StringBuilder();
    for (final Object o : collection) {
      if (o instanceof THashSet) {
        builder.append(new TreeSet<Object>((THashSet) o));
      } else {
        builder.append(o);
      }
      builder.append("\n");
    }
    return builder.toString();
  }
 private static void generateTestClassCode(
     StringBuilder code, String className, Collection<String> customRunners, boolean isSuite) {
   code.append(TEST_RUNNER_VAR)
       .append(".")
       .append(isSuite ? "addTestSuiteClass(" : "addTestClass(")
       .append(className)
       .append(");\n");
   generateReferences(code, className, customRunners);
 }
    private void updateText(Rectangle clip) {
      FontMetrics fontMetrics =
          ((EditorImpl) getEditor())
              .getFontMetrics(
                  myTextAttributes != null ? myTextAttributes.getFontType() : Font.PLAIN);
      Insets insets = getInsets();
      int maxLineWidth = getWidth() - (insets != null ? insets.left + insets.right : 0);

      myDocumentTextBuilder.setLength(0);

      boolean singleLineMode = getHeight() / (float) getEditor().getLineHeight() < 1.1f;
      if (singleLineMode) {
        appendAbbreviated(
            myDocumentTextBuilder,
            myRawText,
            0,
            myRawText.length(),
            fontMetrics,
            maxLineWidth,
            true);
      } else {
        int lineHeight = getEditor().getLineHeight();
        int firstVisibleLine = clip.y / lineHeight;
        float visibleLinesCountFractional = clip.height / (float) lineHeight;
        int linesToAppend = 1 + (int) visibleLinesCountFractional;

        LineTokenizer lt = new LineTokenizer(myRawText);
        for (int line = 0; !lt.atEnd() && line < firstVisibleLine; lt.advance(), line++) {
          myDocumentTextBuilder.append('\n');
        }

        for (int line = 0; !lt.atEnd() && line < linesToAppend; lt.advance(), line++) {
          int start = lt.getOffset();
          int end = start + lt.getLength();
          appendAbbreviated(
              myDocumentTextBuilder, myRawText, start, end, fontMetrics, maxLineWidth, false);
          if (lt.getLineSeparatorLength() > 0) {
            myDocumentTextBuilder.append('\n');
          }
        }
      }

      setTextToEditor(myDocumentTextBuilder.toString());
    }
 private static void generateTestMethodCode(
     StringBuilder code, String className, String methodName, Collection<String> customRunners) {
   code.append(TEST_RUNNER_VAR)
       .append(".addTestMethod(")
       .append(className)
       .append(", \"")
       .append(methodName)
       .append("\");\n");
   generateReferences(code, className, customRunners);
 }
 public void printToHistory(@NotNull final List<Pair<String, TextAttributes>> attributedText) {
   ApplicationManager.getApplication().assertIsDispatchThread();
   if (LOG.isDebugEnabled()) {
     LOG.debug("printToHistory(): " + attributedText.size());
   }
   final boolean scrollToEnd = shouldScrollHistoryToEnd();
   final int[] offsets = new int[attributedText.size() + 1];
   int i = 0;
   offsets[i] = 0;
   final StringBuilder sb = new StringBuilder();
   for (final Pair<String, TextAttributes> pair : attributedText) {
     sb.append(StringUtil.convertLineSeparators(pair.getFirst()));
     offsets[++i] = sb.length();
   }
   final DocumentEx history = myHistoryViewer.getDocument();
   final int oldHistoryLength = history.getTextLength();
   appendToHistoryDocument(history, sb.toString());
   assert oldHistoryLength + offsets[i] == history.getTextLength()
       : "unexpected history length "
           + oldHistoryLength
           + " "
           + offsets[i]
           + " "
           + history.getTextLength();
   LOG.debug("printToHistory(): text processed");
   final MarkupModel markupModel = DocumentMarkupModel.forDocument(history, myProject, true);
   i = 0;
   for (final Pair<String, TextAttributes> pair : attributedText) {
     markupModel.addRangeHighlighter(
         oldHistoryLength + offsets[i],
         oldHistoryLength + offsets[i + 1],
         HighlighterLayer.SYNTAX,
         pair.getSecond(),
         HighlighterTargetArea.EXACT_RANGE);
     ++i;
   }
   LOG.debug("printToHistory(): markup added");
   if (scrollToEnd) {
     scrollHistoryToEnd();
   }
   queueUiUpdate(scrollToEnd);
   LOG.debug("printToHistory(): completed");
 }
 private void validateEncoding(ModuleChunk chunk, String chunkPresentableName) {
   final CompilerEncodingService es = CompilerEncodingService.getInstance(myProject);
   Charset charset = null;
   for (Module module : chunk.getModules()) {
     final Charset moduleCharset = es.getPreferredModuleEncoding(module);
     if (charset == null) {
       charset = moduleCharset;
     } else {
       if (!Comparing.equal(charset, moduleCharset)) {
         // warn user
         final Charset chunkEncoding = CompilerEncodingService.getPreferredModuleEncoding(chunk);
         final StringBuilder message = new StringBuilder();
         message.append("Modules in chunk [");
         message.append(chunkPresentableName);
         message.append("] configured to use different encodings.\n");
         if (chunkEncoding != null) {
           message
               .append("\"")
               .append(chunkEncoding.name())
               .append("\" encoding will be used to compile the chunk");
         } else {
           message.append("Default compiler encoding will be used to compile the chunk");
         }
         myCompileContext.addMessage(
             CompilerMessageCategory.INFORMATION, message.toString(), null, -1, -1);
         break;
       }
     }
   }
 }
 public static String toString(Collection<?> collection, String separator) {
   List<String> list =
       ContainerUtil.map2List(
           collection,
           new Function<Object, String>() {
             @Override
             public String fun(final Object o) {
               return String.valueOf(o);
             }
           });
   Collections.sort(list);
   StringBuilder builder = new StringBuilder();
   boolean flag = false;
   for (final String o : list) {
     if (flag) {
       builder.append(separator);
     }
     builder.append(o);
     flag = true;
   }
   return builder.toString();
 }
 private static void generateReferences(
     StringBuilder code, String className, Collection<String> classes) {
   int i = 1;
   for (String qname : classes) {
     code.append("var __ref_")
         .append(className.replace(".", "_"))
         .append("_")
         .append(i++)
         .append("_ : ")
         .append(qname)
         .append(";\n");
   }
 }
 @Override
 public String getUnescapedText(@NotNull final PsiElement injectedNode) {
   final StringBuilder text = new StringBuilder(injectedNode.getTextLength());
   // gather text from (patched) leaves
   injectedNode.accept(
       new PsiRecursiveElementWalkingVisitor() {
         @Override
         public void visitElement(PsiElement element) {
           String unescaped = element.getCopyableUserData(UNESCAPED_TEXT);
           if (unescaped != null) {
             text.append(unescaped);
             return;
           }
           if (element.getFirstChild() == null) {
             text.append(element.getText());
             return;
           }
           super.visitElement(element);
         }
       });
   return text.toString();
 }
 private static void generateImportCode(StringBuilder imports, String qname) {
   imports.append("import ").append(qname).append(";\n");
 }
  public static String composeText(
      final Map<String, ExpectedHighlightingSet> types,
      Collection<HighlightInfo> infos,
      String text) {
    // filter highlighting data and map each highlighting to a tag name
    List<Pair<String, HighlightInfo>> list =
        ContainerUtil.mapNotNull(
            infos,
            (NullableFunction<HighlightInfo, Pair<String, HighlightInfo>>)
                info -> {
                  for (Map.Entry<String, ExpectedHighlightingSet> entry : types.entrySet()) {
                    final ExpectedHighlightingSet set = entry.getValue();
                    if (set.enabled
                        && set.severity == info.getSeverity()
                        && set.endOfLine == info.isAfterEndOfLine()) {
                      return Pair.create(entry.getKey(), info);
                    }
                  }
                  return null;
                });

    boolean showAttributesKeys = false;
    for (ExpectedHighlightingSet eachSet : types.values()) {
      for (HighlightInfo eachInfo : eachSet.infos) {
        if (eachInfo.forcedTextAttributesKey != null) {
          showAttributesKeys = true;
          break;
        }
      }
    }

    // sort filtered highlighting data by end offset in descending order
    Collections.sort(
        list,
        (o1, o2) -> {
          HighlightInfo i1 = o1.second;
          HighlightInfo i2 = o2.second;

          int byEnds = i2.endOffset - i1.endOffset;
          if (byEnds != 0) return byEnds;

          if (!i1.isAfterEndOfLine() && !i2.isAfterEndOfLine()) {
            int byStarts = i1.startOffset - i2.startOffset;
            if (byStarts != 0) return byStarts;
          } else {
            int byEOL = Comparing.compare(i2.isAfterEndOfLine(), i1.isAfterEndOfLine());
            if (byEOL != 0) return byEOL;
          }

          int bySeverity = i2.getSeverity().compareTo(i1.getSeverity());
          if (bySeverity != 0) return bySeverity;

          return Comparing.compare(i1.getDescription(), i2.getDescription());
        });

    // combine highlighting data with original text
    StringBuilder sb = new StringBuilder();
    Couple<Integer> result = composeText(sb, list, 0, text, text.length(), 0, showAttributesKeys);
    sb.insert(0, text.substring(0, result.second));
    return sb.toString();
  }
  private void runAction(final EvaluationContextImpl context, LocatableEvent event) {
    if (LOG_ENABLED || LOG_EXPRESSION_ENABLED) {
      final StringBuilder buf = StringBuilderSpinAllocator.alloc();
      try {
        if (LOG_ENABLED) {
          buf.append(getEventMessage(event));
          buf.append("\n");
        }
        final DebugProcessImpl debugProcess = context.getDebugProcess();
        final TextWithImports expressionToEvaluate = getLogMessage();
        if (LOG_EXPRESSION_ENABLED
            && expressionToEvaluate != null
            && !"".equals(expressionToEvaluate.getText())) {
          if (!debugProcess.isAttached()) {
            return;
          }

          try {
            ExpressionEvaluator evaluator =
                DebuggerInvocationUtil.commitAndRunReadAction(
                    getProject(),
                    new EvaluatingComputable<ExpressionEvaluator>() {
                      public ExpressionEvaluator compute() throws EvaluateException {
                        return EvaluatorBuilderImpl.build(
                            expressionToEvaluate,
                            ContextUtil.getContextElement(context),
                            ContextUtil.getSourcePosition(context));
                      }
                    });
            final Value eval = evaluator.evaluate(context);
            final String result =
                eval instanceof VoidValue ? "void" : DebuggerUtils.getValueAsString(context, eval);
            buf.append(result);
          } catch (EvaluateException e) {
            buf.append(DebuggerBundle.message("error.unable.to.evaluate.expression"));
            buf.append(" \"");
            buf.append(expressionToEvaluate);
            buf.append("\"");
            buf.append(" : ");
            buf.append(e.getMessage());
          }
          buf.append("\n");
        }
        if (buf.length() > 0) {
          debugProcess.printToConsole(buf.toString());
        }
      } finally {
        StringBuilderSpinAllocator.dispose(buf);
      }
    }
  }
  public boolean execute(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(
                new NullableComputable<RuntimeConfigurationException>() {
                  public RuntimeConfigurationException compute() {
                    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(
                      new NullableComputable<Set<String>>() {
                        public Set<String> compute() {
                          if (DumbService.getInstance(myProject).isDumb()) return null;
                          Set<String> result = new THashSet<>();
                          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());
        }
        break;

      case Method:
        {
          Set<String> customRunners =
              ApplicationManager.getApplication()
                  .runReadAction(
                      new NullableComputable<Set<String>>() {
                        public Set<String> compute() {
                          if (DumbService.getInstance(myProject).isDumb()) return null;
                          Set<String> result = new THashSet<>();
                          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);
        }
        break;

      case Package:
        {
          final Collection<Pair<String, Set<String>>> classes =
              ApplicationManager.getApplication()
                  .runReadAction(
                      new NullableComputable<Collection<Pair<String, Set<String>>>>() {
                        public Collection<Pair<String, Set<String>>> compute() {
                          if (DumbService.getInstance(myProject).isDumb()) return null;

                          final Collection<Pair<String, Set<String>>> result = new ArrayList<>();
                          JSPackageIndex.processElementsInScopeRecursive(
                              params.getPackageName(),
                              new JSPackageIndex.PackageQualifiedElementsProcessor() {
                                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 THashSet<>();
                                      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);
          }
        }
        break;
      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()) ok &= FileUtil.delete(tmpDir);
    if (!tmpDir.isDirectory()) ok &= tmpDir.mkdirs();
    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;
  }
 public GitLogRecord processLast() {
   return processResult(myBuffer.toString());
 }
  private boolean shouldReloadProject(final Project project) {
    if (project.isDisposed()) return false;
    final HashSet<Pair<VirtualFile, StateStorage>> causes =
        new HashSet<Pair<VirtualFile, StateStorage>>();

    synchronized (myChangedProjectFiles) {
      final List<Pair<VirtualFile, StateStorage>> changes = myChangedProjectFiles.remove(project);
      if (changes != null) {
        causes.addAll(changes);
      }

      if (causes.isEmpty()) return false;
    }

    final boolean[] reloadOk = {false};

    ApplicationManager.getApplication()
        .runWriteAction(
            new Runnable() {
              @Override
              public void run() {
                try {
                  LOG.debug("[RELOAD] Reloading project/components...");
                  reloadOk[0] = ((ProjectEx) project).getStateStore().reload(causes);
                } catch (StateStorageException e) {
                  Messages.showWarningDialog(
                      ProjectBundle.message("project.reload.failed", e.getMessage()),
                      ProjectBundle.message("project.reload.failed.title"));
                } catch (IOException e) {
                  Messages.showWarningDialog(
                      ProjectBundle.message("project.reload.failed", e.getMessage()),
                      ProjectBundle.message("project.reload.failed.title"));
                }
              }
            });
    if (reloadOk[0]) return false;

    String message;
    if (causes.size() == 1) {
      message =
          ProjectBundle.message(
              "project.reload.external.change.single",
              causes.iterator().next().first.getPresentableUrl());
    } else {
      StringBuilder filesBuilder = new StringBuilder();
      boolean first = true;
      Set<String> alreadyShown = new HashSet<String>();
      for (Pair<VirtualFile, StateStorage> cause : causes) {
        String url = cause.first.getPresentableUrl();
        if (!alreadyShown.contains(url)) {
          if (alreadyShown.size() > 10) {
            filesBuilder
                .append("\n" + "and ")
                .append(causes.size() - alreadyShown.size())
                .append(" more");
            break;
          }
          if (!first) filesBuilder.append("\n");
          first = false;
          filesBuilder.append(url);
          alreadyShown.add(url);
        }
      }
      message =
          ProjectBundle.message("project.reload.external.change.multiple", filesBuilder.toString());
    }

    return Messages.showTwoStepConfirmationDialog(
            message,
            ProjectBundle.message("project.reload.external.change.title"),
            "Reload project",
            Messages.getQuestionIcon())
        == 0;
  }