Commit Graph

1040 Commits

Author SHA1 Message Date
Yorick Peterse d50f89cdf1 Use "node" for axis variables
This ensures that any nested code uses the right variables.
2015-08-19 20:14:22 +02:00
Yorick Peterse 045cfe4ab8 XPath compiler support for operators in predicates
Previously the operator methods would ignore any blocks set by the
on_predicate family of methods.
2015-08-19 20:14:22 +02:00
Yorick Peterse aa8386e6f3 Cleaned up compiler handling of axes/calls
Function call handlers don't receive a single AST node, instead they
receive the XPath arguments as separate method arguments.
2015-08-19 20:14:21 +02:00
Yorick Peterse bfc970a95a XPath compiler support for type tests 2015-08-19 20:14:21 +02:00
Yorick Peterse ef59f160c7 XPath compiler support for true()/false() 2015-08-19 20:14:21 +02:00
Yorick Peterse 2eb12eced6 XPath compiler support for all operators
Some specs still fail due to true()/false() not being implemented but
the operators themselves should work just fine.
2015-08-19 20:14:21 +02:00
Yorick Peterse 3a18d23792 to_boolean support for truthy Ruby values 2015-08-19 20:14:21 +02:00
Yorick Peterse 06ae1503d4 nodes/attributes support in to_compatible_types
This extends XPath::Conversion.to_compatible_types so that it can also
take XML::Node and XML::Attribute objects as input.
2015-08-19 20:14:21 +02:00
Yorick Peterse 376d016acd Expanded supported input for Conversion.to_float
This extends XPath::Conversion.to_float so it can also convert NodeSet
and Node instances.
2015-08-19 20:14:21 +02:00
Yorick Peterse 8a82cc3593 XPath compiler support for the "=" operator 2015-08-19 20:14:21 +02:00
Yorick Peterse 04aa8f6546 Ruby generator support for "begin" blocks 2015-08-19 20:14:21 +02:00
Yorick Peterse 92b43a7500 Renamed on_begin to on_followed_by 2015-08-19 20:14:21 +02:00
Yorick Peterse c98ba21a87 Ruby generator support for mass assignments 2015-08-19 20:14:21 +02:00
Yorick Peterse 53c142ca26 Prefix compiler predicate methods with on_ 2015-08-19 20:14:21 +02:00
Yorick Peterse bea7e19d57 Cast compiled predicate indexes to integers 2015-08-19 20:14:21 +02:00
Yorick Peterse 1f2545c03b Renamed xpath_number? to number? 2015-08-19 20:14:21 +02:00
Yorick Peterse 0e9f533358 Use return_nodeset? vs USE_NODESET 2015-08-19 20:14:21 +02:00
Yorick Peterse 9000d5efdb XPath::Compiler#compile specifies blocks for paths
Previously the on_path method itself would specify a block to use when a
node was matched. This makes it impossible to customize this behaviour
which is needed when a path is used in an operator or predicate. By
letting the #compile() method specify the block other handlers can
overwrite it.
2015-08-19 20:14:21 +02:00
Yorick Peterse e549b28ca4 Removed useless YARD docs from the XPath compiler
The method names already explain their intent.
2015-08-19 20:14:21 +02:00
Yorick Peterse 20c6bbdaa8 Removed left-over comment in the XPath compiler 2015-08-19 20:14:21 +02:00
Yorick Peterse 616fd42600 XPath compiler support for the "attribute" axis 2015-08-19 20:14:21 +02:00
Yorick Peterse 4f03bf19c1 XPath compiler support for "ancestor" 2015-08-19 20:14:21 +02:00
Yorick Peterse f96b30fb1f Tag the XPath compiler as private 2015-08-19 20:14:21 +02:00
Yorick Peterse f7484f1c8d Use each_ancestor for ancestor-or-self in XPath
The XPath compiler now uses XML::Node#each_ancestor for compiling the
"ancestor-or-self" axis.
2015-08-19 20:14:20 +02:00
Yorick Peterse 52741a3b78 Added XML::Node#each_ancestor
This method can be used to walk through the ancestor tree of a Node.
2015-08-19 20:14:20 +02:00
Yorick Peterse db39b25546 XPath compiler support for ancestor-or-self
This also comes with some changes to the specs as the old behaviour of
the Evaluator was incorrect. The Evaluator would bail after matching a
single node but instead it's meant to continue until it runs out of
parent nodes.
2015-08-19 20:14:20 +02:00
Yorick Peterse d8fbaf75d8 Ruby generator support for while loops 2015-08-19 20:14:20 +02:00
Yorick Peterse 9925b2a9c9 XPath compiler support for predicates
This currently supports index predicates (e.g. "foo[10]") and predicates
using paths (e.g. foo[bar/baz]). The usage of boolean operators and more
complex expressions has not yet been tested as these are not yet
supported in the first place.
2015-08-19 20:14:20 +02:00
Yorick Peterse 7fdf8d7460 Rewrote XPath compiler predicate specs 2015-08-19 20:14:20 +02:00
Yorick Peterse 6f6151fd52 Added Ruby generator support for Symbols 2015-08-19 20:14:20 +02:00
Yorick Peterse 05a57a807e XPath compiler support for variable references 2015-08-19 20:14:20 +02:00
Yorick Peterse cf2405998b Ruby::Generator support for #[] methods 2015-08-19 20:14:20 +02:00
Yorick Peterse 17f6b3a3bb Added simple method docs for the XPath compiler 2015-08-19 20:14:20 +02:00
Yorick Peterse 2c1b4e7cbc Support for generating "else" statements 2015-08-19 20:14:20 +02:00
Yorick Peterse ac6c0d806e Updated XPath variables spec to use the compiler 2015-08-19 20:14:20 +02:00
Yorick Peterse ebcadd1cb8 XPath compiler support for absolute paths/integers 2015-08-19 20:14:20 +02:00
Yorick Peterse 94f7f85dc3 Added XML::Document#root_node 2015-08-19 20:14:20 +02:00
Yorick Peterse a7744b7a5c Use the XPath compiler for XPath/CSS specs 2015-08-19 20:14:20 +02:00
Yorick Peterse 3300a6df49 Added XPath::Compiler.compile_with_cache 2015-08-19 20:14:20 +02:00
Yorick Peterse 6d01adafc7 XPath compiler now actually returns a Proc 2015-08-19 20:14:20 +02:00
Yorick Peterse d11a754946 Basic support for compiling XPath to Ruby
This currently comes with exactly 0% test coverage. Once I've
implemented all required handler methods I'll be updating the current
evaluator tests to use the compiler instead. This removes the need for
writing an entirely new set of tests.

Currently the compiler is only capable of compiling basic expressions
such as "foo", "foo/bar" and "foo[@x="y"]/bar".
2015-08-19 20:14:20 +02:00
Yorick Peterse 6daff674d9 Use "parse" instead of "parse_xml" 2015-08-19 20:14:20 +02:00
Yorick Peterse 337d126264 Added Ruby::Generator class
This class will be used to serialize a Ruby AST back to valid Ruby
source code (as a String).
2015-08-19 20:14:20 +02:00
Yorick Peterse 6673f176d8 Added Oga::Ruby::Node
This class will be used for building Ruby ASTs that will be generated
based on XPath expressions.
2015-08-19 20:14:20 +02:00
Yorick Peterse c25879f18e Removed some explicit returns in .rll files 2015-08-19 20:14:19 +02:00
Yorick Peterse 08c965bfbc Basic specs for the XPath compiler 2015-08-19 20:14:19 +02:00
Yorick Peterse f10b7aa065 Super basic boilerplate for the XPath compiler 2015-08-19 20:14:19 +02:00
Yorick Peterse 46f3ec9df5 Configurable samples in the concurrent xpath bench 2015-08-19 13:34:41 +02:00
Yorick Peterse 399403c290 Release 1.2.3 2015-08-19 12:09:14 +02:00
Yorick Peterse 4f94d03a85 Improved NodeSet performance by a factor of 50
This change is broken up in to two parts:

1. Using a Hash to track if a node is already in a NodeSet
2. Only calling take_ownership when an owner is set

== Using a Hash

Previously various methods such as NodeSet#push and NodeSet#unshift
would call Array#include? (on the internal "nodes" Array) to see if a
node is already present in the set. This is quite problematic
performance wise, especially for large NodeSets. In fact, for the
attached benchmark the vast majority of the time was spent in
Array#include? calls.

Because a NodeSet demands ordering of nodes and must be able to access
them by index (something Set can't do without relying on Enumerable), a
Hash is used to separately keep track of what nodes are in a NodeSet.
This means that checking the presence of a node is simply a matter of
checking a Hash key's presence.

== Calling take_ownership

The if-check for the "owner" variable has been moved out of the
"take_ownership" method and into the methods that call "take_ownership".
This ensures the method isn't called in the first place if no owner is
present, at the cost of slightly more code repetition. The same applies
to the "remove_ownership" method.

== Conclusion

The combined result is a speedup of about 50x when running the attached
concurrent_time_bench.rb benchmark.
2015-08-19 01:36:37 +02:00