Example #1
0
def js_parse(
    data,
    args=None,
    file="",
    flatten=True,
    print_stack=True,
    start_node=None,
    print_warnings=False,
    exit_on_err=True,
    log_productions=False,
    validate=False,
):
    back = glob.copy()

    def safe_get(data, i):
        if i < 0:
            return ""
        elif i >= len(data):
            return ""

        return data[i]

    if args != None:
        if not isinstance(args, tuple) and not isinstance(args, list):
            if caniter(args) and not isinstance(args, Node) and type(args) not in [str, bytes]:
                args = list(args)
            else:
                args = (args,)  # encapsulate single arguments in a tuple

        i = 0
        ai = 0
        while i < len(data) - 2:
            if data[i] == "$" and safe_get(data, i - 1) != "$":
                i1 = i
                t = data[i + 1]
                i += 2

                arg, i = fetch_int(data, i)
                if arg == None:
                    arg = ai
                    ai += 1
                else:
                    arg -= 1
                    ai = max(arg, ai)

                if arg >= len(args):
                    raise RuntimeError("Not enough args for format conversion in js_parse()")

                if t == "n":
                    buf = args[arg].gen_js(0)
                elif t == "s":
                    buf = str(args[arg])
                elif t in ["d", "i", "u"]:
                    buf = str(int(args[arg]))
                elif t in ["f", "lf"]:
                    buf = str(float(args[arg]))
                elif t == "x":
                    buf = hex(int(args[arg]))
                else:
                    buf = data[i1:i]

                data = data[:i1] + buf + data[i:]

                i = i1 + len(buf)

            i += 1

    glob.reset()
    glob.g_exit_on_err = exit_on_err
    glob.g_lexer = plexer
    glob.g_production_debug = False
    glob.g_file = file
    glob.g_print_stack = print_stack
    glob.g_print_warnings = print_warnings
    glob.g_log_productions = log_productions
    glob.g_validate_mode = validate

    plexer.lineno = plexer.lexer.lineno = 0
    plexer.input(data)

    ret = parser.parse(data, lexer=plexer)
    if glob.g_error:
        print("------------LLLLLLLLLLLLLLLLLLL yeek!!!")
        ret = None

    if glob.g_clear_slashr:
        print("\n")

    def fix_parents(node, lastnode=None):
        if node.parent in [0, None]:
            node.parent = lastnode

        for c in node.children:
            fix_parents(c, node)

    if ret != None:
        fix_parents(ret)
        if flatten:
            ret = flatten_statementlists(ret, None)
            if ret == None:
                traceback.print_stack()
                sys.stderr.write("error: internal parse error within js_parse\n")
                sys.exit(-1)

    if start_node != None and ret != None:

        def visit(n):
            if type(n) == start_node:
                return n

            for c in n.children:
                c2 = visit(c)
                if c2 != None:
                    return c2

        ret = visit(ret)

    if ret != None:
        combine_try_nodes(ret)

    glob.load(back)

    return ret
Example #2
0
def parse_intern(data, create_logger=False, expand_loops=True, expand_generators=True):
    glob.g_lines = data.split("\n")

    if glob.g_preprocess_code:
        data = preprocess_text(data, glob.g_file)

    if glob.g_print_tokens:
        plexer.input(data)
        tok = plexer.token()
        while tok != None:
            print(tok)
            tok = plexer.token()
        plexer.input(data)

    glob.g_lexer = plexer
    result = parser.parse(data, lexer=plexer)

    if result == None:
        if glob.g_error_pre != None:
            glob.g_error = True

        result = StatementList()

    if glob.g_error:
        print_err(glob.g_error_pre)

    typespace = JSTypeSpace()

    if result != None:
        if len(result) > 0 and type(result[0]) == StrLitNode and result[0].val == '"use strict"':
            glob.g_force_global_strict = True
        elif len(result) > 0 and type(result[0]) == StrLitNode and result[0].val == '"not_a_module"':
            glob.g_es6_modules = False

    if glob.g_force_global_strict:
        kill_bad_globals(result, typespace)

    # handle .? operator
    transform_exisential_operators(result, typespace)

    if glob.g_write_manifest and glob.g_outfile != "":
        buf = gen_manifest_file(result, typespace)
        file = open(glob.g_outfile + ".manifest", "w")
        file.write(buf)
        file.close()

    if glob.g_es6_modules:
        module_transform(result, typespace)

    if glob.g_require_js:
        expand_requirejs_classes(result, typespace)
    else:
        expand_harmony_classes(result, typespace)
    expand_typed_classes(result, typespace)

    if glob.g_clear_slashr:
        print("\n")

    if result != None and len(result) == 0:
        result = None
        return "", None
        # sys.stdout.write("Error: empty compilation\n");
        # raise JSError("Empty compilation");

    global f_id
    f_id = [0]
    flatten_statementlists(result, typespace)

    if expand_loops:
        expand_of_loops(result, typespace)

    # combine_try_nodes may have nested statementlists again, so better reflatten
    flatten_statementlists(result, typespace)

    if create_logger:
        traverse(result, FunctionNode, create_type_logger)

    if expand_generators:
        flatten_statementlists(result, typespace)
        process_generators(result, typespace)
        flatten_statementlists(result, typespace)

    if glob.g_add_opt_initializers:
        add_func_opt_code(result, typespace)

    debug_forloop_expansion = False
    if debug_forloop_expansion:
        reset = 0
        if reset or not os.path.exists("cur_d.txt"):
            f = open("cur_d.txt", "w")
            f.write("-1")
            f.close()

        f = open("cur_d.txt", "r")
        d = int(f.read())
        print("\n\nd: %d\n" % d)
        traverse_i(result, ForInNode, expand_mozilla_forloops, d, use_scope=True)
        f.close()

        f = open("cur_d.txt", "w")
        f.write(str(d + 1))
        f.close()

    if glob.g_combine_ifelse_nodes:
        combine_if_else_nodes(result)

    if glob.g_print_nodes:
        print("nodes: ", result)
        pass

    if glob.g_replace_instanceof and not glob.g_require_js:
        replace_instanceof(result, typespace)

    if glob.g_enable_static_vars:
        process_static_vars(result, typespace)

    if glob.g_do_docstrings:
        process_docstrings(result, typespace)

    if glob.g_gen_source_map:
        smap = SourceMap()

        def set_smap(node, smap):
            node.smap = smap
            for n in node:
                set_smap(n, smap)

        set_smap(result, smap)

        if not glob.g_minify:
            buf = result.gen_js(0)
            map = gen_source_map(data, buf, smap)
        else:
            buf, smap = js_minify(result)
            map = gen_source_map(data, buf, smap)

        if glob.g_add_srcmap_ref:
            spath = glob.g_outfile
            if os.path.sep in spath:
                spath = os.path.split(spath)[1]

            buf += "\n//# sourceMappingURL=/content/%s\n" % (spath + ".map")

        if glob.g_gen_smap_orig:
            f = open(glob.g_outfile + ".origsrc", "w")
            f.write(data)
            f.close()
    else:
        if not glob.g_minify:
            buf = result.gen_js(0)
        else:
            buf, smap = js_minify(result)

    if glob.g_outfile == "":
        print(buf)
        if 0:
            file = open("generator_test.html", "w")
            file.write(
                """
      <html><head><title>Generator Test</title></head>
      <script>
      function arr_iter(keys)
      {
        this.keys = keys;
        this.cur = 0;
        
        this.next = function() {
          if (this.cur >= this.keys.length) {
            throw StopIteration;
          }
          
          return this.keys[this.cur++];
        }
      }

      __use_Iterator = true;

      function __get_iter(obj)
      {
        if (obj.__proto__.hasOwnProperty("__iterator__") || obj.hasOwnProperty("__iterator__")) {
          return obj.__iterator__();
        } else {
          if (__use_Iterator) {
            return Iterator(obj);
          } else {
            keys = []
            for (var k in obj) {
              keys.push(k)
            }
            return new arr_iter(keys);
          }
        }
      }

      function __get_iter2(obj)
      {
        if (obj.__proto__.hasOwnProperty("__iterator__") || obj.hasOwnProperty("__iterator__")) {
          return obj.__iterator__();
        } else {
          keys = []
          for (var k in obj) {
            keys.push([k, obj[k]])
          }
          return new arr_iter(keys);
        }
      }

      try {
        _tst = Iterator({});
      } catch (Error) {
        __use_Iterator = false;
        Iterator = __get_iter2;
      }
      FrameContinue = {1:1};
      FrameBreak = {2:2};
      """
            )
            file.write(buf.replace("yield", "return"))
            file.write(
                """
  j = 0;
  for (var tst in new range2(2, 8)) {
    if (_do_frame_debug) console.log(tst);
    if (j > 10)
      break;
    j++;
  }
  </script>
  </html>
  """
            )
            file.close()
        pass

    return buf, result
Example #3
0
def parse_intern(data, create_logger=False, expand_loops=True, expand_generators=True):
  glob.g_lines = data.split("\n")
  
  if glob.g_preprocess_code:
    data = preprocess_text(data, glob.g_file)
    
  if glob.g_print_tokens:
    plexer.input(data)
    tok = plexer.token()
    while tok != None:
      print(tok)
      tok = plexer.token()
    plexer.input(data)
  
  glob.g_lexer = plexer
  result = parser.parse(data, lexer=plexer)
  
  if result == None:
    if glob.g_error_pre != None:
      glob.g_error = True
    
    result = StatementList()

  if glob.g_error:
    print_err(glob.g_error_pre)
    
  typespace = JSTypeSpace()
  
  if result != None:
    if len(result) > 0 and type(result[0]) == StrLitNode and result[0].val == '"use strict"':
      glob.g_force_global_strict = True
    elif len(result) > 0 and type(result[0]) == StrLitNode and result[0].val == '"not_a_module"':
      glob.g_es6_modules = False
      
  if glob.g_compile_statics_only:
    process_static_vars(result, typespace)
    return result.gen_js(0), result
    
  if glob.g_enable_let:
    process_let(result, typespace)
    
  if glob.g_force_global_strict:
    kill_bad_globals(result, typespace)
  
  #handle .? operator
  transform_exisential_operators(result, typespace)
  
  if glob.g_write_manifest and glob.g_outfile != "":
    buf = gen_manifest_file(result, typespace);
    file = open(glob.g_outfile+".manifest", "w")
    file.write(buf)
    file.close()
    
  if glob.g_es6_modules:
    module_transform(result, typespace)
  
  if glob.g_require_js:
    expand_requirejs_classes(result, typespace);
  else:
    expand_harmony_classes(result, typespace);
  expand_typed_classes(result, typespace)
  
  if glob.g_clear_slashr:
    print("\n")
  
  if result != None and len(result) == 0:
    result = None
    return "", None
    #sys.stdout.write("Error: empty compilation\n");
    #raise JSError("Empty compilation");
  
  global f_id  
  f_id = [0]
  flatten_statementlists(result, typespace)
  
  has_generators = [False]
  def has_generator(n):
    if type(n) == YieldNode:
      has_generators[0] = True
    
    for c in n:
      has_generator(c)
  
  has_generator(result)
  
  if expand_loops or has_generators[0]:
    expand_of_loops(result, typespace)
  
  #combine_try_nodes may have nested statementlists again, so better reflatten
  flatten_statementlists(result, typespace)
  
  if create_logger:
    traverse(result, FunctionNode, create_type_logger)
  
  process_arrow_function_this(result, typespace)
  
  if expand_generators:
    flatten_statementlists(result, typespace)
    process_generators(result, typespace);
    flatten_statementlists(result, typespace)
  
  if glob.g_add_opt_initializers:
    add_func_opt_code(result, typespace)
  
  if glob.g_combine_ifelse_nodes:
    combine_if_else_nodes(result)
  
  if glob.g_print_nodes:
    print("nodes: ", result)
    pass
    
  if glob.g_replace_instanceof and not glob.g_require_js:
    replace_instanceof(result, typespace)
  
  if glob.g_enable_static_vars:
    process_static_vars(result, typespace)
    
  if glob.g_do_docstrings:
    process_docstrings(result, typespace)
  
  if glob.g_gen_v7_bytecode:
    from js_opcode_emit2 import v7_emit_bytecode
    buf = v7_emit_bytecode(result, typespace)
  elif not glob.g_minify:
    buf = result.gen_js(0)
  else:
    buf, smap = js_minify(result)
    
  if glob.g_outfile == "":
    print(buf)
    
  return buf, result