private static void appendSignature(
     final DartComponent namedComponent, final StringBuilder builder) {
   if (namedComponent instanceof DartClass) {
     appendClassSignature(builder, (DartClass) namedComponent);
   } else if (namedComponent instanceof DartFunctionDeclarationWithBodyOrNative) {
     appendFunctionSignature(
         builder,
         namedComponent,
         ((DartFunctionDeclarationWithBodyOrNative) namedComponent).getReturnType());
   } else if (namedComponent instanceof DartFunctionTypeAlias) {
     builder.append("typedef ");
     appendFunctionSignature(
         builder, namedComponent, ((DartFunctionTypeAlias) namedComponent).getReturnType());
   } else if (namedComponent.isConstructor()) {
     appendConstructorSignature(
         builder, namedComponent, PsiTreeUtil.getParentOfType(namedComponent, DartClass.class));
   } else if (namedComponent instanceof DartMethodDeclaration) {
     appendFunctionSignature(
         builder, namedComponent, ((DartMethodDeclaration) namedComponent).getReturnType());
   } else if (namedComponent instanceof DartVarAccessDeclaration) {
     appendVariableSignature(
         builder, namedComponent, ((DartVarAccessDeclaration) namedComponent).getType());
   } else if (namedComponent instanceof DartGetterDeclaration) {
     builder.append("get ");
     appendFunctionSignature(
         builder, namedComponent, ((DartGetterDeclaration) namedComponent).getReturnType());
   } else if (namedComponent instanceof DartSetterDeclaration) {
     builder.append("set ");
     appendFunctionSignature(
         builder, namedComponent, ((DartSetterDeclaration) namedComponent).getReturnType());
   } else if (namedComponent instanceof DartEnumConstantDeclaration) {
     builder.append(((DartEnumDefinition) namedComponent.getParent()).getName()).append(" ");
     builder.append("<b>").append(namedComponent.getName()).append("</b>");
   }
 }
  @NotNull
  private static String getPresentableElementPosition(
      @NotNull final CodeInsightTestFixture fixture, final @Nullable PsiElement element) {
    if (element == null) return "";

    final StringBuilder buf = new StringBuilder(element.getText());
    DartComponent component = PsiTreeUtil.getParentOfType(element, DartComponent.class);
    while (component != null) {
      final DartComponentName componentName = component.getComponentName();
      if (componentName != null && componentName != element) {
        buf.insert(0, component.getName() + " -> ");
      }
      component = PsiTreeUtil.getParentOfType(component, DartComponent.class);
    }
    String path =
        element instanceof PsiDirectoryImpl
            ? ((PsiDirectoryImpl) element).getVirtualFile().getPath()
            : element.getContainingFile().getVirtualFile().getPath();

    final String contentRoot =
        ModuleRootManager.getInstance(fixture.getModule()).getContentRoots()[0].getPath();
    if (path.equals(contentRoot)) path = "[content root]";

    final String contentRootWithSlash = contentRoot + "/";
    if (path.startsWith(contentRootWithSlash)) path = path.substring(contentRootWithSlash.length());

    final DartSdk sdk = DartSdk.getDartSdk(element.getProject());
    if (sdk != null && path.startsWith(sdk.getHomePath()))
      path = "[Dart SDK]" + path.substring(sdk.getHomePath().length());

    if (buf.length() > 0) buf.insert(0, " -> ");
    buf.insert(0, path);

    return buf.toString();
  }
 private static void appendFunctionSignature(
     final StringBuilder builder, final DartComponent function, final String returnType) {
   builder.append("<b>").append(function.getName()).append("</b>");
   if (!function.isGetter()) {
     builder.append('(');
     builder.append(
         StringUtil.escapeXml(
             DartPresentableUtil.getPresentableParameterList(
                 function, new DartGenericSpecialization(), true, true)));
     builder.append(')');
   }
   builder.append(' ');
   builder.append(DartPresentableUtil.RIGHT_ARROW);
   builder.append(' ');
   builder.append(returnType);
 }
 private static void appendVariableSignature(
     final StringBuilder builder, final DartComponent component, final DartType type) {
   if (type == null) {
     builder.append("var ");
   } else {
     builder.append(type.getReferenceExpression().getText());
     appendTypeArguments(builder, type);
     builder.append(" ");
   }
   builder.append("<b>").append(component.getName()).append("</b>");
 }
  @Nullable
  private static String getDocumentationText(final DartComponent dartComponent) {
    // PSI is not perfect currently, doc comment may be not part of the corresponding DartComponent
    // element, so docs are searched for in several places:
    // - direct child of this DartComponent
    // - previous sibling (or previous sibling of parent element if this element is first child of
    // its parent DartClassMembers)
    // Consequent line doc comments (///) are joined

    // 1. Look for multiline doc comment as direct child
    final DartDocComment multilineComment =
        PsiTreeUtil.getChildOfType(dartComponent, DartDocComment.class);
    if (multilineComment != null) return getMultilineDocCommentText(multilineComment);

    // 2. Look for single line doc comments as direct children
    final PsiComment[] childComments =
        PsiTreeUtil.getChildrenOfType(dartComponent, PsiComment.class);
    if (childComments != null) {
      //
      final String docText = getSingleLineDocCommentsText(childComments);
      if (docText != null) return docText;
    }

    PsiElement anchorElement = dartComponent;

    final PsiElement parent = dartComponent.getParent();
    if (parent instanceof DartClassMembers && parent.getFirstChild() == dartComponent
        || dartComponent instanceof DartVarAccessDeclaration) {
      anchorElement = parent;
    }

    // 3. Look for multiline doc comment or line doc comments as previous siblings
    final List<PsiComment> siblingComments = new ArrayList<PsiComment>();
    PsiElement previous = anchorElement;
    while ((previous = UsefulPsiTreeUtil.getPrevSiblingSkipWhiteSpaces(previous, true))
        instanceof PsiComment) {
      if (previous instanceof DartDocComment) {
        return getMultilineDocCommentText((DartDocComment) previous);
      }
      siblingComments.add(0, (PsiComment) previous);
    }

    if (!siblingComments.isEmpty()) {
      return getSingleLineDocCommentsText(
          siblingComments.toArray(new PsiComment[siblingComments.size()]));
    }

    return null;
  }