@NotNull
  private static String getMultilineDocCommentText(final @NotNull DartDocComment docComment) {
    final StringBuilder buf = new StringBuilder();
    boolean afterAsterisk = false;

    for (PsiElement child = docComment.getFirstChild();
        child != null;
        child = child.getNextSibling()) {
      final IElementType elementType = child.getNode().getElementType();
      final String text = child.getText();

      if (elementType != DartTokenTypesSets.MULTI_LINE_DOC_COMMENT_START
          && elementType != DartTokenTypesSets.DOC_COMMENT_LEADING_ASTERISK
          && elementType != DartTokenTypesSets.MULTI_LINE_COMMENT_END) {
        int newLinesCount;
        if (child instanceof PsiWhiteSpace
            && (newLinesCount = StringUtil.countNewLines(text)) > 0) {
          buf.append(StringUtil.repeatSymbol('\n', newLinesCount));
        } else {
          if (afterAsterisk && text.startsWith(" ")) {
            buf.append(text.substring(1));
          } else {
            buf.append(text);
          }
        }
      }

      afterAsterisk = elementType == DartTokenTypesSets.DOC_COMMENT_LEADING_ASTERISK;
    }

    return buf.toString();
  }
 public static String generateDoc(
     @Nullable final String signature,
     final boolean signatureIsHtml,
     @Nullable final String docText,
     @Nullable final String containingLibraryName,
     @Nullable final String containingClassDescription,
     @Nullable final String staticType,
     @Nullable final String propagatedType) {
   final boolean hasContainingLibraryName = !StringUtil.isEmpty(containingLibraryName);
   final boolean hasContainingClassDescription = !StringUtil.isEmpty(containingClassDescription);
   final boolean hasStaticType = !StringUtil.isEmpty(staticType);
   final boolean hasPropagatedType = !StringUtil.isEmpty(propagatedType);
   // generate
   final StringBuilder builder = new StringBuilder();
   builder.append("<code>");
   if (signature != null) {
     builder.append("<b>Signature:</b> ");
     if (signatureIsHtml) {
       builder.append(signature);
     } else {
       builder.append(StringUtil.escapeXml(signature));
     }
     builder.append("<br>");
   }
   if (hasContainingLibraryName || hasContainingClassDescription) {
     builder.append("<br>");
     if (hasContainingLibraryName) {
       builder.append("<b>Containing library:</b> ");
       builder.append(StringUtil.escapeXml(containingLibraryName));
       builder.append("<br>");
     }
     if (hasContainingClassDescription) {
       builder.append("<b>Containing class:</b> ");
       builder.append(StringUtil.escapeXml(containingClassDescription));
       builder.append("<br>");
     }
   }
   if (hasStaticType || hasPropagatedType) {
     builder.append("<br>");
     if (hasStaticType) {
       builder.append("<b>Static type:</b> ");
       builder.append(StringUtil.escapeXml(staticType));
       builder.append("<br>");
     }
     if (hasPropagatedType) {
       builder.append("<b>Propagated type:</b> ");
       builder.append(StringUtil.escapeXml(propagatedType));
       builder.append("<br>");
     }
   }
   builder.append("</code>");
   if (docText != null) {
     builder.append("<br>");
     final MarkdownProcessor processor = new MarkdownProcessor();
     builder.append(processor.markdown(docText));
   }
   // done
   return builder.toString();
 }
  public static String generateDoc(final PsiElement element) {
    if (!(element instanceof DartComponent) && !(element.getParent() instanceof DartComponent)) {
      return null;
    }
    final DartComponent namedComponent =
        (DartComponent) (element instanceof DartComponent ? element : element.getParent());

    final String signatureHtml;
    {
      final StringBuilder builder = new StringBuilder();
      appendSignature(namedComponent, builder);
      signatureHtml = builder.toString();
    }

    final String containingLibraryName;
    final PsiFile file = element.getContainingFile();
    if (file != null) {
      containingLibraryName = DartResolveUtil.getLibraryName(file);
    } else {
      containingLibraryName = null;
    }

    final String containingClassDescription;
    final DartClass dartClass = PsiTreeUtil.getParentOfType(namedComponent, DartClass.class);
    if (dartClass != null) {
      final StringBuilder builder = new StringBuilder();
      builder.append(dartClass.getName());
      appendTypeParams(builder, dartClass.getTypeParameters());
      containingClassDescription = builder.toString();
    } else {
      containingClassDescription = null;
    }

    final String docText = getDocumentationText(namedComponent);
    return generateDoc(
        signatureHtml,
        true,
        docText,
        containingLibraryName,
        containingClassDescription,
        null,
        null);
  }
 @Nullable
 public static String getSignature(@NotNull PsiElement element) {
   if (!(element instanceof DartComponent)) {
     element = element.getParent();
   }
   if (element instanceof DartComponent) {
     final StringBuilder sb = new StringBuilder();
     appendSignature((DartComponent) element, sb);
     if (sb.length() > 0) return sb.toString();
   }
   return null;
 }
  @Nullable
  private static String getSingleLineDocCommentsText(final @NotNull PsiComment[] comments) {
    StringBuilder buf = null;

    for (PsiComment comment : comments) {
      if (comment.getNode().getElementType() == DartTokenTypesSets.SINGLE_LINE_DOC_COMMENT) {
        if (buf == null) {
          buf = new StringBuilder();
        } else {
          buf.append('\n');
        }

        final String text = comment.getText();
        if (text.startsWith(SINGLE_LINE_DOC_COMMENT + " ")) {
          buf.append(StringUtil.trimStart(text, SINGLE_LINE_DOC_COMMENT + " "));
        } else {
          buf.append(StringUtil.trimStart(text, SINGLE_LINE_DOC_COMMENT));
        }
      }
    }

    return buf == null ? null : buf.toString();
  }