Class | CodeRay::Scanners::JavaScript |
In: |
lib/coderay/scanners/java_script.rb
|
Parent: | Scanner |
Scanner for JavaScript.
Aliases: ecmascript, ecma_script, javascript
# File lib/coderay/scanners/java_script.rb, line 201 201: def reset_instance 202: super 203: @xml_scanner.reset if defined? @xml_scanner 204: end
# File lib/coderay/scanners/java_script.rb, line 57 57: def scan_tokens encoder, options 58: 59: state = :initial 60: string_delimiter = nil 61: value_expected = true 62: key_expected = false 63: function_expected = false 64: 65: until eos? 66: 67: case state 68: 69: when :initial 70: 71: if match = scan(/ \s+ | \\\n /x) 72: value_expected = true if !value_expected && match.index(?\n) 73: encoder.text_token match, :space 74: 75: elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx) 76: value_expected = true 77: encoder.text_token match, :comment 78: 79: elsif check(/\.?\d/) 80: key_expected = value_expected = false 81: if match = scan(/0[xX][0-9A-Fa-f]+/) 82: encoder.text_token match, :hex 83: elsif match = scan(/(?>0[0-7]+)(?![89.eEfF])/) 84: encoder.text_token match, :octal 85: elsif match = scan(/\d+[fF]|\d*\.\d+(?:[eE][+-]?\d+)?[fF]?|\d+[eE][+-]?\d+[fF]?/) 86: encoder.text_token match, :float 87: elsif match = scan(/\d+/) 88: encoder.text_token match, :integer 89: end 90: 91: elsif value_expected && match = scan(/<([[:alpha:]]\w*) (?: [^\/>]*\/> | .*?<\/\1>)/xim) 92: # TODO: scan over nested tags 93: xml_scanner.tokenize match, :tokens => encoder 94: value_expected = false 95: next 96: 97: elsif match = scan(/ [-+*=<>?:;,!&^|(\[{~%]+ | \.(?!\d) /x) 98: value_expected = true 99: last_operator = match[-1] 100: key_expected = (last_operator == ?{) || (last_operator == ?,) 101: function_expected = false 102: encoder.text_token match, :operator 103: 104: elsif match = scan(/ [)\]}]+ /x) 105: function_expected = key_expected = value_expected = false 106: encoder.text_token match, :operator 107: 108: elsif match = scan(/ [$a-zA-Z_][A-Za-z_0-9$]* /x) 109: kind = IDENT_KIND[match] 110: value_expected = (kind == :keyword) && KEYWORDS_EXPECTING_VALUE[match] 111: # TODO: labels 112: if kind == :ident 113: if match.index(?$) # $ allowed inside an identifier 114: kind = :predefined 115: elsif function_expected 116: kind = :function 117: elsif check(/\s*[=:]\s*function\b/) 118: kind = :function 119: elsif key_expected && check(/\s*:/) 120: kind = :key 121: end 122: end 123: function_expected = (kind == :keyword) && (match == 'function') 124: key_expected = false 125: encoder.text_token match, kind 126: 127: elsif match = scan(/["']/) 128: if key_expected && check(KEY_CHECK_PATTERN[match]) 129: state = :key 130: else 131: state = :string 132: end 133: encoder.begin_group state 134: string_delimiter = match 135: encoder.text_token match, :delimiter 136: 137: elsif value_expected && (match = scan(/\//)) 138: encoder.begin_group :regexp 139: state = :regexp 140: string_delimiter = '/' 141: encoder.text_token match, :delimiter 142: 143: elsif match = scan(/ \/ /x) 144: value_expected = true 145: key_expected = false 146: encoder.text_token match, :operator 147: 148: else 149: encoder.text_token getch, :error 150: 151: end 152: 153: when :string, :regexp, :key 154: if match = scan(STRING_CONTENT_PATTERN[string_delimiter]) 155: encoder.text_token match, :content 156: elsif match = scan(/["'\/]/) 157: encoder.text_token match, :delimiter 158: if state == :regexp 159: modifiers = scan(/[gim]+/) 160: encoder.text_token modifiers, :modifier if modifiers && !modifiers.empty? 161: end 162: encoder.end_group state 163: string_delimiter = nil 164: key_expected = value_expected = false 165: state = :initial 166: elsif state != :regexp && (match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)) 167: if string_delimiter == "'" && !(match == "\\\\" || match == "\\'") 168: encoder.text_token match, :content 169: else 170: encoder.text_token match, :char 171: end 172: elsif state == :regexp && match = scan(/ \\ (?: #{ESCAPE} | #{REGEXP_ESCAPE} | #{UNICODE_ESCAPE} ) /mox) 173: encoder.text_token match, :char 174: elsif match = scan(/\\./m) 175: encoder.text_token match, :content 176: elsif match = scan(/ \\ | $ /x) 177: encoder.end_group state 178: encoder.text_token match, :error 179: key_expected = value_expected = false 180: state = :initial 181: else 182: raise_inspect "else case \" reached; %p not handled." % peek(1), encoder 183: end 184: 185: else 186: raise_inspect 'Unknown state', encoder 187: 188: end 189: 190: end 191: 192: if [:string, :regexp].include? state 193: encoder.end_group state 194: end 195: 196: encoder 197: end