diff --git a/Syntaxes/Ruby.plist b/Syntaxes/Ruby.plist index 2802c0b..9b1cb06 100644 --- a/Syntaxes/Ruby.plist +++ b/Syntaxes/Ruby.plist @@ -104,149 +104,693 @@ Ruby patterns + + begin + ^\s*(class) + beginCaptures + + 1 + + name + keyword.control.class.begin.ruby + + + end + (?<!\.|::)\bend\b(?![?!]) + endCaptures + + 0 + + name + keyword.control.class.end.ruby + + + name + meta.class.ruby + patterns + + + begin + \G\s+(?:([.a-zA-Z0-9_:]+)(?:\s*(<)\s*([.a-zA-Z0-9_:]+))?|(<<)\s*([.a-zA-Z0-9_:]+)) + beginCaptures + + 1 + + name + entity.name.type.class.ruby + patterns + + + captures + + 1 + + name + punctuation.separator.namespace.ruby + + + comment + Mark as namespace separator if double colons followed by capital letter + match + (::)\s*(?=[A-Z]) + + + include + $self + + + + 2 + + name + keyword.operator.other.ruby + + 3 + + name + entity.other.inherited-class.ruby + patterns + + + captures + + 1 + + name + punctuation.separator.namespace.ruby + + + comment + Mark as namespace separator if double colons followed by capital letter + match + (::)\s*(?=[A-Z]) + + + include + $self + + + + 4 + + name + keyword.operator.other.ruby + + 5 + + name + variable.other.object.ruby + patterns + + + include + $self + + + + + end + (?=;|$) + endCaptures + + 1 + + name + keyword.control.do.optional.ruby + + + + + include + $self + + + + + begin + ^\s*(module) + beginCaptures + + 1 + + name + keyword.control.module.begin.ruby + + + end + (?<!\.|::)\bend\b(?![?!]) + endCaptures + + 0 + + name + keyword.control.module.end.ruby + + + name + meta.module.ruby + patterns + + + begin + \G\s+(([A-Z]\w*(::))?([A-Z]\w*(::))?([A-Z]\w*(::))*[A-Z]\w*) + beginCaptures + + 1 + + name + entity.name.type.module.ruby + + 2 + + name + entity.other.inherited-class.module.first.ruby + + 3 + + name + punctuation.separator.inheritance.ruby + + 4 + + name + entity.other.inherited-class.module.second.ruby + + 5 + + name + punctuation.separator.inheritance.ruby + + 6 + + name + entity.other.inherited-class.module.third.ruby + + 7 + + name + punctuation.separator.inheritance.ruby + + + end + (?=;|$) + + + include + $self + + + + + comment + else if is a common mistake carried over from other languages. it works if you put in a second end, but it’s never what you want. + match + (?<!\.)\belse(\s)+if\b + name + invalid.deprecated.ruby + + + captures + + 1 + + name + punctuation.definition.constant.ruby + + + comment + symbols as hash key (1.9 syntax) + match + (?>[a-zA-Z_]\w*(?>[?!])?)(:)(?!:) + name + constant.other.symbol.hashkey.ruby + captures 1 name - keyword.control.class.ruby + punctuation.definition.constant.ruby + + + comment + symbols as hash key (1.8 syntax) + match + (?<!:)(:)(?>[a-zA-Z_]\w*(?>[?!])?)(?=\s*=>) + name + constant.other.symbol.hashkey.ruby + + + begin + (?<!^\.|[^.]\.|::)\b(for)\b(?![?!]) + beginCaptures + + 1 + + name + keyword.control.for.begin.ruby + + + end + (?<!\.|::)\bend\b(?![?!]) + endCaptures + + 0 + + name + keyword.control.for.end.ruby + + + name + meta.syntax.for-block.ruby + patterns + + + begin + \G\s+(.+?)\s+\b(in)\b + beginCaptures + + 1 + + patterns + + + include + $self + + + + 2 + + name + keyword.control.in.ruby + + + end + (?<![^.]\.|::)(\bdo\b)(?![?!])|;|$ + endCaptures + + 1 + + name + keyword.control.do.optional.ruby + + + patterns + + + include + $self + + + + + include + $self + + + + + begin + (?<!^\.|[^.]\.|::)\b(do)\b(?![?!])\s*(\|[^|]*\|)? + beginCaptures + + 1 + + name + keyword.control.do.begin.ruby 2 + + patterns + + + include + $self + + + + + end + (?<!\.|::)\bend\b(?![?!]) + endCaptures + + 0 name - entity.name.type.class.ruby + keyword.control.do.end.ruby - 3 + + name + meta.syntax.do-block.ruby + patterns + + + include + $self + + + + + begin + (?<!^\.|[^.]\.|::)\b(begin)\b(?![?!]) + beginCaptures + + 1 name - keyword.operator.other.ruby + keyword.control.begin-block.begin.ruby - 4 + + end + (?<!\.|::)\bend\b(?![?!]) + endCaptures + + 0 name - entity.other.inherited-class.ruby + keyword.control.begin-block.end.ruby - 5 + + name + meta.syntax.begin-block.ruby + patterns + + + include + $self + + + + + begin + (?<!^\.|[^.]\.|::)\b(case)\b(?![?!]) + beginCaptures + + 1 name - keyword.operator.other.ruby + keyword.control.case.begin.ruby - 6 + + end + (?<!\.|::)\bend\b(?![?!]) + endCaptures + + 0 name - variable.other.object.ruby + keyword.control.case.end.ruby - match - ^\s*(class)\s+(?:([.a-zA-Z0-9_:]+)(?:\s*(<)\s*([.a-zA-Z0-9_:]+))?|(<<)\s*([.a-zA-Z0-9_:]+)) name - meta.class.ruby + meta.syntax.case-block.ruby + patterns + + + include + $self + + - captures + begin + (?x) + (?: + ^ # beginning of line + | (?<= # or look-behind on: + [=>~(?:\[,|&;] + | [\s;]if\s # keywords + | [\s;]elsif\s + | [\s;]while\s + | [\s;]unless\s + | [\s;]when\s + | [\s;]assert_match\s + | [\s;]or\s # boolean opperators + | [\s;]and\s + | [\s;]not\s + | [\s.]index\s # methods + | [\s.]scan\s + | [\s.]sub\s + | [\s.]sub!\s + | [\s.]gsub\s + | [\s.]gsub!\s + | [\s.]match\s + ) + | (?<= # or a look-behind with line anchor: + ^when\s # duplication necessary due to limits of regex + | ^if\s + | ^elsif\s + | ^while\s + | ^unless\s + ) + ) + \s*((/))(?![*+{}?]) + + beginCaptures + + 1 + + name + string.regexp.classic.ruby + + 2 + + name + punctuation.definition.string.ruby + + + comment + regular expressions (normal) + we only start a regexp if the character before it (excluding whitespace) + is what we think is before a regexp + + contentName + string.regexp.classic.ruby + end + ((/[eimnosux]*))\s*(?:(\b(?:if|unless)\b(?![?!]))|(\b(?:while|until)\b(?![?!])))? + endCaptures 1 name - keyword.control.module.ruby + string.regexp.classic.ruby 2 name - entity.name.type.module.ruby + punctuation.definition.string.ruby 3 name - entity.other.inherited-class.module.first.ruby + keyword.control.if-unless.modifier.ruby 4 name - punctuation.separator.inheritance.ruby + keyword.control.while-until.modifier.ruby - 5 + + patterns + - name - entity.other.inherited-class.module.second.ruby + include + #regex_sub - 6 + + + + captures + + 1 name - punctuation.separator.inheritance.ruby + keyword.control.if-unless.modifier.ruby - 7 + + match + (?x) + (?<=[}\])\w?!"'`]) + (?<!\Wif|^if| # \WX|^X is equivalent to \bX + \Wunless|^unless| # this is workaround for code editors which doesn't support onigomo + \Wcase|^case| # https://github.com/microsoft/vscode-textmate/issues/121#issuecomment-565689295 + \Wwhen|^when| + \Wwhile|^while| + \Wuntil|^until| + \Wfor|^for| + \Wbegin|^begin| + \Wand|^and| + \Wnot|^not| + \Wor|^or| + \Win|^in| + \W!|^!| + \W\?|^\?) + \s*\b(if|unless)\b(?![?!]) + + + + begin + (?x) + (?<!::) + (?<=<|&|\||=|>|~|\^|[+\-*/%]|\.{2}|\.{3}|^|;|:| + \Wif|^if| # \WX|^X is equivalent to \bX + \Wunless|^unless| # this is workaround for code editors which doesn't support onigomo + \Wcase|^case| # https://github.com/microsoft/vscode-textmate/issues/121#issuecomment-565689295 + \Wwhen|^when| + \Wwhile|^while| + \Wuntil|^until| + \Wfor|^for| + \Wbegin|^begin| + \Wand|^and| + \Wnot|^not| + \Wor|^or| + \Win|^in| + \W!|^!| + \W\?|^\?) + \s*\b(if|unless)\b(?![?!]) + + beginCaptures + + 1 name - entity.other.inherited-class.module.third.ruby + keyword.control.if-unless.begin.ruby - 8 + + end + (?<!\.|::)\bend\b(?![?!]) + endCaptures + + 0 name - punctuation.separator.inheritance.ruby + keyword.control.if-unless.end.ruby - match - ^\s*(module)\s+(([A-Z]\w*(::))?([A-Z]\w*(::))?([A-Z]\w*(::))*[A-Z]\w*) name - meta.module.ruby + meta.syntax.if-unless-block.ruby + patterns + + + include + $self + + - comment - else if is a common mistake carried over from other languages. it works if you put in a second end, but it’s never what you want. match - (?<!\.)\belse(\s)+if\b + (?x) + (?<=[}\])\w?!"'`]) + (?<!\Wif|^if| # \WX|^X is equivalent to \bX + \Wunless|^unless| # this is workaround for code editors which doesn't support onigomo + \Wcase|^case| # https://github.com/microsoft/vscode-textmate/issues/121#issuecomment-565689295 + \Wwhen|^when| + \Wwhile|^while| + \Wuntil|^until| + \Wfor|^for| + \Wbegin|^begin| + \Wand|^and| + \Wnot|^not| + \Wor|^or| + \Win|^in| + \W!|^!| + \W\?|^\?) + \s*\b(while|until)\b(?![?!]) + name - invalid.deprecated.ruby + keyword.control.while-until.modifier.ruby - captures + begin + (?x) + (?<!::) + (?<=<|&|\||=|>|~|\^|[+\-*/%]|\.{2}|\.{3}|^|;|:| + \Wif|^if| # \WX|^X is equivalent to \bX + \Wunless|^unless| # this is workaround for code editors which doesn't support onigomo + \Wcase|^case| # https://github.com/microsoft/vscode-textmate/issues/121#issuecomment-565689295 + \Wwhen|^when| + \Wwhile|^while| + \Wuntil|^until| + \Wfor|^for| + \Wbegin|^begin| + \Wand|^and| + \Wnot|^not| + \Wor|^or| + \Win|^in| + \W!|^!| + \W\?|^\?) + \s*\b(while|until)\b(?![?!]) + + beginCaptures 1 name - punctuation.definition.constant.ruby + keyword.control.while-until.begin.ruby - comment - symbols as hash key (1.9 syntax) - match - (?>[a-zA-Z_]\w*(?>[?!])?)(:)(?!:) - name - constant.other.symbol.hashkey.ruby - - - captures + end + (?<!\.|::)\bend\b(?![?!]) + endCaptures - 1 + 0 name - punctuation.definition.constant.ruby + keyword.control.while-until.end.ruby - comment - symbols as hash key (1.8 syntax) + name + meta.syntax.while-until-block.ruby + patterns + + + begin + \G + end + (?<![^.]\.|::)(\bdo\b)(?![?!])|;|$ + endCaptures + + 1 + + name + keyword.control.do.optional.ruby + + + patterns + + + include + $self + + + + + include + $self + + + + match - (?<!:)(:)(?>[a-zA-Z_]\w*(?>[?!])?)(?=\s*=>) + (?<!\.|::)\brescue\b(?![?!]) name - constant.other.symbol.hashkey.ruby + keyword.control.rescue.ruby - comment - everything being a reserved word, not a value and needing a 'end' is a.. match - (?<!\.)\b(BEGIN|begin|case|class|else|elsif|END|end|ensure|for|if|in|module|rescue|then|unless|until|when|while)\b(?![?!]) + (?<!\.|::)\bensure\b(?![?!]) name - keyword.control.ruby + keyword.control.ensure.ruby comment - contextual smart pair support for block parameters + everything being a reserved word, not a value and needing a 'end' is a.. match - (?<!\.)\bdo\b + (?<!\.)\b(BEGIN|else|elsif|END|end|in|then|when)\b(?![?!]) name - keyword.control.start-block.ruby + keyword.control.ruby comment @@ -274,42 +818,6 @@ name variable.language.ruby - - begin - ^__END__\n - captures - - 0 - - name - string.unquoted.program-block.ruby - - - comment - __END__ marker - contentName - text.plain - end - (?=not)impossible - patterns - - - begin - (?=<?xml|<(?i:html\b)|!DOCTYPE (?i:html\b)) - end - (?=not)impossible - name - text.html.embedded.ruby - patterns - - - include - text.html.basic - - - - - match \b(self)\b(?![?!]) @@ -447,19 +955,19 @@ begin (?x) - (?=def\b) # an optimization to help Oniguruma fail fast - (?<=^|\s)(def)\s+ # the def keyword - ( (?>[a-zA-Z_]\w*(?>\.|::))? # a method name prefix - (?>[a-zA-Z_]\w*(?>[?!]|=(?!>))? # the method name - |===?|!=|!~|>[>=]?|<=>|<[<=]?|[%&`/\|^]|\*\*?|=?~|[-+]@?|\[\]=?) ) # …or an operator method - \s*(\() # the openning parenthesis for arguments - + (?=def\b) # an optimization to help Oniguruma fail fast + (?<=^|\s)(def)\s+ # the def keyword + ( (?>[a-zA-Z_]\w*(?>\.|::))? # a method name prefix + (?>[a-zA-Z_]\w*(?>[?!]|=(?!>))? # the method name + |===?|!=|!~|>[>=]?|<=>|<[<=]?|[%&`/\|^]|\*\*?|=?~|[-+]@?|\[\]=?) ) # …or an operator method + \s*(\(.*\)) # the openning parenthesis for arguments + beginCaptures 1 name - keyword.control.def.ruby + keyword.control.def.begin.ruby 2 @@ -470,29 +978,6 @@ name punctuation.definition.parameters.ruby - - - comment - the method pattern comes from the symbol pattern, see there for a explaination - end - \) - endCaptures - - 0 - - name - punctuation.definition.parameters.ruby - - - name - meta.function.method.with-arguments.ruby - patterns - - - begin - (?=[&*_a-zA-Z]) - end - (?=[,)]) patterns @@ -536,6 +1021,27 @@ + + comment + the method pattern comes from the symbol pattern, see there for a explaination + end + (?<!\.|::)\bend\b(?![?!]) + endCaptures + + 0 + + name + keyword.control.def.end.ruby + + + name + meta.function.method.with-arguments.ruby + patterns + + + include + $self + repository @@ -620,20 +1126,20 @@ begin (?x) - (?=def\b) # an optimization to help Oniguruma fail fast - (?<=^|\s)(def)\s+ # the def keyword - ( (?>[a-zA-Z_]\w*(?>\.|::))? # a method name prefix - (?>[a-zA-Z_]\w*(?>[?!]|=(?!>))? # the method name - |===?|!=|!~|>[>=]?|<=>|<[<=]?|[%&`/\|^]|\*\*?|=?~|[-+]@?|\[\]=?) ) # …or an operator method - [ \t] # the space separating the arguments - (?=[ \t]*[^\s#;]) # make sure arguments and not a comment follow - + (?=def\b) # an optimization to help Oniguruma fail fast + (?<=^|\s)(def)\s+ # the def keyword + ( (?>[a-zA-Z_]\w*(?>\.|::))? # a method name prefix + (?>[a-zA-Z_]\w*(?>[?!]|=(?!>))? # the method name + |===?|!=|!~|>[>=]?|<=>|<[<=]?|[%&`/\|^]|\*\*?|=?~|[-+]@?|\[\]=?) ) # …or an operator method + [ \t] # the space separating the arguments + (?=[ \t]*[^\s#;]) # make sure arguments and not a comment follow + beginCaptures 1 name - keyword.control.def.ruby + keyword.control.def.begin.ruby 2 @@ -644,7 +1150,15 @@ comment same as the previous rule, but without parentheses around the arguments end - $ + (?<!\.|::)\bend\b(?![?!]) + endCaptures + + 0 + + name + keyword.control.def.end.ruby + + name meta.function.method.with-arguments.ruby patterns @@ -653,7 +1167,7 @@ begin (?![\s,]) end - (?=,|$) + (?=,|(?<!\.|::)\bend\b(?![?!])|$) patterns @@ -694,12 +1208,21 @@ - captures + begin + (?x) + (?=def\b) # an optimization to help Oniguruma fail fast + (?<=^|\s)(def)\b # the def keyword + ( \s+ # an optional group of whitespace followed by… + ( (?>[a-zA-Z_]\w*(?>\.|::))? # a method name prefix + (?>[a-zA-Z_]\w*(?>[?!]|=(?!>))? # the method name + |===?|!=|!~|>[>=]?|<=>|<[<=]?|[%&`/\|^]|\*\*?|=?~|[-+]@?|\[\]=?) ) )? # …or an operator method + + beginCaptures 1 name - keyword.control.def.ruby + keyword.control.def.begin.ruby 3 @@ -709,17 +1232,25 @@ comment the optional name is just to catch the def also without a method-name - match - (?x) - (?=def\b) # an optimization to help Oniguruma fail fast - (?<=^|\s)(def)\b # the def keyword - ( \s+ # an optional group of whitespace followed by… - ( (?>[a-zA-Z_]\w*(?>\.|::))? # a method name prefix - (?>[a-zA-Z_]\w*(?>[?!]|=(?!>))? # the method name - |===?|!=|!~|>[>=]?|<=>|<[<=]?|[%&`/\|^]|\*\*?|=?~|[-+]@?|\[\]=?) ) )? # …or an operator method - + end + (?<!\.|::)\bend\b(?![?!]) + endCaptures + + 0 + + name + keyword.control.def.end.ruby + + name meta.function.method.without-arguments.ruby + patterns + + + include + $self + + match @@ -924,70 +1455,6 @@ include #percent_literals - - begin - (?x) - (?: - ^ # beginning of line - | (?<= # or look-behind on: - [=>~(?:\[,|&;] - | [\s;]if\s # keywords - | [\s;]elsif\s - | [\s;]while\s - | [\s;]unless\s - | [\s;]when\s - | [\s;]assert_match\s - | [\s;]or\s # boolean opperators - | [\s;]and\s - | [\s;]not\s - | [\s.]index\s # methods - | [\s.]scan\s - | [\s.]sub\s - | [\s.]sub!\s - | [\s.]gsub\s - | [\s.]gsub!\s - | [\s.]match\s - ) - | (?<= # or a look-behind with line anchor: - ^when\s # duplication necessary due to limits of regex - | ^if\s - | ^elsif\s - | ^while\s - | ^unless\s - ) - ) - \s*((/))(?![*+{}?]) - - captures - - 1 - - name - string.regexp.classic.ruby - - 2 - - name - punctuation.definition.string.ruby - - - comment - regular expressions (normal) - we only start a regexp if the character before it (excluding whitespace) - is what we think is before a regexp - - contentName - string.regexp.classic.ruby - end - ((/[eimnosux]*)) - patterns - - - include - #regex_sub - - - captures @@ -1058,34 +1525,70 @@ comment - matches questionmark-letters. - - examples (1st alternation = hex): - ?\x1 ?\x61 - - examples (2nd alternation = octal): - ?\0 ?\07 ?\017 - - examples (3rd alternation = escaped): - ?\n ?\b - - examples (4th alternation = meta-ctrl): - ?\C-a ?\M-a ?\C-\M-\C-\M-a - - examples (4th alternation = normal): - ?a ?A ?0 - ?* ?" ?( - ?. ?# + matches questionmark-letters. + examples (1st alternation = hex): + ?\x1 ?\x61 - the negative lookbehind prevents against matching - p(42.tainted?) - + examples (2nd alternation = octal): + ?\0 ?\07 ?\017 + + examples (3rd alternation = escaped): + ?\n ?\b + + examples (4th alternation = meta-ctrl): + ?\C-a ?\M-a ?\C-\M-\C-\M-a + + examples (4th alternation = normal): + ?a ?A ?0 + ?* ?" ?( + ?. ?# + + + the negative lookbehind prevents against matching + p(42.tainted?) + match (?<!\w)\?(\\(x\h{1,2}(?!\h)\b|0[0-7]{0,2}(?![0-7])\b|[^x0MC])|(\\[MC]-)+\w|[^\s\\]) name constant.numeric.ruby + + begin + ^__END__\n + captures + + 0 + + name + string.unquoted.program-block.ruby + + + comment + __END__ marker + contentName + text.plain + end + (?=not)impossible + patterns + + + begin + (?=<?xml|<(?i:html\b)|!DOCTYPE (?i:html\b)) + end + (?=not)impossible + name + text.html.embedded.ruby + patterns + + + include + text.html.basic + + + + + begin (?=(?><<[-~]("?)((?:[_\w]+_|)HTML)\b\1)) @@ -1726,17 +2229,17 @@ begin - (?>=\s*<<(\w+)) + (?<==)\s*(<<(\w+)) beginCaptures - 0 + 1 name punctuation.definition.string.begin.ruby end - ^\1$ + ^\2$ endCaptures 0 diff --git a/Tests/end_distinction.rb b/Tests/end_distinction.rb new file mode 100644 index 0000000..b936d1e --- /dev/null +++ b/Tests/end_distinction.rb @@ -0,0 +1,553 @@ +# ------------------------------------------- +# Testarea for classes +# ------------------------------------------- + +# singleline +class Foo; @@a = 1; end +class Foo::Bar << M::Baz; @@a = 1; end + +# multiline +class Foo + @@var = 1 + + $hello + @hello +end + +# ------------------------------------------- +# Testarea for classes +# ------------------------------------------- + +# singleline +module Mod; @a = 1; end +module ModOne::ModTwo; @a = 1; end + +# multiline +module Bar + class Foo + @@var = 1 + end +end + +# ------------------------------------------- +# Testarea for method without arguments +# ------------------------------------------- + +# singleline +def a; puts "a"; end +def b; def c; puts "c"; end; end +def d; puts self.end; end + +# multiline +def e + puts "e" +end + +def f + def g + puts "g" + end +end + +def h + puts self.end +end + +def i + end? # self.end? + end! # self.end! +end + +# ------------------------------------------- +# Testarea for method with arguments +# ------------------------------------------- + +# singleline +def a(arg); puts arg; end +def b; def c(arg); puts arg; end; end +def d(arg); puts arg.end; end + +# multiline +def e(arg) + puts arg +end + +def f + def g(arg) + puts arg + end +end + +def h(arg) + puts arg.end +end + +def i(arg) + end? # self.end? + end! # self.end! +end + +# ------------------------------------------- +# Testarea for method with arguments without parenthesis +# ------------------------------------------- + +# singleline +def a arg; puts arg; end +def b; def c arg; puts arg; end; end +def d arg; puts arg.end; end + +# multiline +def e arg + puts arg +end + +def f + def g arg + puts arg + end +end + +def h arg + puts arg.end +end + +def i arg + end? # self.end? + end! # self.end! +end + +# ------------------------------------------- +# Testarea for begin-block +# ------------------------------------------- + +# singleline +begin puts "foo" end +begin puts "foo"; begin puts "bar" end end +begin puts self.end end +begin puts self.end; end +begin puts end? end +begin puts end!; end +if begin true end then true else false end +1..begin 10 end +1...begin 10 end + +self.begin puts "foo" end #shouldn't work +self::begin puts "foo" end #shouldn't work +begin? puts "foo" end #shouldn't work +begin! puts "foo" end #shouldn't work + +# multiline +begin + puts "foo" +end + +begin + puts self.end +end + +begin + puts end? + puts end! +end + +begin + puts "foo" + begin + puts "bar" + end +end + +# ------------------------------------------- +# Testarea for do-block +# ------------------------------------------- + +# singleline +3.times.map do 1 end +3.times.map do || 1 end +3.times.map do |e, x=1| e + x end +[(0..10), (10..20)].map do |r| r.end end +any_method do? 1 end #shouldn't work +any_method do! 1 end #shouldn't work +self.do 1 end #shouldn't work +self::do 1 end #shouldn't work + +# multiline +[1,2,3].map do |element| + element + 1 +end + +[[1],[2],[3]].each do |element| + element.each do |subelement| + puts subelement + end +end + +[(0..10), (10..20)].map do |r| + r.end +end + +[].each do |e| + e + end? - end! +end + +3.times do + puts "foo" +end + +3.times do || + puts "bar" +end + +# ------------------------------------------- +# Testarea for for-loop +# ------------------------------------------- + +# singleline +for i in for j in [[1,2]] do break j; end do puts i; end +for i in for j in [[1,2]] do break j; end do [i].map do |e| e end; end +for i in for j in [[1,2]]; break j; end; [i].map do |e| e end; end +for i in for j in if true then [[1,2]] else [[3,4]] end; break j; end; [i].map do |e| e end; end +for i in for j in if true; [[1,2]] else [[3,4]] end; break j; end; [i].map do |e| e end; end +for i in [(0..10), (10..20)] do break i.end end +for i in [] do puts end?; puts end! end +1..for i in [1,2,3] do break i if i == 2; end +1...for i in [1,2,3] do break i if i == 2; end +10 / for i in [1,2,3] do break i if i == 2; end +#you cant use do-end blocks inside in statement +for i in 3.times.map do 1 end do puts i; end # shouldn't work +for? i in [1,2,3] # shouldn't work +for! i in [1,2,3] # shouldn't work +self.for i in [1,2,3] # shouldn't work + +# multiline +for i in [1,2,3] + puts i +end + +for i in [(0..10), (10..20)] do + puts i.end +end + +for i in [] + puts end? + puts end! +end + +for i in for j in [[1,2]] do break j; end do + r = [i].map do |e| + e + end + p r +end + +# ------------------------------------------- +# Testarea for while/until +# ------------------------------------------- + +# singleline block +i = 0 +while i < 10; i += 1; end +while i < 10 do i += 1; end +a = while i < 10 do break i if i == 5; i += 1; end +false || while i < 10 do break i if i == 5; i += 1; end +false or while i < 10; break i if i == 5; i += 1; end +true && while i < 10; break i if i == 5; i += 1; end +true and while i < 10 do break i if i == 5; i += 1; end +1..while i < 10 do break i if i == 5; i += 1; end +1...while i < 10 do break i if i == 5; i += 1; end +true ? while i < 10; break i if i == 5; i += 1; end : while i < 10; break i if i == 5; i += 1; end +!while i < 10; break i if i == 5; i += 1; end +! while i < 10; break i if i == 5; i += 1; end +true && !while i < 10; break i if i == 5; i += 1; end +true && ! while i < 10; break i if i == 5; i += 1; end +while i < while j < 10; break j if j == 5; j+=1; end; break i if i > 3; i += 1; end +while i < while j < 10 do break j if j == 5; j+=1; end; break i if i > 3; i += 1; end +while i < while j < 10; break j if j == 5; j+=1; end do break i if i > 3; i += 1; end +while i < while j < 10 do break j if j == 5; j+=1; end do break i if i > 3; i += 1; end +while false do [1,2,3].each do |e| puts e end; end +while false do [(0..10), (10..20)].each do |r| puts r.end end end +while false do puts end?; puts end! end + +# singleline modifier +foo::while false # shouldn't work +while? false # shouldn't work +while! false # shouldn't work +foo.while false # shouldn't work +acc = 0 +acc += 10 while acc < 1000 +a = /regex/ while acc < 10 +{} while false +[] while false +"foo" while false +'foo' while false +(expression) while false +foo! while false +foo? while false +method_without_args while false +method(with, args) while false +method with, args while false +`ls` while false + +# multiline block +while i < 10 + i += 1 +end + +while i < 10 do + i += 1 +end + +10 / while i < 10 do + break i if i == 5 + i += 1 +end + +while false do + [(0..10), (10..20)].each do |r| + puts r.end + end +end + +while false do + puts end? + puts end! +end + +begin + i += 1 +end; while i < 100 do i += 1; end + +# multiline modifier +begin + i += 1 +end while i < 100 + +# ------------------------------------------- +# Testarea for if/unless +# ------------------------------------------- + +# singleline block +1..if true; 10 else 20 end +1...if true then 10 else 20 end +if while i < 10 do break i if i == 5; i += 1; end < 10 then true else false end +if true then 1 else 2 end +true ? if true then true else false end : if true then true else false end +if if true then true else false end; 1 else 0 end +if if true then true else false end then 1 else 0 end +if if true; true else false end then 1 else 0 end +if if true; true else false end; 1 else 0 end +20 / if true then 10 else 5 end +20 / if true; 10 else 5 end +!if true then true else false end +! if true then true else false end +true && !if true then true else false end +true && ! if true then true else false end +a = /hello/; 20 / if true then 1 else 2 end +a = /hello/; if true then 1 else 2 end +if true then puts (1..10).end else puts (1..20).end end +if true then puts end? else puts end! end + +# singleline modifier +foo::if something # shouldn't work +foo.if something # shouldn't work +if? something # shouldn't work +if! something # shouldn't work +foo! if true +foo? if true +return {} if something +return [] if something +(expression) if something +method_without_args if something +method(with, args) if something +method with, args if somethign +a = /regexp/ if something +"hello".scan /[eo]/ if something +`ls` if true + +# singleline mix +%w(hello, world, foo).map { |e| e.scan /[oeiua]/ } * if true; 2 else 0 end +%w(hello, world, foo).map { |e| e.scan /[oeiua]/ if true } * if true then 2 else 0 end +e.scan /[oeiua]/ if true; if true then 2 else 0 end + +# multiline block +if something then + if true + foo + else + bar + end +else + baz +end + +if true + puts (1..10).end +else + puts (1..20).end +end + +if true + puts end? +else + puts end! +end + +begin + 1 +end; if true; true else false end + +# multiline modifier +begin + 1 +end if true + +# ------------------------------------------- +# Testarea for case +# ------------------------------------------- + +# singleline +case 15 when 0..50 then "foo" when 51..100 then "bar" else "baz" end +case x = rand(1..100) when 0..50 then case x when 0..25 then 1 else 2 end when 51..100 then case x when 51..75 then 3 else 4 end end +1..case 15 when 0..50 then 10 when 51..100 then 20 else 30 end +1...case 15 when 0..50 then 10 when 51..100 then 20 else 30 end +case x = rand(1..100) when 0..50 then puts (1..10).end when 51..100 then puts (1..20).end end +case x = rand(1..100) when 0..50 then puts end? when 51..100 then puts end! end + +self.case 15 when 0..50 then "foo" when 51..100 then "bar" else "baz" end # shouldn't work +self::case 15 when 0..50 then "foo" when 51..100 then "bar" else "baz" end # shouldn't work +case? 15 when 0..50 then "foo" when 51..100 then "bar" else "baz" end # shouldn't work +case! 15 when 0..50 then "foo" when 51..100 then "bar" else "baz" end # shouldn't work + +# multiline +case 15 +when 0..50 + "foo" +when 51..100 + "bar" +else + "baz" +end + +case x = rand(1..100) +when 0..50 then + puts (1..10).end +when 51..100 then + puts (1..20).end +end + +case x = rand(1..100) +when 0..50 then + puts end? +when 51..100 then + puts end! +end + + +case if [true, false].sample then 25 else 75 end +when 0..50 + "foo" +when 51..100 + "bar" +else + "baz" +end + +case x = rand(1..100) +when 0..50 then + case x + when 0..25 then + 1 + else + 2 + end +when 51..100 then + case x + when 51..75 then + 3 + else + 4 + end +end + +# ------------------------------------------- +# Testarea for rescue & ensure +# ------------------------------------------- + +# singleline +some_method rescue handle_error +some_method rescue SomeException + +self.rescue handle_error # shouldn't work +self::rescue handle_error # shouldn't work +some_method rescue? handle_error # shouldn't work +some_method rescue! SomeException # shouldn't work + +# multiline +begin + some_method +rescue + handle_error +ensure + close_connection +end + +begin + some_method +rescue SomeException + handle_error +ensure + close_connection +end + +def method1 + some_method +rescue + handle_error +ensure + close_connection +end + +def method2 + some_method +rescue SomeException => e + log(e) + handle_error +ensure + close_connection +end + +def method3 + some_method +rescue? SomeException => e # shouldn't work + log(e) + handle_error +ensure? # shouldn't work + close_connection +end + +def method4 + some_method +rescue! SomeException => e # shouldn't work + log(e) + handle_error +ensure! # shouldn't work + close_connection +end + +def method5 + some_method +.rescue SomeException => e # shouldn't work + log(e) + handle_error +.ensure # shouldn't work + close_connection +end + +def method6 + some_method +::rescue SomeException => e # shouldn't work + log(e) + handle_error +::ensure # shouldn't work + close_connection +end