fdlint 0.1.3 → 0.2.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +2 -9
- data/Gemfile.lock +14 -4
- data/Rakefile +9 -85
- data/bin/fdlint +71 -8
- data/lib/fdlint/cli.rb +102 -0
- data/lib/{file_validator.rb → fdlint/file_validator.rb} +0 -0
- data/lib/fdlint/helper/code_type.rb +55 -0
- data/lib/fdlint/helper/file_reader.rb +19 -0
- data/lib/fdlint/helper/logger.rb +35 -0
- data/lib/fdlint/log_entry.rb +51 -0
- data/lib/fdlint/parser/base_parser.rb +151 -0
- data/lib/{css/parser.rb → fdlint/parser/css/css_parser.rb} +31 -28
- data/lib/{css → fdlint/parser/css}/struct.rb +5 -5
- data/lib/{encoding_error.rb → fdlint/parser/encoding_error.rb} +2 -2
- data/lib/{html/parser.rb → fdlint/parser/html/html_parser.rb} +26 -20
- data/lib/{html → fdlint/parser/html}/query.rb +0 -0
- data/lib/{html → fdlint/parser/html}/rule/check_tag_rule.rb +0 -0
- data/lib/{html → fdlint/parser/html}/struct.rb +82 -38
- data/lib/fdlint/parser/js/expr/expr.rb +71 -0
- data/lib/fdlint/parser/js/expr/left_hand.rb +65 -0
- data/lib/fdlint/parser/js/expr/operate.rb +94 -0
- data/lib/fdlint/parser/js/expr/primary.rb +168 -0
- data/lib/{js/parser.rb → fdlint/parser/js/js_parser.rb} +11 -9
- data/lib/fdlint/parser/js/stat/if.rb +27 -0
- data/lib/fdlint/parser/js/stat/iter.rb +88 -0
- data/lib/fdlint/parser/js/stat/stat.rb +120 -0
- data/lib/fdlint/parser/js/stat/switch.rb +67 -0
- data/lib/fdlint/parser/js/stat/try.rb +30 -0
- data/lib/fdlint/parser/js/stat/var.rb +42 -0
- data/lib/fdlint/parser/js/struct.rb +257 -0
- data/lib/fdlint/parser/node.rb +27 -0
- data/lib/fdlint/parser/parse_error.rb +10 -0
- data/lib/fdlint/parser/parser_visitable.rb +134 -0
- data/lib/{position_info.rb → fdlint/parser/position_info.rb} +12 -1
- data/lib/fdlint/parser.rb +3 -0
- data/lib/fdlint/printer/base_printer.rb +20 -0
- data/lib/fdlint/printer/console_printer.rb +80 -0
- data/lib/fdlint/printer/nocolor_printer.rb +29 -0
- data/lib/fdlint/printer/vim_printer.rb +21 -0
- data/lib/fdlint/printer.rb +1 -0
- data/lib/fdlint/rule/dsl.rb +83 -0
- data/lib/fdlint/rule/validation.rb +79 -0
- data/lib/fdlint/rule.rb +81 -0
- data/lib/fdlint/support/core/array.rb +5 -0
- data/lib/fdlint/support/core/file.rb +8 -0
- data/lib/fdlint/support/core/hash.rb +5 -0
- data/lib/fdlint/support/core/nil.rb +7 -0
- data/lib/fdlint/support/core/string.rb +7 -0
- data/lib/fdlint/support/core_ext.rb +5 -0
- data/lib/fdlint/validator.rb +102 -0
- data/lib/fdlint/version.rb +3 -0
- data/lib/fdlint.rb +5 -0
- data/rules.d/css.rule.rb +100 -0
- data/rules.d/filename.rule.rb +49 -0
- data/rules.d/html.rule.rb +169 -0
- data/rules.d/js.jquery.rule.rb +49 -0
- data/rules.d/js.rule.rb +205 -0
- data/test/default_test.rb +14 -0
- data/test/fixtures/js/scope-test.js +15 -2
- data/test/test_helper.rb +9 -0
- metadata +269 -221
- data/lib/base_parser.rb +0 -143
- data/lib/cmd_runner.rb +0 -145
- data/lib/context.rb +0 -31
- data/lib/css/reader.rb +0 -30
- data/lib/css/rule/check_compression_rule.rb +0 -48
- data/lib/css/rule/checklist.rb +0 -45
- data/lib/helper/code_type.rb +0 -50
- data/lib/helper/color_string.rb +0 -44
- data/lib/helper/file_reader.rb +0 -22
- data/lib/helper/strenc.rb +0 -65
- data/lib/js/expr/expr.rb +0 -66
- data/lib/js/expr/left_hand.rb +0 -63
- data/lib/js/expr/operate.rb +0 -92
- data/lib/js/expr/primary.rb +0 -166
- data/lib/js/rule/all.rb +0 -35
- data/lib/js/rule/checklist.rb +0 -41
- data/lib/js/rule/file_checker.rb +0 -42
- data/lib/js/rule/helper.rb +0 -96
- data/lib/js/rule/no_global.rb +0 -87
- data/lib/js/stat/if.rb +0 -25
- data/lib/js/stat/iter.rb +0 -85
- data/lib/js/stat/stat.rb +0 -117
- data/lib/js/stat/switch.rb +0 -65
- data/lib/js/stat/try.rb +0 -28
- data/lib/js/stat/var.rb +0 -40
- data/lib/js/struct.rb +0 -248
- data/lib/log_entry.rb +0 -49
- data/lib/node.rb +0 -28
- data/lib/parse_error.rb +0 -13
- data/lib/parser_visitable.rb +0 -138
- data/lib/printer/base_printer.rb +0 -24
- data/lib/printer/console_printer.rb +0 -66
- data/lib/printer/nocolor_printer.rb +0 -27
- data/lib/printer/vim_printer.rb +0 -19
- data/lib/rule.rb +0 -241
- data/lib/rule_helper.rb +0 -14
- data/lib/runner.rb +0 -225
- data/rules.d/css.rule +0 -127
- data/rules.d/html.dtd.rule +0 -22
- data/rules.d/html.prop.rule +0 -51
- data/rules.d/html.tag.rule +0 -136
- data/rules.d/js.file.rule +0 -13
- data/rules.d/js.jquery.rule +0 -56
- data/rules.d/js.mergefile.rule +0 -71
- data/rules.d/js.rule +0 -84
@@ -1,29 +1,31 @@
|
|
1
|
-
require_relative '../base_parser'
|
2
1
|
require_relative 'struct'
|
3
2
|
|
4
|
-
module
|
3
|
+
module Fdlint; module Parser
|
4
|
+
|
5
5
|
module CSS
|
6
6
|
|
7
|
-
class
|
8
|
-
|
9
|
-
|
10
|
-
QUOT_EXPR = "'[^']*'"
|
11
|
-
DQUOT_EXPR = '"[^"]*"'
|
7
|
+
class CssParser < ::Fdlint::Parser::BaseParser
|
8
|
+
|
9
|
+
include ::Fdlint::Parser::ParserVisitable
|
12
10
|
|
13
|
-
|
14
|
-
|
11
|
+
TERM = %q([^;{}'"])
|
12
|
+
TERM2 = %q([^;{}'",])
|
13
|
+
QUOT_EXPR = "'[^']*'"
|
14
|
+
DQUOT_EXPR = '"[^"]*"'
|
15
|
+
R_IDENT = /-?[_a-z][_a-z0-9-]*/
|
16
|
+
R_ANY = %r"((?:#{TERM})|(?:#{QUOT_EXPR})|(?:#{DQUOT_EXPR}))+"
|
15
17
|
R_SELECTOR = %r"((?:#{TERM2})|(?:#{QUOT_EXPR})|(?:#{DQUOT_EXPR}))+"
|
16
18
|
R_PROPERTY = /[*_+\\]?-?[_a-z\\][\\_a-z0-9-]*/
|
17
19
|
|
18
20
|
attr_reader :comments
|
19
21
|
|
20
|
-
def initialize(css
|
22
|
+
def initialize(css)
|
21
23
|
super
|
22
24
|
@comments = []
|
23
25
|
end
|
24
26
|
|
25
27
|
def parse_stylesheet(inner = false)
|
26
|
-
|
28
|
+
debug { 'parse stylesheet' }
|
27
29
|
|
28
30
|
do_parse_comment
|
29
31
|
|
@@ -39,7 +41,7 @@ module XRay
|
|
39
41
|
|
40
42
|
# ruleset or directive
|
41
43
|
def parse_statement
|
42
|
-
|
44
|
+
debug { 'parse statement' }
|
43
45
|
|
44
46
|
if check /@/
|
45
47
|
parse_directive
|
@@ -49,7 +51,7 @@ module XRay
|
|
49
51
|
end
|
50
52
|
|
51
53
|
def parse_directive
|
52
|
-
|
54
|
+
debug { 'parse directive' }
|
53
55
|
|
54
56
|
skip /@/
|
55
57
|
keyword = scan R_IDENT
|
@@ -69,14 +71,14 @@ module XRay
|
|
69
71
|
skip /;/
|
70
72
|
end
|
71
73
|
|
72
|
-
|
73
|
-
|
74
|
-
|
74
|
+
debug { " keyword: #{keyword} #{keyword.position}" }
|
75
|
+
debug { " expression: #{expr} #{expr.position}" } if expr
|
76
|
+
debug { " block:\n#{block}\n#{block.position}" } if block
|
75
77
|
Directive.new keyword, expr, block
|
76
78
|
end
|
77
79
|
|
78
80
|
def parse_ruleset
|
79
|
-
|
81
|
+
debug { 'parse ruleset' }
|
80
82
|
|
81
83
|
selector = check(/\{/) ? nil : parse_selector
|
82
84
|
skip /\{/
|
@@ -87,15 +89,15 @@ module XRay
|
|
87
89
|
end
|
88
90
|
|
89
91
|
def parse_selector
|
90
|
-
|
92
|
+
debug { ' parse selector' }
|
91
93
|
simple_selectors = batch(:parse_simple_selector, /\{/, /,/)
|
92
94
|
Selector.new simple_selectors
|
93
95
|
end
|
94
96
|
|
95
97
|
def parse_simple_selector
|
96
|
-
log ' parse simple selector'
|
97
98
|
selector = scan R_SELECTOR
|
98
|
-
|
99
|
+
debug { ' parse simple selector' }
|
100
|
+
debug { " #{selector} #{selector.position}" }
|
99
101
|
selector
|
100
102
|
end
|
101
103
|
|
@@ -113,7 +115,7 @@ module XRay
|
|
113
115
|
end
|
114
116
|
|
115
117
|
def parse_declaration
|
116
|
-
|
118
|
+
debug { ' parse declaration' }
|
117
119
|
|
118
120
|
property = parse_property
|
119
121
|
skip /:/
|
@@ -123,24 +125,24 @@ module XRay
|
|
123
125
|
end
|
124
126
|
|
125
127
|
def parse_property
|
126
|
-
|
128
|
+
debug { ' parse property' }
|
127
129
|
property = scan R_PROPERTY
|
128
|
-
|
130
|
+
debug { " #{property} #{property.position}" }
|
129
131
|
property
|
130
132
|
end
|
131
133
|
|
132
134
|
def parse_value
|
133
|
-
|
135
|
+
debug { ' parse value' }
|
134
136
|
|
135
137
|
value = scan R_ANY
|
136
|
-
|
138
|
+
debug { " #{value} #{value.position}" }
|
137
139
|
value
|
138
140
|
end
|
139
141
|
|
140
142
|
def parse_comment
|
141
|
-
|
143
|
+
debug { 'pare comment' }
|
142
144
|
comment = raw_scan /\/\*[^*]*\*+([^\/*][^*]*\*+)*\//
|
143
|
-
|
145
|
+
debug { " #{comment}" }
|
144
146
|
comment
|
145
147
|
end
|
146
148
|
|
@@ -183,4 +185,5 @@ module XRay
|
|
183
185
|
end
|
184
186
|
|
185
187
|
end
|
186
|
-
|
188
|
+
|
189
|
+
end; end
|
@@ -1,8 +1,7 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
module XRay
|
1
|
+
module Fdlint; module Parser
|
4
2
|
module CSS
|
5
|
-
|
3
|
+
|
4
|
+
Node = ::Fdlint::Parser::Node
|
6
5
|
|
7
6
|
class StyleSheet < Node
|
8
7
|
attr_reader :statements
|
@@ -108,4 +107,5 @@ module XRay
|
|
108
107
|
end
|
109
108
|
|
110
109
|
end
|
111
|
-
|
110
|
+
|
111
|
+
end; end
|
@@ -1,11 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
require 'fdlint/parser/base_parser'
|
2
|
+
require 'fdlint/parser/css/css_parser'
|
3
|
+
require 'fdlint/parser/js/js_parser'
|
4
|
+
require 'fdlint/parser/html/struct'
|
5
5
|
|
6
|
-
module
|
6
|
+
module Fdlint; module Parser; module HTML
|
7
7
|
|
8
|
-
class
|
8
|
+
class HtmlParser < ::Fdlint::Parser::BaseParser
|
9
|
+
|
10
|
+
include ::Fdlint::Parser::ParserVisitable
|
9
11
|
|
10
12
|
def self.parse(src, &block)
|
11
13
|
parser = self.new(src)
|
@@ -36,12 +38,13 @@ module XRay; module HTML
|
|
36
38
|
when 0 then nil
|
37
39
|
when 1 then nodes[0]
|
38
40
|
else
|
39
|
-
::
|
41
|
+
::Fdlint::Parser::HTML::Document.new( nodes )
|
40
42
|
end
|
41
43
|
end
|
42
44
|
|
43
45
|
def parse_element
|
44
46
|
if @scanner.check(DTD) and !@dtd_checked
|
47
|
+
# only one DTD for one document
|
45
48
|
@dtd_checked = true
|
46
49
|
parse_dtd
|
47
50
|
elsif @scanner.check(COMMENT)
|
@@ -49,7 +52,7 @@ module XRay; module HTML
|
|
49
52
|
elsif @scanner.check(TAG_START)
|
50
53
|
parse_tag
|
51
54
|
elsif !text_end?
|
52
|
-
|
55
|
+
parse_text_tag
|
53
56
|
else
|
54
57
|
parse_error('Invalid HTML struct')
|
55
58
|
end
|
@@ -65,8 +68,9 @@ module XRay; module HTML
|
|
65
68
|
CommentElement.new(@scanner[1])
|
66
69
|
end
|
67
70
|
|
68
|
-
def
|
71
|
+
def parse_text_tag
|
69
72
|
text = ''
|
73
|
+
pos = scanner_pos
|
70
74
|
until text_end? do
|
71
75
|
text << '<' if @scanner.skip(/</)
|
72
76
|
text << "#{@scanner.scan(TEXT)}"
|
@@ -74,7 +78,9 @@ module XRay; module HTML
|
|
74
78
|
# TODO: make this detection a rule
|
75
79
|
parse_warn "'#{$~}' not escaped" if text =~ /<|>/
|
76
80
|
end
|
77
|
-
TextElement.new text
|
81
|
+
TextElement.new( text ).tap do |text|
|
82
|
+
text.position = pos
|
83
|
+
end
|
78
84
|
end
|
79
85
|
|
80
86
|
def parse_tag
|
@@ -137,7 +143,7 @@ module XRay; module HTML
|
|
137
143
|
begin
|
138
144
|
end_tag = %r(<#{tag.text.sub(/^(?!=\/)/, '\/')}>)i
|
139
145
|
rescue
|
140
|
-
raise ::
|
146
|
+
raise ::Fdlint::Parser::ParseError.new("invalid tag name: #{tag.text}", scanner_pos)
|
141
147
|
end
|
142
148
|
|
143
149
|
if auto_close?(tag.text) and !@scanner.check(end_tag)
|
@@ -159,7 +165,7 @@ module XRay; module HTML
|
|
159
165
|
|
160
166
|
scopes.pop
|
161
167
|
|
162
|
-
el =
|
168
|
+
el = Tag.new(tag, prop, children, close_type, ending)
|
163
169
|
el.scopes = scopes.dup
|
164
170
|
el
|
165
171
|
end
|
@@ -183,7 +189,7 @@ module XRay; module HTML
|
|
183
189
|
end
|
184
190
|
|
185
191
|
def auto_close?(tag)
|
186
|
-
|
192
|
+
Fdlint::Parser::HTML::AUTO_CLOSE_TAGS.include?(tag.to_s.downcase)
|
187
193
|
end
|
188
194
|
|
189
195
|
def text_end?
|
@@ -200,13 +206,13 @@ module XRay; module HTML
|
|
200
206
|
end
|
201
207
|
|
202
208
|
|
203
|
-
end; end
|
209
|
+
end; end; end
|
204
210
|
|
205
211
|
if __FILE__ == $0
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
begin;
|
211
|
-
|
212
|
+
Fdlint::Parser::HTML::HtmlParser.parse(%q(<div class="info" checked>information</div>)) { |e| puts e.outer_html }
|
213
|
+
Fdlint::Parser::HTML::HtmlParser.parse(%q(<img width="100" height='150' id=img > <center>text</center>)) { |e| puts e.first.outer_html }
|
214
|
+
Fdlint::Parser::HTML::HtmlParser.parse(%q(<center><div><div><center>text</center></div></div></center>)) { |e| puts e.outer_html }
|
215
|
+
Fdlint::Parser::HTML::HtmlParser.parse(%q(<center ns:name="value"><div><div><center>text</center></div></div></center>)) { |e| puts e.outer_html }
|
216
|
+
begin; Fdlint::Parser::HTML::HtmlParser.parse(%q(<center><div></center></div>)) { |e| puts e.outer_html }; rescue; end
|
217
|
+
Fdlint::Parser::HTML::HtmlParser.parse('<br/>') { |e| puts e.outer_html }
|
212
218
|
end
|
File without changes
|
File without changes
|
@@ -1,9 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
module XRay
|
1
|
+
module Fdlint; module Parser
|
4
2
|
module HTML
|
5
3
|
|
6
|
-
Node =
|
4
|
+
Node = ::Fdlint::Parser::Node
|
5
|
+
|
7
6
|
AUTO_CLOSE_TAGS = %w(area base basefont br col frame hr img input link meta param)
|
8
7
|
INLINE_ELEMENTS = %w(a br label abbr legend address link
|
9
8
|
area mark audio meter bm nav cite optgroup
|
@@ -11,21 +10,53 @@ module XRay
|
|
11
10
|
command source datalist span em strong
|
12
11
|
font sub i summary iframe sup img tbody
|
13
12
|
input td ins time kbd var)
|
13
|
+
module Matchable
|
14
|
+
def =~ patten
|
15
|
+
if name
|
16
|
+
case patten
|
17
|
+
when String
|
18
|
+
name =~ Regexp.new("^#{patten}$", Regexp::IGNORECASE)
|
19
|
+
when Regexp
|
20
|
+
name =~ patten
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
alias_method :name_equal?, :=~
|
26
|
+
|
27
|
+
end
|
28
|
+
|
14
29
|
|
15
30
|
class Element < Node
|
16
31
|
|
32
|
+
include Matchable
|
33
|
+
|
17
34
|
attr_reader :tag, :props, :children
|
18
|
-
attr_accessor :parent, :close_type, :ending, :scopes
|
35
|
+
attr_accessor :position, :parent, :close_type, :ending, :scopes
|
19
36
|
|
20
37
|
def initialize(tag, props=[], children=[], close_type=:after, ending=nil)
|
21
|
-
|
22
|
-
@
|
23
|
-
@
|
38
|
+
|
39
|
+
@tag, @close_type, @ending = tag, close_type, ending
|
40
|
+
@props = to_props( props )
|
24
41
|
@scopes = []
|
42
|
+
|
43
|
+
if tag.respond_to?( :position ) and tag.position
|
44
|
+
@position = @tag.position.dup
|
45
|
+
end
|
46
|
+
|
47
|
+
@children = (Array.[](children).flatten || []).tap do |children|
|
48
|
+
children.each do |child|
|
49
|
+
child.parent = self
|
50
|
+
end
|
51
|
+
end
|
25
52
|
end
|
26
53
|
|
27
54
|
def has_scope?
|
28
|
-
!
|
55
|
+
!top_level?
|
56
|
+
end
|
57
|
+
|
58
|
+
def top_level?
|
59
|
+
parent.nil? and @scopes.empty?
|
29
60
|
end
|
30
61
|
|
31
62
|
def in_scope?(scp)
|
@@ -37,19 +68,13 @@ module XRay
|
|
37
68
|
end
|
38
69
|
|
39
70
|
def text
|
40
|
-
children.inject("")
|
41
|
-
s + child.text
|
42
|
-
end
|
71
|
+
children.inject("") { |s,child| s + child.text }
|
43
72
|
end
|
44
73
|
|
45
74
|
def tag_name
|
46
75
|
@tag.is_a?(Node) ? @tag.text : @tag.to_s
|
47
76
|
end
|
48
77
|
|
49
|
-
def tag_name_equal?(name)
|
50
|
-
tag_name.downcase == name.downcase
|
51
|
-
end
|
52
|
-
|
53
78
|
def inner_html
|
54
79
|
@children.inject('') { |s,c| s + c.outer_html }
|
55
80
|
end
|
@@ -98,6 +123,10 @@ module XRay
|
|
98
123
|
end
|
99
124
|
end
|
100
125
|
|
126
|
+
def [] name
|
127
|
+
prop_value(name)
|
128
|
+
end
|
129
|
+
|
101
130
|
def to_s
|
102
131
|
"[HTML: #{outer_html}]"
|
103
132
|
end
|
@@ -111,7 +140,7 @@ module XRay
|
|
111
140
|
end
|
112
141
|
|
113
142
|
def closed?
|
114
|
-
@close_type != :none
|
143
|
+
auto_close? && !self_closed? || @close_type != :none
|
115
144
|
end
|
116
145
|
|
117
146
|
def self_closed?
|
@@ -126,30 +155,41 @@ module XRay
|
|
126
155
|
false
|
127
156
|
end
|
128
157
|
|
129
|
-
|
130
|
-
|
131
|
-
@outer_html = text
|
158
|
+
def stylesheet_link?
|
159
|
+
self =~ 'link' && self['rel'] =~ /stylesheet/i
|
132
160
|
end
|
133
161
|
|
162
|
+
protected
|
163
|
+
|
164
|
+
def parse(text)
|
165
|
+
@outer_html = text
|
166
|
+
end
|
167
|
+
|
134
168
|
private
|
135
169
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
170
|
+
def to_props(src)
|
171
|
+
case src
|
172
|
+
when Array
|
173
|
+
src
|
174
|
+
when Hash
|
175
|
+
src.map do |n, v|
|
176
|
+
Property.new(n, v)
|
177
|
+
end
|
178
|
+
else
|
179
|
+
[]
|
143
180
|
end
|
144
|
-
|
145
|
-
[]
|
146
|
-
end
|
147
|
-
end
|
181
|
+
end
|
148
182
|
|
149
183
|
end
|
150
184
|
|
185
|
+
class Tag < Element
|
186
|
+
include Matchable
|
187
|
+
|
188
|
+
alias_method :name, :tag_name
|
189
|
+
end
|
190
|
+
|
191
|
+
class Document < Tag
|
151
192
|
|
152
|
-
class Document < Element
|
153
193
|
def initialize( children=[] )
|
154
194
|
super(nil, {}, children || [])
|
155
195
|
@position = Position.new(0,0,0)
|
@@ -169,9 +209,15 @@ module XRay
|
|
169
209
|
children.empty?
|
170
210
|
end
|
171
211
|
|
212
|
+
def has_dtd?
|
213
|
+
!empty? && children.first.is_a?( DTDElement )
|
214
|
+
end
|
215
|
+
|
216
|
+
alias_method :have_dtd?, :has_dtd?
|
217
|
+
|
172
218
|
end
|
173
219
|
|
174
|
-
class TextElement <
|
220
|
+
class TextElement < Tag
|
175
221
|
|
176
222
|
def initialize(text="")
|
177
223
|
super(nil)
|
@@ -263,6 +309,8 @@ module XRay
|
|
263
309
|
|
264
310
|
class Property < Node
|
265
311
|
|
312
|
+
include Matchable
|
313
|
+
|
266
314
|
attr_reader :name, :sep
|
267
315
|
attr_accessor :value
|
268
316
|
|
@@ -272,10 +320,6 @@ module XRay
|
|
272
320
|
|
273
321
|
def position; name.position; end
|
274
322
|
|
275
|
-
def name_equal?(text)
|
276
|
-
@name.to_s.downcase == text.to_s.downcase
|
277
|
-
end
|
278
|
-
|
279
323
|
def to_s
|
280
324
|
if value.nil?
|
281
325
|
name.to_s
|
@@ -288,4 +332,4 @@ module XRay
|
|
288
332
|
|
289
333
|
|
290
334
|
end
|
291
|
-
end
|
335
|
+
end; end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'fdlint/parser/js/expr/primary'
|
2
|
+
require 'fdlint/parser/js/expr/left_hand'
|
3
|
+
require 'fdlint/parser/js/expr/operate'
|
4
|
+
|
5
|
+
|
6
|
+
module Fdlint
|
7
|
+
module Parser
|
8
|
+
module JS
|
9
|
+
module Expr
|
10
|
+
|
11
|
+
module Expr
|
12
|
+
|
13
|
+
include ::Fdlint::Parser::JS::Expr::Primary
|
14
|
+
include ::Fdlint::Parser::JS::Expr::LeftHand
|
15
|
+
include ::Fdlint::Parser::JS::Expr::Operate
|
16
|
+
|
17
|
+
def parse_expression
|
18
|
+
log 'parse expression'
|
19
|
+
parse_expr_with_operate :parse_expr_assignment, /,/
|
20
|
+
end
|
21
|
+
|
22
|
+
def parse_expr_assignment
|
23
|
+
log 'parse expr assignment'
|
24
|
+
|
25
|
+
expr = parse_expr_condition
|
26
|
+
|
27
|
+
r = /=|\*=|\/=|%=|\+=|-=|<<=|>>=|>>>=|&=|\^=|\|=/
|
28
|
+
if expr.left_hand? && check(r)
|
29
|
+
op = scan r
|
30
|
+
expr = create_element Expression, op.text, expr, parse_expr_assignment
|
31
|
+
end
|
32
|
+
expr
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse_expr_condition
|
36
|
+
log 'parse expr condition'
|
37
|
+
expr = parse_expr_logical_or
|
38
|
+
if check /\?/
|
39
|
+
skip /\?/
|
40
|
+
left = parse_expr_assignment
|
41
|
+
skip /:/
|
42
|
+
right = parse_expr_assignment
|
43
|
+
|
44
|
+
expr = create_element ConditionExpression, expr, left, right
|
45
|
+
end
|
46
|
+
expr
|
47
|
+
end
|
48
|
+
|
49
|
+
def parse_expr_with_operate(left, pattern = nil, &block)
|
50
|
+
block = block || lambda {
|
51
|
+
if check pattern
|
52
|
+
skip_empty
|
53
|
+
before_pos = scanner_pos
|
54
|
+
op = scan pattern
|
55
|
+
[op.text, self.send(left), before_pos]
|
56
|
+
end
|
57
|
+
}
|
58
|
+
|
59
|
+
expr = self.send left
|
60
|
+
while (ret = block.call)
|
61
|
+
expr = create_element Expression, ret[0], expr, ret[1], ret[2]
|
62
|
+
end
|
63
|
+
expr
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Fdlint
|
2
|
+
module Parser
|
3
|
+
module JS
|
4
|
+
module Expr
|
5
|
+
|
6
|
+
module LeftHand
|
7
|
+
|
8
|
+
def parse_expr_lefthand
|
9
|
+
log 'parse expr lefthand'
|
10
|
+
expr = check(/new\b/) ? parse_expr_new : parse_expr_member
|
11
|
+
expr.left_hand = true
|
12
|
+
expr
|
13
|
+
end
|
14
|
+
|
15
|
+
def parse_expr_new
|
16
|
+
log 'parse expr new'
|
17
|
+
|
18
|
+
pos = skip /new/
|
19
|
+
expr = check(/new\b/) ? parse_expr_new : parse_expr_member
|
20
|
+
args = check(/\(/) ? parse_arguments_list : nil
|
21
|
+
|
22
|
+
create_element Expression, 'new', expr, args, pos
|
23
|
+
end
|
24
|
+
|
25
|
+
def parse_expr_member
|
26
|
+
log 'parse expr member'
|
27
|
+
parse_expr_with_operate(:parse_expr_member_left) do
|
28
|
+
if check /[.]/
|
29
|
+
skip /[.]/
|
30
|
+
['.', parse_expr_identifier]
|
31
|
+
elsif check /[\[]/
|
32
|
+
skip /\[/
|
33
|
+
expr = parse_expression
|
34
|
+
skip /\]/
|
35
|
+
['[', expr]
|
36
|
+
elsif check /\(/
|
37
|
+
['(', parse_arguments_list]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
protected
|
43
|
+
|
44
|
+
def parse_expr_member_left
|
45
|
+
if check /function\b/
|
46
|
+
create_element FunctionExpression, parse_function_declaration(true)
|
47
|
+
else
|
48
|
+
parse_expr_primary
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
def parse_arguments_list
|
54
|
+
log 'parse arguments list'
|
55
|
+
skip /\(/
|
56
|
+
params = batch :parse_expr_assignment, /\)/, /,/
|
57
|
+
skip /\)/
|
58
|
+
Elements.new params
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|