Module: Opal::Nodes::Helpers
- Included in:
- Base
- Defined in:
- opal/lib/opal/nodes/helpers.rb
Constant Summary
- ES51_RESERVED_WORD =
Reserved javascript keywords - we cannot create variables with the same name (ref: http://stackoverflow.com/a/9337272/601782)
/#{REGEXP_START}(?:do|if|in|for|let|new|try|var|case|else|enum|eval|false|null|this|true|void|with|break|catch|class|const|super|throw|while|yield|delete|export|import|public|return|static|switch|typeof|default|extends|finally|package|private|continue|debugger|function|arguments|interface|protected|implements|instanceof)#{REGEXP_END}/
- ES3_RESERVED_WORD_EXCLUSIVE =
ES3 reserved words that aren’t ES5.1 reserved words
/#{REGEXP_START}(?:int|byte|char|goto|long|final|float|short|double|native|throws|boolean|abstract|volatile|transient|synchronized)#{REGEXP_END}/
- PROTO_SPECIAL_PROPS =
Prototype special properties.
/#{REGEXP_START}(?:constructor|displayName|__proto__|__parent__|__noSuchMethod__|__count__)#{REGEXP_END}/
- PROTO_SPECIAL_METHODS =
Prototype special methods.
/#{REGEXP_START}(?:hasOwnProperty|valueOf)#{REGEXP_END}/
- IMMUTABLE_PROPS =
Immutable properties of the global object
/#{REGEXP_START}(?:NaN|Infinity|undefined)#{REGEXP_END}/
- BASIC_IDENTIFIER_RULES =
Doesn't take in account utf8
/#{REGEXP_START}[$_a-z][$_a-z\d]*#{REGEXP_END}/i
Instance Method Summary collapse
- #current_indent ⇒ Object
- #empty_line ⇒ Object
- #indent(&block) ⇒ Object
- #ivar(name) ⇒ Object
- #js_falsy(sexp) ⇒ Object
- #js_truthy(sexp) ⇒ Object
- #js_truthy_optimize(sexp) ⇒ Object
- #line(*strs) ⇒ Object
-
#lvar_to_js(var) ⇒ Object
Converts a ruby lvar/arg name to a js identifier.
-
#mid_to_jsid(mid) ⇒ Object
Converts a ruby method name into its javascript equivalent for a method/function call.
- #property(name) ⇒ Object
- #valid_ivar_name?(name) ⇒ Boolean
- #valid_name?(name) ⇒ Boolean
- #variable(name) ⇒ Object
Instance Method Details
#current_indent ⇒ Object
76 77 78 |
# File 'opal/lib/opal/nodes/helpers.rb', line 76 def current_indent compiler.parser_indent end |
#empty_line ⇒ Object
85 86 87 |
# File 'opal/lib/opal/nodes/helpers.rb', line 85 def empty_line push "\n" end |
#indent(&block) ⇒ Object
72 73 74 |
# File 'opal/lib/opal/nodes/helpers.rb', line 72 def indent(&block) compiler.indent(&block) end |
#ivar(name) ⇒ Object
47 48 49 |
# File 'opal/lib/opal/nodes/helpers.rb', line 47 def ivar(name) valid_ivar_name?(name.to_s) ? name : "#{name}$" end |
#js_falsy(sexp) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'opal/lib/opal/nodes/helpers.rb', line 99 def js_falsy(sexp) if sexp.type == :call mid = sexp[2] if mid == :block_given? scope.uses_block! return "#{scope.block_name} === nil" end end with_temp do |tmp| [fragment("((#{tmp} = "), expr(sexp), fragment(") === nil || (#{tmp}.$$is_boolean && #{tmp} == false))")] end end |
#js_truthy(sexp) ⇒ Object
89 90 91 92 93 94 95 96 97 |
# File 'opal/lib/opal/nodes/helpers.rb', line 89 def js_truthy(sexp) if optimize = js_truthy_optimize(sexp) return optimize end with_temp do |tmp| [fragment("((#{tmp} = "), expr(sexp), fragment(") !== nil && (!#{tmp}.$$is_boolean || #{tmp} == true))")] end end |
#js_truthy_optimize(sexp) ⇒ Object
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
# File 'opal/lib/opal/nodes/helpers.rb', line 113 def js_truthy_optimize(sexp) if sexp.type == :call mid = sexp[2] receiver_handler_class = (receiver = sexp[1]) && compiler.handlers[receiver.type] # Only operator calls on the truthy_optimize? node classes should be optimized. # Monkey patch method calls might return 'self'/aka a bridged instance and need # the nil check - see discussion at https://github.com/opal/opal/pull/1097 allow_optimization_on_type = Compiler::COMPARE.include?(mid.to_s) && receiver_handler_class && receiver_handler_class.truthy_optimize? if allow_optimization_on_type || mid == :block_given? || mid == :==" expr(sexp) end elsif [:lvar, :self].include? sexp.type [expr(sexp.dup), fragment(" !== false && "), expr(sexp.dup), fragment(" !== nil")] end end |
#line(*strs) ⇒ Object
80 81 82 83 |
# File 'opal/lib/opal/nodes/helpers.rb', line 80 def line(*strs) push "\n#{current_indent}" push(*strs) end |
#lvar_to_js(var) ⇒ Object
Converts a ruby lvar/arg name to a js identifier. Not all ruby names are valid in javascript. A $ suffix is added to non-valid names. varibales
54 55 56 57 |
# File 'opal/lib/opal/nodes/helpers.rb', line 54 def lvar_to_js(var) var = "#{var}$" unless valid_name? var.to_s var.to_sym end |
#mid_to_jsid(mid) ⇒ Object
Converts a ruby method name into its javascript equivalent for a method/function call. All ruby method names get prefixed with a '$', and if the name is a valid javascript identifier, it will have a '.' prefix (for dot-calling), otherwise it will be wrapped in brackets to use reference notation calling.
64 65 66 67 68 69 70 |
# File 'opal/lib/opal/nodes/helpers.rb', line 64 def mid_to_jsid(mid) if /\=|\+|\-|\*|\/|\!|\?|<|\>|\&|\||\^|\%|\~|\[/ =~ mid.to_s "['$#{mid}']" else '.$' + mid end end |
#property(name) ⇒ Object
27 28 29 |
# File 'opal/lib/opal/nodes/helpers.rb', line 27 def property(name) valid_name?(name) ? ".#{name}" : "[#{name.inspect}]" end |
#valid_ivar_name?(name) ⇒ Boolean
43 44 45 |
# File 'opal/lib/opal/nodes/helpers.rb', line 43 def valid_ivar_name?(name) not (PROTO_SPECIAL_PROPS =~ name or PROTO_SPECIAL_METHODS =~ name) end |
#valid_name?(name) ⇒ Boolean
31 32 33 34 35 36 37 |
# File 'opal/lib/opal/nodes/helpers.rb', line 31 def valid_name?(name) BASIC_IDENTIFIER_RULES =~ name and not( ES51_RESERVED_WORD =~ name or ES3_RESERVED_WORD_EXCLUSIVE =~ name or IMMUTABLE_PROPS =~ name ) end |
#variable(name) ⇒ Object
39 40 41 |
# File 'opal/lib/opal/nodes/helpers.rb', line 39 def variable(name) valid_name?(name.to_s) ? name : "#{name}$" end |