Skip to content

Commit

Permalink
Merge pull request #8233 from enebo/regex_linear
Browse files Browse the repository at this point in the history
Implement Regexp#linear_time?
  • Loading branch information
enebo committed May 13, 2024
2 parents 476962b + 7e61ccd commit c226852
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 3 deletions.
2 changes: 1 addition & 1 deletion core/pom.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
jar 'com.github.jnr:jffi:${jffi.version}'
jar 'com.github.jnr:jffi:${jffi.version}:native'

jar 'org.jruby.joni:joni:2.2.1'
jar 'org.jruby.joni:joni:2.2.2-SNAPSHOT'
jar 'org.jruby.jcodings:jcodings:1.0.58'
jar 'org.jruby:dirgra:0.5'

Expand Down
2 changes: 1 addition & 1 deletion core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ DO NOT MODIFY - GENERATED CODE
<dependency>
<groupId>org.jruby.joni</groupId>
<artifactId>joni</artifactId>
<version>2.2.1</version>
<version>2.2.2-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.jruby.jcodings</groupId>
Expand Down
44 changes: 43 additions & 1 deletion core/src/main/java/org/jruby/RubyRegexp.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

package org.jruby;

import static org.jruby.RubyNumeric.fix2int;
import static org.jruby.anno.FrameField.BACKREF;
import static org.jruby.anno.FrameField.LASTLINE;

Expand Down Expand Up @@ -75,6 +76,7 @@
import org.jruby.util.io.EncodingUtils;
import org.jruby.util.collections.WeakValuedMap;

import static org.jruby.api.Convert.castToHash;
import static org.jruby.api.Error.typeError;
import static org.jruby.util.RubyStringBuilder.str;
import static org.jruby.util.StringSupport.CR_7BIT;
Expand Down Expand Up @@ -874,7 +876,7 @@ public IRubyObject initialize_copy(IRubyObject re) {

private static int objectAsJoniOptions(IRubyObject arg) {
Ruby runtime = arg.getRuntime();
if (arg instanceof RubyFixnum) return RubyNumeric.fix2int(arg);
if (arg instanceof RubyFixnum) return fix2int(arg);
if (arg instanceof RubyString) return RegexpOptions.fromByteList(runtime, ((RubyString) arg).getByteList()).toJoniOptions();
if (arg instanceof RubyBoolean) {
if (arg.isTrue()) return RE_OPTION_IGNORECASE;
Expand Down Expand Up @@ -1496,6 +1498,46 @@ public IRubyObject fixed_encoding_p(ThreadContext context) {
return RubyBoolean.newBoolean(context, options.isFixed());
}

private record RegexpArgs(RubyString string, int options, IRubyObject timeout) {}

// MRI: reg_extract_args - This does not break the regexp into a String value since it will never used if the first
// argument is a Regexp. This also is true of MRI so I am not sure why they do the string part.
private static RegexpArgs extractRegexpArgs(ThreadContext context, IRubyObject[] args) {
int callInfo = ThreadContext.resetCallInfo(context);
int length = args.length;

IRubyObject timeout = null;
if ((callInfo & ThreadContext.CALL_KEYWORD) != 0) {
length--;
RubyHash opts = castToHash(context, args[args.length - 1]);
timeout = opts.fastARef(context.runtime.newSymbol("timeout"));
}

RubyString string;
int opts = 0;
if (args[0] instanceof RubyRegexp) {
if (length > 1) context.runtime.getWarnings().warn("flags ignored");
string = null;
} else {
if (length > 1) opts = objectAsJoniOptions(args[1]);
string = args[0].convertToString();
}

return new RegexpArgs(string, opts, timeout);
}

@JRubyMethod(name = "linear_time?", meta = true, required = 1, optional = 1)
public static IRubyObject linear_time_p(ThreadContext context, IRubyObject recv, IRubyObject[] args) {
RegexpArgs regexpArgs = extractRegexpArgs(context, args);
RubyRegexp regexp = args[0] instanceof RubyRegexp reg ?
reg : newRegexpFromStr(context.runtime, regexpArgs.string, regexpArgs.options);

Regex pattern = regexp.pattern;

// Regexp.allocate will make a regexp instance with no pattern.
return pattern != null && pattern.isLinear() ? context.tru : context.fals;
}

/** rb_reg_nth_match
*
*/
Expand Down

0 comments on commit c226852

Please sign in to comment.