Make CXFA_NodeHelper::GetIndex() a member of CXFA_Node.

Do the same for GetSiblings(). Also move CFXJSE_Engine::GetIndexByName()
and CFXJSE_Engine::GetIndexByClassName() in CXFA_Node.

Change-Id: Ia5e1c686f64160dc3b67d57486c37bb6ad9f8bac
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/52376
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/fxjs/xfa/cfxjse_engine.cpp b/fxjs/xfa/cfxjse_engine.cpp
index b5c7a78..8c20211 100644
--- a/fxjs/xfa/cfxjse_engine.cpp
+++ b/fxjs/xfa/cfxjse_engine.cpp
@@ -757,18 +757,6 @@
   return pValue;
 }
 
-size_t CFXJSE_Engine::GetIndexByName(CXFA_Node* refNode) {
-  if (!refNode)
-    return 0;
-  return CXFA_NodeHelper::GetIndex(refNode, refNode->IsProperty(), false);
-}
-
-size_t CFXJSE_Engine::GetIndexByClassName(CXFA_Node* refNode) {
-  if (!refNode)
-    return 0;
-  return CXFA_NodeHelper::GetIndex(refNode, refNode->IsProperty(), true);
-}
-
 void CFXJSE_Engine::SetNodesOfRunScript(std::vector<CXFA_Node*>* pArray) {
   m_pScriptNodeArray = pArray;
 }
diff --git a/fxjs/xfa/cfxjse_engine.h b/fxjs/xfa/cfxjse_engine.h
index cacf09f..d96eaee 100644
--- a/fxjs/xfa/cfxjse_engine.h
+++ b/fxjs/xfa/cfxjse_engine.h
@@ -84,9 +84,6 @@
   void AddToCacheList(std::unique_ptr<CXFA_List> pList);
   CXFA_Object* GetThisObject() const { return m_pThisObject.Get(); }
 
-  size_t GetIndexByName(CXFA_Node* refNode);
-  size_t GetIndexByClassName(CXFA_Node* refNode);
-
   void SetNodesOfRunScript(std::vector<CXFA_Node*>* pArray);
   void AddNodesOfRunScript(CXFA_Node* pNode);
   CFXJSE_Class* GetJseNormalClass() const { return m_pJsClass.Get(); }
diff --git a/fxjs/xfa/cfxjse_resolveprocessor.cpp b/fxjs/xfa/cfxjse_resolveprocessor.cpp
index 9829a2b..a9b9634 100644
--- a/fxjs/xfa/cfxjse_resolveprocessor.cpp
+++ b/fxjs/xfa/cfxjse_resolveprocessor.cpp
@@ -126,7 +126,7 @@
   WideStringView wsName = rnd.m_wsName.AsStringView();
   WideString wsCondition = rnd.m_wsCondition;
   const bool bClassName = !wsName.IsEmpty() && wsName[0] == '#';
-  CXFA_Node* pChild =
+  CXFA_Node* const pChild =
       bClassName
           ? pParent->GetOneChildOfClass(wsName.Right(wsName.GetLength() - 1))
           : pParent->GetOneChildNamed(wsName);
@@ -142,8 +142,7 @@
   for (const auto& pObject : rnd.m_Objects)
     nodes.push_back(pObject->AsNode());
 
-  std::vector<CXFA_Node*> siblings =
-      CXFA_NodeHelper::GetSiblings(pChild, bClassName);
+  std::vector<CXFA_Node*> siblings = pChild->GetSiblings(bClassName);
   nodes.insert(nodes.end(), siblings.begin(), siblings.end());
   rnd.m_Objects =
       std::vector<UnownedPtr<CXFA_Object>>(nodes.begin(), nodes.end());
@@ -333,9 +332,11 @@
       if (!(dwStyles & XFA_RESOLVENODE_ALL)) {
         std::vector<CXFA_Node*> upArrayNodes;
         if (curNode->IsTransparent()) {
-          upArrayNodes = CXFA_NodeHelper::GetSiblings(
-              ToNode(rnd.m_Objects.front().Get()),
-              !!(dwStyles & XFA_RESOLVENODE_TagName));
+          CXFA_Node* pCurrent = ToNode(rnd.m_Objects.front().Get());
+          if (pCurrent) {
+            upArrayNodes =
+                pCurrent->GetSiblings(!!(dwStyles & XFA_RESOLVENODE_TagName));
+          }
         }
         if (upArrayNodes.size() > rnd.m_Objects.size()) {
           CXFA_Object* pSaveObject = rnd.m_Objects.front().Get();
@@ -465,9 +466,12 @@
     }
     if (rnd.m_Objects.size() > nNum) {
       if (parentNode->IsTransparent()) {
-        std::vector<CXFA_Node*> upArrayNodes = CXFA_NodeHelper::GetSiblings(
-            ToNode(rnd.m_Objects.front().Get()),
-            !!(dwStyles & XFA_RESOLVENODE_TagName));
+        std::vector<CXFA_Node*> upArrayNodes;
+        CXFA_Node* pCurrent = ToNode(rnd.m_Objects.front().Get());
+        if (pCurrent) {
+          upArrayNodes =
+              pCurrent->GetSiblings(!!(dwStyles & XFA_RESOLVENODE_TagName));
+        }
         if (upArrayNodes.size() > rnd.m_Objects.size()) {
           CXFA_Object* pSaveObject = rnd.m_Objects.front().Get();
           rnd.m_Objects = std::vector<UnownedPtr<CXFA_Object>>(
@@ -651,12 +655,12 @@
   size_t iCurIndex = 0;
   const std::vector<CXFA_Node*>* pArray = pRnd->m_pSC->GetUpObjectArray();
   if (!pArray->empty()) {
-    CXFA_Node* curNode = pArray->back();
-    bool bIsProperty = curNode->IsProperty();
+    CXFA_Node* pNode = pArray->back();
+    bool bIsProperty = pNode->IsProperty();
     bool bIsClassIndex =
-        curNode->IsUnnamed() ||
-        (bIsProperty && curNode->GetElementType() != XFA_Element::PageSet);
-    iCurIndex = CXFA_NodeHelper::GetIndex(curNode, bIsProperty, bIsClassIndex);
+        pNode->IsUnnamed() ||
+        (bIsProperty && pNode->GetElementType() != XFA_Element::PageSet);
+    iCurIndex = pNode->GetIndex(bIsProperty, bIsClassIndex);
   }
 
   size_t iFoundCount = pRnd->m_Objects.size();
diff --git a/fxjs/xfa/cjx_tree.cpp b/fxjs/xfa/cjx_tree.cpp
index 62ce3f4..c036ab9 100644
--- a/fxjs/xfa/cjx_tree.cpp
+++ b/fxjs/xfa/cjx_tree.cpp
@@ -167,9 +167,9 @@
     return;
   }
 
-  CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
-  pValue->SetInteger(pdfium::base::checked_cast<int32_t>(
-      pScriptContext->GetIndexByName(ToNode(GetXFAObject()))));
+  CXFA_Node* pNode = ToNode(GetXFAObject());
+  size_t iIndex = pNode ? pNode->GetIndexByName() : 0;
+  pValue->SetInteger(pdfium::base::checked_cast<int32_t>(iIndex));
 }
 
 void CJX_Tree::classIndex(CFXJSE_Value* pValue,
@@ -180,9 +180,9 @@
     return;
   }
 
-  CFXJSE_Engine* pScriptContext = GetDocument()->GetScriptContext();
-  pValue->SetInteger(pdfium::base::checked_cast<int32_t>(
-      pScriptContext->GetIndexByClassName(ToNode(GetXFAObject()))));
+  CXFA_Node* pNode = ToNode(GetXFAObject());
+  size_t iIndex = pNode ? pNode->GetIndexByClassName() : 0;
+  pValue->SetInteger(pdfium::base::checked_cast<int32_t>(iIndex));
 }
 
 void CJX_Tree::somExpression(CFXJSE_Value* pValue,
diff --git a/xfa/fxfa/parser/cxfa_node.cpp b/xfa/fxfa/parser/cxfa_node.cpp
index 1e636bf..9f19a49 100644
--- a/xfa/fxfa/parser/cxfa_node.cpp
+++ b/xfa/fxfa/parser/cxfa_node.cpp
@@ -218,7 +218,6 @@
 #include "xfa/fxfa/parser/cxfa_msgid.h"
 #include "xfa/fxfa/parser/cxfa_nameattr.h"
 #include "xfa/fxfa/parser/cxfa_neverembed.h"
-#include "xfa/fxfa/parser/cxfa_nodehelper.h"
 #include "xfa/fxfa/parser/cxfa_nodeiteratortemplate.h"
 #include "xfa/fxfa/parser/cxfa_numberofcopies.h"
 #include "xfa/fxfa/parser/cxfa_numberpattern.h"
@@ -767,9 +766,59 @@
     ws.Replace(L".", L"\\.");
   }
 
-  return WideString::Format(
-      pszFormat, ws.c_str(),
-      CXFA_NodeHelper::GetIndex(pNode, bIsProperty, bIsClassIndex));
+  return WideString::Format(pszFormat, ws.c_str(),
+                            pNode->GetIndex(bIsProperty, bIsClassIndex));
+}
+
+void TraverseSiblings(CXFA_Node* parent,
+                      uint32_t dwNameHash,
+                      std::vector<CXFA_Node*>* pSiblings,
+                      bool bIsClassName,
+                      bool bIsFindProperty) {
+  ASSERT(parent);
+  ASSERT(pSiblings);
+
+  if (bIsFindProperty) {
+    for (CXFA_Node* child :
+         parent->GetNodeList(XFA_NODEFILTER_Properties, XFA_Element::Unknown)) {
+      if (bIsClassName) {
+        if (child->GetClassHashCode() == dwNameHash)
+          pSiblings->push_back(child);
+      } else {
+        if (child->GetNameHash() == dwNameHash) {
+          if (child->GetElementType() != XFA_Element::PageSet &&
+              child->GetElementType() != XFA_Element::Extras &&
+              child->GetElementType() != XFA_Element::Items) {
+            pSiblings->push_back(child);
+          }
+        }
+      }
+      if (child->IsUnnamed() &&
+          child->GetElementType() == XFA_Element::PageSet) {
+        TraverseSiblings(child, dwNameHash, pSiblings, bIsClassName, false);
+      }
+    }
+    if (!pSiblings->empty())
+      return;
+  }
+  for (CXFA_Node* child :
+       parent->GetNodeList(XFA_NODEFILTER_Children, XFA_Element::Unknown)) {
+    if (child->GetElementType() == XFA_Element::Variables)
+      continue;
+
+    if (bIsClassName) {
+      if (child->GetClassHashCode() == dwNameHash)
+        pSiblings->push_back(child);
+    } else {
+      if (child->GetNameHash() == dwNameHash)
+        pSiblings->push_back(child);
+    }
+
+    if (child->IsTransparent() &&
+        child->GetElementType() != XFA_Element::PageSet) {
+      TraverseSiblings(child, dwNameHash, pSiblings, bIsClassName, false);
+    }
+  }
 }
 
 }  // namespace
@@ -1664,6 +1713,50 @@
   return FindFirstSiblingOfClass(this, element);
 }
 
+std::vector<CXFA_Node*> CXFA_Node::GetSiblings(bool bIsClassName) {
+  std::vector<CXFA_Node*> siblings;
+  CXFA_Node* parent = GetParent();
+  if (!parent)
+    return siblings;
+  if (!parent->HasProperty(GetElementType())) {
+    parent = GetTransparentParent();
+    if (!parent)
+      return siblings;
+  }
+
+  uint32_t dwNameHash = bIsClassName ? GetClassHashCode() : GetNameHash();
+  TraverseSiblings(parent, dwNameHash, &siblings, bIsClassName, true);
+  return siblings;
+}
+
+size_t CXFA_Node::GetIndex(bool bIsProperty, bool bIsClassIndex) {
+  CXFA_Node* parent = GetParent();
+  if (!parent)
+    return 0;
+
+  if (!bIsProperty) {
+    parent = GetTransparentParent();
+    if (!parent)
+      return 0;
+  }
+  uint32_t dwHashName = bIsClassIndex ? GetClassHashCode() : GetNameHash();
+  std::vector<CXFA_Node*> siblings;
+  TraverseSiblings(parent, dwHashName, &siblings, bIsClassIndex, true);
+  for (size_t i = 0; i < siblings.size(); ++i) {
+    if (siblings[i] == this)
+      return i;
+  }
+  return 0;
+}
+
+size_t CXFA_Node::GetIndexByName() {
+  return GetIndex(IsProperty(), /*bIsClassIndex=*/false);
+}
+
+size_t CXFA_Node::GetIndexByClassName() {
+  return GetIndex(IsProperty(), /*bIsClassIndex=*/true);
+}
+
 CXFA_Node* CXFA_Node::GetInstanceMgrOfSubform() {
   CXFA_Node* pInstanceMgr = nullptr;
   if (m_ePacket == XFA_PacketType::Form) {
@@ -5067,6 +5160,19 @@
   }
 }
 
+CXFA_Node* CXFA_Node::GetTransparentParent() {
+  CXFA_Node* parent = GetParent();
+  while (parent) {
+    XFA_Element type = parent->GetElementType();
+    if (type == XFA_Element::Variables ||
+        (type != XFA_Element::SubformSet && !parent->IsUnnamed())) {
+      return parent;
+    }
+    parent = parent->GetParent();
+  }
+  return nullptr;
+}
+
 // static
 std::unique_ptr<CXFA_Node> CXFA_Node::Create(CXFA_Document* doc,
                                              XFA_Element element,
diff --git a/xfa/fxfa/parser/cxfa_node.h b/xfa/fxfa/parser/cxfa_node.h
index 106050f..e962fe9 100644
--- a/xfa/fxfa/parser/cxfa_node.h
+++ b/xfa/fxfa/parser/cxfa_node.h
@@ -218,6 +218,11 @@
   CXFA_Node* GetOneChildNamed(WideStringView wsName);
   CXFA_Node* GetOneChildOfClass(WideStringView wsClass);
 
+  std::vector<CXFA_Node*> GetSiblings(bool bIsClassName);
+  size_t GetIndex(bool bIsProperty, bool bIsClassIndex);
+  size_t GetIndexByName();
+  size_t GetIndexByClassName();
+
   CXFA_Node* GetInstanceMgrOfSubform();
 
   Optional<bool> GetDefaultBoolean(XFA_Attribute attr) const;
@@ -467,6 +472,7 @@
   Optional<XFA_AttributeValue> GetIntactFromKeep(
       const CXFA_Keep* pKeep,
       XFA_AttributeValue eLayoutType) const;
+  CXFA_Node* GetTransparentParent();
 
   Optional<float> TryHeight();
   Optional<float> TryMinWidth();
diff --git a/xfa/fxfa/parser/cxfa_nodehelper.cpp b/xfa/fxfa/parser/cxfa_nodehelper.cpp
index 9d76d54..7d65e0d 100644
--- a/xfa/fxfa/parser/cxfa_nodehelper.cpp
+++ b/xfa/fxfa/parser/cxfa_nodehelper.cpp
@@ -18,121 +18,10 @@
 #include "xfa/fxfa/parser/xfa_resolvenode_rs.h"
 #include "xfa/fxfa/parser/xfa_utils.h"
 
-namespace {
-
-void TraverseSiblings(CXFA_Node* parent,
-                      uint32_t dwNameHash,
-                      std::vector<CXFA_Node*>* pSiblings,
-                      bool bIsClassName,
-                      bool bIsFindProperty) {
-  ASSERT(parent);
-  ASSERT(pSiblings);
-
-  if (bIsFindProperty) {
-    for (CXFA_Node* child :
-         parent->GetNodeList(XFA_NODEFILTER_Properties, XFA_Element::Unknown)) {
-      if (bIsClassName) {
-        if (child->GetClassHashCode() == dwNameHash)
-          pSiblings->push_back(child);
-      } else {
-        if (child->GetNameHash() == dwNameHash) {
-          if (child->GetElementType() != XFA_Element::PageSet &&
-              child->GetElementType() != XFA_Element::Extras &&
-              child->GetElementType() != XFA_Element::Items) {
-            pSiblings->push_back(child);
-          }
-        }
-      }
-      if (child->IsUnnamed() &&
-          child->GetElementType() == XFA_Element::PageSet) {
-        TraverseSiblings(child, dwNameHash, pSiblings, bIsClassName, false);
-      }
-    }
-    if (!pSiblings->empty())
-      return;
-  }
-  for (CXFA_Node* child :
-       parent->GetNodeList(XFA_NODEFILTER_Children, XFA_Element::Unknown)) {
-    if (child->GetElementType() == XFA_Element::Variables)
-      continue;
-
-    if (bIsClassName) {
-      if (child->GetClassHashCode() == dwNameHash)
-        pSiblings->push_back(child);
-    } else {
-      if (child->GetNameHash() == dwNameHash)
-        pSiblings->push_back(child);
-    }
-
-    if (child->IsTransparent() &&
-        child->GetElementType() != XFA_Element::PageSet) {
-      TraverseSiblings(child, dwNameHash, pSiblings, bIsClassName, false);
-    }
-  }
-}
-
-CXFA_Node* GetTransparentParent(CXFA_Node* pNode) {
-  CXFA_Node* parent = pNode ? pNode->GetParent() : nullptr;
-  while (parent) {
-    XFA_Element type = parent->GetElementType();
-    if (type == XFA_Element::Variables ||
-        (type != XFA_Element::SubformSet && !parent->IsUnnamed())) {
-      return parent;
-    }
-    parent = parent->GetParent();
-  }
-  return nullptr;
-}
-
-}  // namespace
-
 CXFA_NodeHelper::CXFA_NodeHelper() = default;
 
 CXFA_NodeHelper::~CXFA_NodeHelper() = default;
 
-// static
-std::vector<CXFA_Node*> CXFA_NodeHelper::GetSiblings(CXFA_Node* pNode,
-                                                     bool bIsClassName) {
-  std::vector<CXFA_Node*> siblings;
-  CXFA_Node* parent = pNode ? pNode->GetParent() : nullptr;
-  if (!parent)
-    return siblings;
-  if (!parent->HasProperty(pNode->GetElementType())) {
-    parent = GetTransparentParent(pNode);
-    if (!parent)
-      return siblings;
-  }
-
-  uint32_t dwNameHash =
-      bIsClassName ? pNode->GetClassHashCode() : pNode->GetNameHash();
-  TraverseSiblings(parent, dwNameHash, &siblings, bIsClassName, true);
-  return siblings;
-}
-
-// static
-size_t CXFA_NodeHelper::GetIndex(CXFA_Node* pNode,
-                                 bool bIsProperty,
-                                 bool bIsClassIndex) {
-  CXFA_Node* parent = pNode ? pNode->GetParent() : nullptr;
-  if (!parent)
-    return 0;
-
-  if (!bIsProperty) {
-    parent = GetTransparentParent(pNode);
-    if (!parent)
-      return 0;
-  }
-  uint32_t dwHashName =
-      bIsClassIndex ? pNode->GetClassHashCode() : pNode->GetNameHash();
-  std::vector<CXFA_Node*> siblings;
-  TraverseSiblings(parent, dwHashName, &siblings, bIsClassIndex, true);
-  for (size_t i = 0; i < siblings.size(); ++i) {
-    if (siblings[i] == pNode)
-      return i;
-  }
-  return 0;
-}
-
 bool CXFA_NodeHelper::CreateNodeForCondition(const WideString& wsCondition) {
   size_t szLen = wsCondition.GetLength();
   WideString wsIndex(L"0");
diff --git a/xfa/fxfa/parser/cxfa_nodehelper.h b/xfa/fxfa/parser/cxfa_nodehelper.h
index fca64cf..66e7e66 100644
--- a/xfa/fxfa/parser/cxfa_nodehelper.h
+++ b/xfa/fxfa/parser/cxfa_nodehelper.h
@@ -21,12 +21,6 @@
   CXFA_NodeHelper();
   ~CXFA_NodeHelper();
 
-  static std::vector<CXFA_Node*> GetSiblings(CXFA_Node* pNode,
-                                             bool bIsClassName);
-  static size_t GetIndex(CXFA_Node* pNode,
-                         bool bIsProperty,
-                         bool bIsClassIndex);
-
   bool CreateNode(const WideString& wsName,
                   const WideString& wsCondition,
                   bool bLastNode,