示例#1
0
static Optional<DocComment *>
getAnyBaseClassDocComment(swift::markup::MarkupContext &MC,
                          const ClassDecl *CD,
                          const Decl *D) {
  RawComment RC;

  if (const auto *VD = dyn_cast<ValueDecl>(D)) {
    const auto *BaseDecl = VD->getOverriddenDecl();
    while (BaseDecl) {
      RC = BaseDecl->getRawComment();
      if (!RC.isEmpty()) {
        swift::markup::LineList LL = MC.getLineList(RC);
        auto *Doc = swift::markup::parseDocument(MC, LL);
        auto Parts = extractCommentParts(MC, Doc);

        SmallString<48> RawCascadeText;
        llvm::raw_svector_ostream OS(RawCascadeText);
        OS << "This documentation comment was inherited from ";


        auto *Text = swift::markup::Text::create(MC, MC.allocateCopy(OS.str()));

        auto BaseClass =
          BaseDecl->getDeclContext()->getAsClassOrClassExtensionContext();

        auto *BaseClassMonospace =
          swift::markup::Code::create(MC,
                                      MC.allocateCopy(BaseClass->getNameStr()));

        auto *Period = swift::markup::Text::create(MC, ".");

        auto *Para = swift::markup::Paragraph::create(MC, {
          Text, BaseClassMonospace, Period
        });
        auto CascadeNote = swift::markup::NoteField::create(MC, {Para});

        SmallVector<const swift::markup::MarkupASTNode *, 8> BodyNodes {
          Parts.BodyNodes.begin(),
          Parts.BodyNodes.end()
        };
        BodyNodes.push_back(CascadeNote);
        Parts.BodyNodes = MC.allocateCopy(llvm::makeArrayRef(BodyNodes));

        return new (MC) DocComment(D, Doc, Parts);
      }

      BaseDecl = BaseDecl->getOverriddenDecl();
    }
  }
  
  return None;
}
示例#2
0
static swift::markup::CommentParts
extractCommentParts(swift::markup::MarkupContext &MC,
                    swift::markup::MarkupASTNode *Node) {

  swift::markup::CommentParts Parts;
  auto Children = Node->getChildren();
  if (Children.empty())
    return Parts;

  auto FirstParagraph
      = dyn_cast<swift::markup::Paragraph>(Node->getChildren().front());
  if (FirstParagraph)
    Parts.Brief = FirstParagraph;

  SmallVector<const swift::markup::MarkupASTNode *, 4> BodyNodes;
  SmallVector<swift::markup::ParamField *, 8> ParamFields;

  // Look for special top-level lists
  size_t StartOffset = FirstParagraph == nullptr ? 0 : 1;
  for (auto C = Children.begin() + StartOffset; C != Children.end(); ++C) {
    if (auto L = dyn_cast<swift::markup::List>(*C)) {
      // Could be one of the following:
      // 1. A parameter outline:
      //    - Parameters:
      //      - x: ...
      //      - y: ...
      // 2. An exploded parameter list:
      //    - parameter x: ...
      //    - parameter y: ...
      // 3. Some other simple field, including "returns" (see SimpleFields.def)
      auto ListNowEmpty = extractParameterOutline(MC, L, ParamFields);
      ListNowEmpty |= extractSeparatedParams(MC, L, ParamFields);
      ListNowEmpty |= extractSimpleField(MC, L, Parts, BodyNodes);
      if (ListNowEmpty)
        continue; // This drops the empty list from the doc comment body.
    }
    BodyNodes.push_back(*C);
  }

  // Copy BodyNodes and ParamFields into the MarkupContext.
  Parts.BodyNodes = MC.allocateCopy(llvm::makeArrayRef(BodyNodes));
  Parts.ParamFields = MC.allocateCopy(llvm::makeArrayRef(ParamFields));

  for (auto Param : Parts.ParamFields) {
    auto ParamParts = extractCommentParts(MC, Param);
    Param->setParts(ParamParts);
  }

  return Parts;
}
示例#3
0
bool extractSimpleField(
    swift::markup::MarkupContext &MC, swift::markup::List *L,
    swift::markup::CommentParts &Parts,
    SmallVectorImpl<const swift::markup::MarkupASTNode *> &BodyNodes) {
  auto Children = L->getChildren();
  SmallVector<swift::markup::MarkupASTNode *, 8> NormalItems;
  for (auto Child : Children) {
    auto I = dyn_cast<swift::markup::Item>(Child);
    if (!I) {
      NormalItems.push_back(Child);
      continue;
    }

    auto ItemChildren = I->getChildren();
    if (ItemChildren.empty()) {
      NormalItems.push_back(Child);
      continue;
    }

    auto FirstParagraph
        = dyn_cast<swift::markup::Paragraph>(ItemChildren.front());
    if (!FirstParagraph) {
      NormalItems.push_back(Child);
      continue;
    }

    auto ParagraphChildren = FirstParagraph->getChildren();
    if (ParagraphChildren.empty()) {
      NormalItems.push_back(Child);
      continue;
    }

    auto ParagraphText
        = dyn_cast<swift::markup::Text>(ParagraphChildren.front());
    if (!ParagraphText) {
      NormalItems.push_back(Child);
      continue;
    }

    StringRef Tag;
    StringRef Remainder;
    std::tie(Tag, Remainder) = ParagraphText->getLiteralContent().split(':');
    Tag = Tag.ltrim().rtrim();
    Remainder = Remainder.ltrim();

    if (!swift::markup::isAFieldTag(Tag)) {
      NormalItems.push_back(Child);
      continue;
    }

    ParagraphText->setLiteralContent(Remainder);
    auto Field = swift::markup::createSimpleField(MC, Tag, ItemChildren);

    if (auto RF = dyn_cast<swift::markup::ReturnsField>(Field)) {
      Parts.ReturnsField = RF;
    } else if (auto TF = dyn_cast<swift::markup::ThrowsField>(Field)) {
      Parts.ThrowsField = TF;
    } else if (auto TF = dyn_cast<swift::markup::TagField>(Field)) {
      llvm::SmallString<64> Scratch;
      llvm::raw_svector_ostream OS(Scratch);
      printInlinesUnder(TF, OS);
      Parts.Tags.insert(MC.allocateCopy(OS.str()));
    } else if (auto LKF = dyn_cast<markup::LocalizationKeyField>(Field)) {
      Parts.LocalizationKeyField = LKF;
    } else {
      BodyNodes.push_back(Field);
    }
  }

  if (NormalItems.size() != Children.size())
    L->setChildren(NormalItems);

  return NormalItems.empty();
}