Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / xml / XPathPath.cpp
index 77a761e..74dc33c 100644 (file)
 #include "core/xml/XPathPath.h"
 
 #include "core/dom/Document.h"
+#include "core/dom/NodeTraversal.h"
 #include "core/xml/XPathPredicate.h"
 #include "core/xml/XPathStep.h"
 #include "core/xml/XPathValue.h"
 
-namespace WebCore {
+namespace blink {
 namespace XPath {
 
-Filter::Filter(PassOwnPtr<Expression> expr, Vector<OwnPtr<Predicate> >& predicates)
+Filter::Filter(PassOwnPtrWillBeRawPtr<Expression> expr, WillBeHeapVector<OwnPtrWillBeMember<Predicate> >& predicates)
     : m_expr(expr)
 {
     m_predicates.swap(predicates);
@@ -49,16 +50,22 @@ Filter::~Filter()
 {
 }
 
-Value Filter::evaluate() const
+void Filter::trace(Visitor* visitor)
 {
-    Value v = m_expr->evaluate();
+    visitor->trace(m_expr);
+    visitor->trace(m_predicates);
+    Expression::trace(visitor);
+}
+
+Value Filter::evaluate(EvaluationContext& evaluationContext) const
+{
+    Value v = m_expr->evaluate(evaluationContext);
 
-    NodeSet& nodes = v.modifiableNodeSet();
+    NodeSet& nodes = v.modifiableNodeSet(evaluationContext);
     nodes.sort();
 
-    EvaluationContext& evaluationContext = Expression::evaluationContext();
     for (unsigned i = 0; i < m_predicates.size(); i++) {
-        NodeSet newNodes;
+        OwnPtrWillBeRawPtr<NodeSet> newNodes(NodeSet::create());
         evaluationContext.size = nodes.size();
         evaluationContext.position = 0;
 
@@ -68,10 +75,10 @@ Value Filter::evaluate() const
             evaluationContext.node = node;
             ++evaluationContext.position;
 
-            if (m_predicates[i]->evaluate())
-                newNodes.append(node);
+            if (m_predicates[i]->evaluate(evaluationContext))
+                newNodes->append(node);
         }
-        nodes.swap(newNodes);
+        nodes.swap(*newNodes);
     }
 
     return v;
@@ -85,13 +92,22 @@ LocationPath::LocationPath()
 
 LocationPath::~LocationPath()
 {
+#if !ENABLE(OILPAN)
     deleteAllValues(m_steps);
+#endif
 }
 
-Value LocationPath::evaluate() const
+void LocationPath::trace(Visitor* visitor)
 {
-    EvaluationContext& evaluationContext = Expression::evaluationContext();
-    EvaluationContext backupContext = evaluationContext;
+#if ENABLE(OILPAN)
+    visitor->trace(m_steps);
+#endif
+    Expression::trace(visitor);
+}
+
+Value LocationPath::evaluate(EvaluationContext& evaluationContext) const
+{
+    EvaluationContext clonedContext = evaluationContext;
     // http://www.w3.org/TR/xpath/
     // Section 2, Location Paths:
     // "/ selects the document root (which is always the parent of the document element)"
@@ -105,25 +121,24 @@ Value LocationPath::evaluate() const
         if (context->inDocument())
             context = context->ownerDocument();
         else
-            context = &context->highestAncestorOrSelf();
+            context = &NodeTraversal::highestAncestorOrSelf(*context);
     }
 
-    NodeSet nodes;
-    nodes.append(context);
-    evaluate(nodes);
+    OwnPtrWillBeRawPtr<NodeSet> nodes(NodeSet::create());
+    nodes->append(context);
+    evaluate(clonedContext, *nodes);
 
-    evaluationContext = backupContext;
-    return Value(nodes, Value::adopt);
+    return Value(nodes.release(), Value::adopt);
 }
 
-void LocationPath::evaluate(NodeSet& nodes) const
+void LocationPath::evaluate(EvaluationContext& context, NodeSet& nodes) const
 {
     bool resultIsSorted = nodes.isSorted();
 
     for (unsigned i = 0; i < m_steps.size(); i++) {
         Step* step = m_steps[i];
-        NodeSet newNodes;
-        HashSet<Node*> newNodesSet;
+        OwnPtrWillBeRawPtr<NodeSet> newNodes(NodeSet::create());
+        WillBeHeapHashSet<RawPtrWillBeMember<Node> > newNodesSet;
 
         bool needToCheckForDuplicateNodes = !nodes.subtreesAreDisjoint() || (step->axis() != Step::ChildAxis && step->axis() != Step::SelfAxis
             && step->axis() != Step::DescendantAxis && step->axis() != Step::DescendantOrSelfAxis && step->axis() != Step::AttributeAxis);
@@ -133,23 +148,23 @@ void LocationPath::evaluate(NodeSet& nodes) const
 
         // This is a simplified check that can be improved to handle more cases.
         if (nodes.subtreesAreDisjoint() && (step->axis() == Step::ChildAxis || step->axis() == Step::SelfAxis))
-            newNodes.markSubtreesDisjoint(true);
+            newNodes->markSubtreesDisjoint(true);
 
         for (unsigned j = 0; j < nodes.size(); j++) {
-            NodeSet matches;
-            step->evaluate(nodes[j], matches);
+            OwnPtrWillBeRawPtr<NodeSet> matches(NodeSet::create());
+            step->evaluate(context, nodes[j], *matches);
 
-            if (!matches.isSorted())
+            if (!matches->isSorted())
                 resultIsSorted = false;
 
-            for (size_t nodeIndex = 0; nodeIndex < matches.size(); ++nodeIndex) {
-                Node* node = matches[nodeIndex];
+            for (size_t nodeIndex = 0; nodeIndex < matches->size(); ++nodeIndex) {
+                Node* node = (*matches)[nodeIndex];
                 if (!needToCheckForDuplicateNodes || newNodesSet.add(node).isNewEntry)
-                    newNodes.append(node);
+                    newNodes->append(node);
             }
         }
 
-        nodes.swap(newNodes);
+        nodes.swap(*newNodes);
     }
 
     nodes.markSorted(resultIsSorted);
@@ -162,7 +177,9 @@ void LocationPath::appendStep(Step* step)
         bool dropSecondStep;
         optimizeStepPair(m_steps[stepCount - 1], step, dropSecondStep);
         if (dropSecondStep) {
+#if !ENABLE(OILPAN)
             delete step;
+#endif
             return;
         }
     }
@@ -176,7 +193,9 @@ void LocationPath::insertFirstStep(Step* step)
         bool dropSecondStep;
         optimizeStepPair(step, m_steps[0], dropSecondStep);
         if (dropSecondStep) {
+#if !ENABLE(OILPAN)
             delete m_steps[0];
+#endif
             m_steps[0] = step;
             return;
         }
@@ -186,8 +205,8 @@ void LocationPath::insertFirstStep(Step* step)
 }
 
 Path::Path(Expression* filter, LocationPath* path)
-    : m_filter(filter)
-    , m_path(path)
+    : m_filter(adoptPtrWillBeNoop(filter))
+    , m_path(adoptPtrWillBeNoop(path))
 {
     setIsContextNodeSensitive(filter->isContextNodeSensitive());
     setIsContextPositionSensitive(filter->isContextPositionSensitive());
@@ -196,16 +215,21 @@ Path::Path(Expression* filter, LocationPath* path)
 
 Path::~Path()
 {
-    delete m_filter;
-    delete m_path;
 }
 
-Value Path::evaluate() const
+void Path::trace(Visitor* visitor)
+{
+    visitor->trace(m_filter);
+    visitor->trace(m_path);
+    Expression::trace(visitor);
+}
+
+Value Path::evaluate(EvaluationContext& context) const
 {
-    Value v = m_filter->evaluate();
+    Value v = m_filter->evaluate(context);
 
-    NodeSet& nodes = v.modifiableNodeSet();
-    m_path->evaluate(nodes);
+    NodeSet& nodes = v.modifiableNodeSet(context);
+    m_path->evaluate(context, nodes);
 
     return v;
 }