Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: opal/opal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: f7567d664c20
Choose a base ref
...
head repository: opal/opal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: bb1b329ac8a4
Choose a head ref
  • 2 commits
  • 5 files changed
  • 2 contributors

Commits on Apr 29, 2015

  1. Copy the full SHA
    758297e View commit details
  2. Merge pull request #818 from vais/match

    String#match and Regexp#match fully compliant with rubyspec
    elia committed Apr 29, 2015

    Unverified

    This commit is not signed, but one or more authors requires that any commit attributed to them is signed.
    Copy the full SHA
    bb1b329 View commit details
Showing with 32 additions and 77 deletions.
  1. +29 −63 opal/corelib/regexp.rb
  2. +1 −1 spec/corelib
  3. +0 −7 spec/filters/bugs/regexp.rb
  4. +0 −6 spec/filters/bugs/string.rb
  5. +2 −0 spec/filters/unsupported/regular_expressions.rb
92 changes: 29 additions & 63 deletions opal/corelib/regexp.rb
Original file line number Diff line number Diff line change
@@ -50,38 +50,7 @@ def ===(str)
end

def =~(string)
if `string === nil`
$~ = nil

return
end

string = Opal.coerce_to(string, String, :to_str).to_s

%x{
var re = self;
if (re.global) {
// should we clear it afterwards too?
re.lastIndex = 0;
}
else {
// rewrite regular expression to add the global flag to capture pre/post match
re = new RegExp(re.source, 'g' + (re.multiline ? 'm' : '') + (re.ignoreCase ? 'i' : ''));
}
var result = re.exec(string);
if (result) {
#{$~ = MatchData.new(`re`, `result`)};
return result.index;
}
else {
#{$~ = nil};
return nil;
}
}
return match(string) && $~.begin(0)
end

alias eql? ==
@@ -91,49 +60,46 @@ def inspect
end

def match(string, pos = undefined, &block)
if `string === nil`
$~ = nil

return
end

if `string.$$is_string == null`
unless string.respond_to? :to_str
raise TypeError, "no implicit conversion of #{string.class} into String"
end

string = string.to_str
end

%x{
var re = self;
if (re.global) {
// should we clear it afterwards too?
re.lastIndex = 0;
if (pos === undefined) {
pos = 0;
} else {
pos = #{Opal.coerce_to(pos, Integer, :to_int)};
}
else {
re = new RegExp(re.source, 'g' + (re.multiline ? 'm' : '') + (re.ignoreCase ? 'i' : ''));
if (string === nil) {
return #{$~ = nil};
}
var result = re.exec(string);
string = #{Opal.coerce_to(string, String, :to_str)};
if (result) {
result = #{$~ = MatchData.new(`re`, `result`)};
if (pos < 0) {
pos += string.length;
if (pos < 0) {
return #{$~ = nil};
}
}
if (block === nil) {
return result;
var md, re = new RegExp(self.source, 'gm' + (self.ignoreCase ? 'i' : ''));
while (true) {
md = re.exec(string);
if (md === null) {
return #{$~ = nil};
}
else {
return #{block.call(`result`)};
if (md.index >= pos) {
#{$~ = MatchData.new(`re`, `md`)}
return block === nil ? #{$~} : #{block.call($~)};
}
}
else {
return #{$~ = nil};
re.lastIndex = md.index + 1;
}
}
end

def ~
self =~ $_
end

def source
`self.source`
end
2 changes: 1 addition & 1 deletion spec/corelib
7 changes: 0 additions & 7 deletions spec/filters/bugs/regexp.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,2 @@
opal_filter "RegExp" do
fails "Regexp#eql? is true if self and other have the same character set code"
fails "Regexp#== is true if self and other have the same character set code"
fails "Regexp#~ matches against the contents of $_"
fails "Regexp#match uses the start as a character offset"
fails "Regexp#match matches the input at a given position"
fails "Regexp#match with [string, position] when given a positive position matches the input at a given position"
fails "Regexp#match with [string, position] when given a negative position matches the input at a given position"
end
6 changes: 0 additions & 6 deletions spec/filters/bugs/string.rb
Original file line number Diff line number Diff line change
@@ -66,12 +66,6 @@
fails "String#initialize with no arguments does not raise an exception when frozen"
fails "String#initialize is a private method"

fails "String#match matches a literal Regexp that uses ASCII-only UTF-8 escape sequences"
fails "String#match raises a TypeError if pattern is not a regexp or a string"
fails "String#match matches \\G at the start of the string"
fails "String#match with [pattern, position] when given a positive position matches the pattern against self starting at an optional index"
fails "String#match with [pattern, position] when given a negative position matches the pattern against self starting at an optional index"

fails "String#to_c returns a Complex object"
fails "String#to_c understands integers"
fails "String#to_c understands negative integers"
2 changes: 2 additions & 0 deletions spec/filters/unsupported/regular_expressions.rb
Original file line number Diff line number Diff line change
@@ -9,4 +9,6 @@
fails "String#gsub with pattern and replacement returns a copy of self with all occurrences of pattern replaced with replacement" #Only fails str.gsub(/\Ah\S+\s*/, "huh? ").should == "huh? homely world. hah!"

fails "String#scan supports \\G which matches the end of the previous match / string start for first match"

fails "String#match matches \\G at the start of the string"
end