diff --git a/test/jstests/getfield.py b/test/jstests/getfield.py index a41f74c49..39dc1d5b5 100644 --- a/test/jstests/getfield.py +++ b/test/jstests/getfield.py @@ -1,7 +1,5 @@ from youtube_dl.jsinterp.jsgrammar import Token -skip = {'i': 'Interpreting get field not yet implemented'} - tests = [ { 'code': 'return a.var;', diff --git a/youtube_dl/jsinterp/jsinterp.py b/youtube_dl/jsinterp/jsinterp.py index f35acb530..73725294b 100644 --- a/youtube_dl/jsinterp/jsinterp.py +++ b/youtube_dl/jsinterp/jsinterp.py @@ -53,7 +53,7 @@ class JSInterpreter(object): if variables is not None: for k, v in dict(variables).items(): # XXX validate identifiers - self.global_vars[k] = Reference(v, (self.global_vars, k)) + self.global_vars[k] = self.create_reference(v, (self.global_vars, k)) self._context = Context() self._context_stack = [] @@ -65,6 +65,20 @@ class JSInterpreter(object): yield self._statement(ts, stack_size) raise StopIteration + def create_reference(self, value, parent_key): + if isinstance(value, dict): + o = {} + for k, v in value.items(): + o[k] = self.create_reference(v, (o, k)) + elif isinstance(value, list): + o = [] + for k, v in enumerate(value): + o[k] = self.create_reference(v, (o, k)) + else: + o = value + + return Reference(o, parent_key) + def _statement(self, token_stream, stack_top): if stack_top < 0: raise ExtractorError('Recursion limit reached') @@ -923,10 +937,9 @@ class JSInterpreter(object): while tail is not None: tail_name, tail_value, tail = tail if tail_name is Token.FIELD: - # TODO interpret field - raise ExtractorError('''Can't interpret expression called %s''' % tail_name) + target = target.getvalue()[tail_value] elif tail_name is Token.ELEM: - index = self.interpret_statement(tail_value).getvalue() + index = self.interpret_expression(tail_value).getvalue() target = target.getvalue()[index] elif tail_name is Token.CALL: # TODO interpret call @@ -945,9 +958,8 @@ class JSInterpreter(object): elif name is Token.ARRAY: array = [] for key, elem in enumerate(expr[1]): - value = self.interpret_expression(elem) - value._parent = array, key - array.append(value) + value = self.interpret_expression(elem).getvalue() + array.append(Reference(value, (array, key))) ref = Reference(array) else: