yql_ast_annotation.cpp 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. #include "yql_ast_annotation.h"
  2. #include <util/string/printf.h>
  3. #include <util/string/split.h>
  4. #include <util/string/cast.h>
  5. #include <util/string/builder.h>
  6. #include <library/cpp/containers/stack_vector/stack_vec.h>
  7. namespace NYql {
  8. namespace {
  9. TAstNode* AnnotateNodePosition(TAstNode& node, TMemoryPool& pool) {
  10. auto newPosition = node.GetPosition();
  11. TAstNode* pos = PositionAsNode(node.GetPosition(), pool);
  12. TAstNode* shallowClone = &node;
  13. if (node.IsList()) {
  14. TSmallVec<TAstNode*> listChildren(node.GetChildrenCount());
  15. for (ui32 index = 0; index < node.GetChildrenCount(); ++index) {
  16. listChildren[index] = AnnotateNodePosition(*node.GetChild(index), pool);
  17. }
  18. shallowClone = TAstNode::NewList(node.GetPosition(), listChildren.data(), listChildren.size(), pool);
  19. }
  20. return TAstNode::NewList(newPosition, pool, pos, shallowClone);
  21. }
  22. TAstNode* RemoveNodeAnnotations(TAstNode& node, TMemoryPool& pool) {
  23. if (!node.IsList())
  24. return nullptr;
  25. if (node.GetChildrenCount() == 0)
  26. return nullptr;
  27. auto lastNode = node.GetChild(node.GetChildrenCount() - 1);
  28. auto res = lastNode;
  29. if (lastNode->IsList()) {
  30. TSmallVec<TAstNode*> listChildren(lastNode->GetChildrenCount());
  31. for (ui32 index = 0; index < lastNode->GetChildrenCount(); ++index) {
  32. auto item = RemoveNodeAnnotations(*lastNode->GetChild(index), pool);
  33. if (!item)
  34. return nullptr;
  35. listChildren[index] = item;
  36. }
  37. res = TAstNode::NewList(lastNode->GetPosition(), listChildren.data(), listChildren.size(), pool);
  38. }
  39. return res;
  40. }
  41. TAstNode* ExtractNodeAnnotations(TAstNode& node, TAnnotationNodeMap& annotations, TMemoryPool& pool) {
  42. if (!node.IsList())
  43. return nullptr;
  44. if (node.GetChildrenCount() == 0)
  45. return nullptr;
  46. auto lastNode = node.GetChild(node.GetChildrenCount() - 1);
  47. auto res = lastNode;
  48. if (lastNode->IsList()) {
  49. TSmallVec<TAstNode*> listChildren(lastNode->GetChildrenCount());
  50. for (ui32 index = 0; index < lastNode->GetChildrenCount(); ++index) {
  51. auto item = ExtractNodeAnnotations(*lastNode->GetChild(index), annotations, pool);
  52. if (!item)
  53. return nullptr;
  54. listChildren[index] = item;
  55. }
  56. res = TAstNode::NewList(lastNode->GetPosition(), listChildren.data(), listChildren.size(), pool);
  57. }
  58. auto& v = annotations[res];
  59. v.resize(node.GetChildrenCount() - 1);
  60. for (ui32 index = 0; index + 1 < node.GetChildrenCount(); ++index) {
  61. v[index] = node.GetChild(index);
  62. }
  63. return res;
  64. }
  65. TAstNode* ApplyNodePositionAnnotations(TAstNode& node, ui32 annotationIndex, TMemoryPool& pool) {
  66. if (!node.IsList())
  67. return nullptr;
  68. if (node.GetChildrenCount() < annotationIndex + 2)
  69. return nullptr;
  70. auto annotation = node.GetChild(annotationIndex);
  71. auto str = annotation->GetContent();
  72. TStringBuf rowPart;
  73. TStringBuf colPart;
  74. TString filePart;
  75. GetNext(str, ':', rowPart);
  76. GetNext(str, ':', colPart);
  77. filePart = str;
  78. ui32 row = 0, col = 0;
  79. if (!TryFromString(rowPart, row) || !TryFromString(colPart, col))
  80. return nullptr;
  81. TSmallVec<TAstNode*> listChildren(node.GetChildrenCount());
  82. for (ui32 index = 0; index < node.GetChildrenCount() - 1; ++index) {
  83. listChildren[index] = node.GetChild(index);
  84. }
  85. auto lastNode = node.GetChild(node.GetChildrenCount() - 1);
  86. TAstNode* lastResNode;
  87. if (lastNode->IsAtom()) {
  88. lastResNode = TAstNode::NewAtom(TPosition(col, row, filePart), lastNode->GetContent(), pool, lastNode->GetFlags());
  89. } else {
  90. TSmallVec<TAstNode*> lastNodeChildren(lastNode->GetChildrenCount());
  91. for (ui32 index = 0; index < lastNode->GetChildrenCount(); ++index) {
  92. lastNodeChildren[index] = ApplyNodePositionAnnotations(*lastNode->GetChild(index), annotationIndex, pool);
  93. }
  94. lastResNode = TAstNode::NewList(TPosition(col, row, filePart), lastNodeChildren.data(), lastNodeChildren.size(), pool);
  95. }
  96. listChildren[node.GetChildrenCount() - 1] = lastResNode;
  97. return TAstNode::NewList(node.GetPosition(), listChildren.data(), listChildren.size(), pool);
  98. }
  99. bool ApplyNodePositionAnnotationsInplace(TAstNode& node, ui32 annotationIndex) {
  100. if (!node.IsList())
  101. return false;
  102. if (node.GetChildrenCount() < annotationIndex + 2)
  103. return false;
  104. auto annotation = node.GetChild(annotationIndex);
  105. TStringBuf str = annotation->GetContent();
  106. TStringBuf rowPart;
  107. TStringBuf colPart;
  108. TString filePart;
  109. GetNext(str, ':', rowPart);
  110. GetNext(str, ':', colPart);
  111. filePart = str;
  112. ui32 row = 0, col = 0;
  113. if (!TryFromString(rowPart, row) || !TryFromString(colPart, col))
  114. return false;
  115. auto lastNode = node.GetChild(node.GetChildrenCount() - 1);
  116. lastNode->SetPosition(TPosition(col, row, filePart));
  117. if (lastNode->IsList()) {
  118. for (ui32 index = 0; index < lastNode->GetChildrenCount(); ++index) {
  119. if (!ApplyNodePositionAnnotationsInplace(*lastNode->GetChild(index), annotationIndex))
  120. return false;
  121. }
  122. }
  123. return true;
  124. }
  125. }
  126. TAstNode* AnnotatePositions(TAstNode& root, TMemoryPool& pool) {
  127. return AnnotateNodePosition(root, pool);
  128. }
  129. TAstNode* RemoveAnnotations(TAstNode& root, TMemoryPool& pool) {
  130. return RemoveNodeAnnotations(root, pool);
  131. }
  132. TAstNode* ApplyPositionAnnotations(TAstNode& root, ui32 annotationIndex, TMemoryPool& pool) {
  133. return ApplyNodePositionAnnotations(root, annotationIndex, pool);
  134. }
  135. bool ApplyPositionAnnotationsInplace(TAstNode& root, ui32 annotationIndex) {
  136. return ApplyNodePositionAnnotationsInplace(root, annotationIndex);
  137. }
  138. TAstNode* PositionAsNode(TPosition position, TMemoryPool& pool) {
  139. TStringBuilder str;
  140. str << position.Row << ':' << position.Column;
  141. if (!position.File.empty()) {
  142. str << ':' << position.File;
  143. }
  144. return TAstNode::NewAtom(position, str, pool);
  145. }
  146. TAstNode* ExtractAnnotations(TAstNode& root, TAnnotationNodeMap& annotations, TMemoryPool& pool) {
  147. return ExtractNodeAnnotations(root, annotations, pool);
  148. }
  149. }