ThirdParty/Jasy/jasy/js/parse/Parser.py

changeset 5843
76eee727ccd9
parent 3145
a9de05d4a22f
--- a/ThirdParty/Jasy/jasy/js/parse/Parser.py	Thu Aug 10 13:58:50 2017 +0200
+++ b/ThirdParty/Jasy/jasy/js/parse/Parser.py	Fri Aug 11 14:40:54 2017 +0200
@@ -1,11 +1,12 @@
 #
 # Jasy - Web Tooling Framework
 # Copyright 2010-2012 Zynga Inc.
+# Copyright 2013-2014 Sebastian Werner
 #
 
 #
 # License: MPL 1.1/GPL 2.0/LGPL 2.1
-# Authors: 
+# Authors:
 #   - Brendan Eich <brendan@mozilla.org> (Original JavaScript) (2004-2010)
 #   - Sebastian Werner <info@sebastian-werner.net> (Python Port) (2010-2012)
 #
@@ -21,28 +22,29 @@
 def parseExpression(source, fileId=None, line=1, builder=None):
     if builder == None:
         builder = jasy.js.parse.VanillaBuilder.VanillaBuilder()
-    
+
     # Convert source into expression statement to be friendly to the Tokenizer
     if not source.endswith(";"):
         source = source + ";"
-    
+
     tokenizer = jasy.js.tokenize.Tokenizer.Tokenizer(source, fileId, line)
     staticContext = StaticContext(False, builder)
-    
+
     return Expression(tokenizer, staticContext)
 
 
+
 def parse(source, fileId=None, line=1, builder=None):
     if builder == None:
         builder = jasy.js.parse.VanillaBuilder.VanillaBuilder()
-    
+
     tokenizer = jasy.js.tokenize.Tokenizer.Tokenizer(source, fileId, line)
     staticContext = StaticContext(False, builder)
     node = Script(tokenizer, staticContext)
-    
+
     # store fileId on top-level node
     node.fileId = tokenizer.fileId
-    
+
     # add missing comments e.g. empty file with only a comment etc.
     # if there is something non-attached by an inner node it is attached to
     # the top level node, which is not correct, but might be better than
@@ -51,7 +53,7 @@
         builder.COMMENTS_add(node[-1], None, tokenizer.getComments())
     else:
         builder.COMMENTS_add(node, None, tokenizer.getComments())
-    
+
     if not tokenizer.done():
         raise SyntaxError("Unexpected end of file", tokenizer)
 
@@ -61,39 +63,37 @@
 
 class SyntaxError(Exception):
     def __init__(self, message, tokenizer):
-        Exception.__init__(self, "Syntax error: %s\n%s:%s" % (
-            message, tokenizer.fileId, tokenizer.line))
+        Exception.__init__(self, "Syntax error: %s\n%s:%s" % (message, tokenizer.fileId, tokenizer.line))
 
 
 # Used as a status container during tree-building for every def body and the global body
 class StaticContext(object):
     # inFunction is used to check if a return stm appears in a valid context.
     def __init__(self, inFunction, builder):
-        # Whether this is inside a function, mostly True, only for top-level scope
-        # it's False
+        # Whether this is inside a function, mostly True, only for top-level scope it's False
         self.inFunction = inFunction
-        
+
         self.hasEmptyReturn = False
         self.hasReturnWithValue = False
         self.isGenerator = False
         self.blockId = 0
         self.builder = builder
         self.statementStack = []
-        
+
         # Sets to store variable uses
         # self.functions = set()
         # self.variables = set()
-        
+
         # Status
         # self.needsHoisting = False
         self.bracketLevel = 0
         self.curlyLevel = 0
         self.parenLevel = 0
         self.hookLevel = 0
-        
+
         # Configure strict ecmascript 3 mode
         self.ecma3OnlyMode = False
-        
+
         # Status flag during parsing
         self.inForLoopInit = False
 
@@ -101,16 +101,16 @@
 def Script(tokenizer, staticContext):
     """Parses the toplevel and def bodies."""
     node = Statements(tokenizer, staticContext)
-    
+
     # change type from "block" to "script" for script root
     node.type = "script"
-    
+
     # copy over data from compiler context
     # node.functions = staticContext.functions
     # node.variables = staticContext.variables
 
     return node
-    
+
 
 def nest(tokenizer, staticContext, node, func, end=None):
     """Statement stack and nested statement handler."""
@@ -118,7 +118,7 @@
     node = func(tokenizer, staticContext)
     staticContext.statementStack.pop()
     end and tokenizer.mustMatch(end)
-    
+
     return node
 
 
@@ -157,7 +157,7 @@
     tokenizer.mustMatch("left_curly")
     node = Statements(tokenizer, staticContext)
     tokenizer.mustMatch("right_curly")
-    
+
     return node
 
 
@@ -169,25 +169,24 @@
 
     # Cases for statements ending in a right curly return early, avoiding the
     # common semicolon insertion magic after this switch.
-    
+
     if tokenType == "function":
-        # "declared_form" extends functions of staticContext,
-        # "statement_form" doesn'tokenizer.
+        # "declared_form" extends functions of staticContext, "statement_form" doesn'tokenizer.
         if len(staticContext.statementStack) > 1:
             kind = "statement_form"
         else:
             kind = "declared_form"
-        
+
         return FunctionDefinition(tokenizer, staticContext, True, kind)
-        
-        
+
+
     elif tokenType == "left_curly":
         node = Statements(tokenizer, staticContext)
         tokenizer.mustMatch("right_curly")
-        
+
         return node
-        
-        
+
+
     elif tokenType == "if":
         node = builder.IF_build(tokenizer)
         builder.IF_setCondition(node, ParenExpression(tokenizer, staticContext))
@@ -202,10 +201,10 @@
 
         staticContext.statementStack.pop()
         builder.IF_finish(node)
-        
+
         return node
-        
-        
+
+
     elif tokenType == "switch":
         # This allows CASEs after a "default", which is in the standard.
         node = builder.SWITCH_build(tokenizer)
@@ -214,23 +213,23 @@
 
         tokenizer.mustMatch("left_curly")
         tokenType = tokenizer.get()
-        
+
         while tokenType != "right_curly":
             if tokenType == "default":
                 if node.defaultIndex >= 0:
                     raise SyntaxError("More than one switch default", tokenizer)
-                    
+
                 childNode = builder.DEFAULT_build(tokenizer)
                 builder.SWITCH_setDefaultIndex(node, len(node)-1)
                 tokenizer.mustMatch("colon")
                 builder.DEFAULT_initializeStatements(childNode, tokenizer)
-                
+
                 while True:
                     tokenType=tokenizer.peek(True)
                     if tokenType == "case" or tokenType == "default" or tokenType == "right_curly":
                         break
                     builder.DEFAULT_addStatement(childNode, Statement(tokenizer, staticContext))
-                
+
                 builder.DEFAULT_finish(childNode)
 
             elif tokenType == "case":
@@ -244,7 +243,7 @@
                     if tokenType == "case" or tokenType == "default" or tokenType == "right_curly":
                         break
                     builder.CASE_addStatement(childNode, Statement(tokenizer, staticContext))
-                
+
                 builder.CASE_finish(childNode)
 
             else:
@@ -257,32 +256,32 @@
         builder.SWITCH_finish(node)
 
         return node
-        
+
 
     elif tokenType == "for":
         node = builder.FOR_build(tokenizer)
         forBlock = None
-        
+
         if tokenizer.match("identifier") and tokenizer.token.value == "each":
             builder.FOR_rebuildForEach(node)
-            
+
         tokenizer.mustMatch("left_paren")
         tokenType = tokenizer.peek()
         childNode = None
-        
+
         if tokenType != "semicolon":
             staticContext.inForLoopInit = True
-            
+
             if tokenType == "var" or tokenType == "const":
                 tokenizer.get()
                 childNode = Variables(tokenizer, staticContext)
-            
+
             elif tokenType == "let":
                 tokenizer.get()
 
                 if tokenizer.peek() == "left_paren":
                     childNode = LetBlock(tokenizer, staticContext, False)
-                    
+
                 else:
                     # Let in for head, we need to add an implicit block
                     # around the rest of the for.
@@ -290,72 +289,72 @@
                     staticContext.blockId += 1
                     staticContext.statementStack.append(forBlock)
                     childNode = Variables(tokenizer, staticContext, forBlock)
-                
+
             else:
                 childNode = Expression(tokenizer, staticContext)
-            
+
             staticContext.inForLoopInit = False
 
         if childNode and tokenizer.match("in"):
             builder.FOR_rebuildForIn(node)
             builder.FOR_setObject(node, Expression(tokenizer, staticContext), forBlock)
-            
+
             if childNode.type == "var" or childNode.type == "let":
                 if len(childNode) != 1:
                     raise SyntaxError("Invalid for..in left-hand side", tokenizer)
 
                 builder.FOR_setIterator(node, childNode, forBlock)
-                
+
             else:
                 builder.FOR_setIterator(node, childNode, forBlock)
 
         else:
             builder.FOR_setSetup(node, childNode)
             tokenizer.mustMatch("semicolon")
-            
+
             if node.isEach:
                 raise SyntaxError("Invalid for each..in loop", tokenizer)
-                
+
             if tokenizer.peek() == "semicolon":
                 builder.FOR_setCondition(node, None)
             else:
                 builder.FOR_setCondition(node, Expression(tokenizer, staticContext))
-            
+
             tokenizer.mustMatch("semicolon")
-            
+
             if tokenizer.peek() == "right_paren":
                 builder.FOR_setUpdate(node, None)
-            else:    
+            else:
                 builder.FOR_setUpdate(node, Expression(tokenizer, staticContext))
-        
+
         tokenizer.mustMatch("right_paren")
         builder.FOR_setBody(node, nest(tokenizer, staticContext, node, Statement))
-        
+
         if forBlock:
             builder.BLOCK_finish(forBlock)
             staticContext.statementStack.pop()
-    
+
         builder.FOR_finish(node)
         return node
-        
-        
+
+
     elif tokenType == "while":
         node = builder.WHILE_build(tokenizer)
-        
+
         builder.WHILE_setCondition(node, ParenExpression(tokenizer, staticContext))
         builder.WHILE_setBody(node, nest(tokenizer, staticContext, node, Statement))
         builder.WHILE_finish(node)
-        
-        return node                                    
-        
-        
+
+        return node
+
+
     elif tokenType == "do":
         node = builder.DO_build(tokenizer)
-        
+
         builder.DO_setBody(node, nest(tokenizer, staticContext, node, Statement, "while"))
         builder.DO_setCondition(node, ParenExpression(tokenizer, staticContext))
         builder.DO_finish(node)
-        
+
         if not staticContext.ecma3OnlyMode:
             # <script language="JavaScript"> (without version hints) may need
             # automatic semicolon insertion without a newline after do-while.
@@ -364,17 +363,17 @@
             return node
 
         # NO RETURN
-      
-      
+
+
     elif tokenType == "break" or tokenType == "continue":
         if tokenType == "break":
-            node = builder.BREAK_build(tokenizer) 
+            node = builder.BREAK_build(tokenizer)
         else:
             node = builder.CONTINUE_build(tokenizer)
 
         if tokenizer.peekOnSameLine() == "identifier":
             tokenizer.get()
-            
+
             if tokenType == "break":
                 builder.BREAK_setLabel(node, tokenizer.token.value)
             else:
@@ -392,21 +391,21 @@
                 if getattr(statementStack[i], "label", None) == label:
                     break
 
-            # 
+            #
             # Both break and continue to label need to be handled specially
             # within a labeled loop, so that they target that loop. If not in
             # a loop, then break targets its labeled statement. Labels can be
             # nested so we skip all labels immediately enclosing the nearest
             # non-label statement.
-            # 
+            #
             while i < len(statementStack) - 1 and statementStack[i+1].type == "label":
                 i += 1
-                
+
             if i < len(statementStack) - 1 and getattr(statementStack[i+1], "isLoop", False):
                 i += 1
             elif tokenType == "continue":
                 raise SyntaxError("Invalid continue", tokenizer)
-                
+
         else:
             while True:
                 i -= 1
@@ -418,84 +417,84 @@
 
                 if getattr(statementStack[i], "isLoop", False) or (tokenType == "break" and statementStack[i].type == "switch"):
                     break
-        
+
         if tokenType == "break":
             builder.BREAK_finish(node)
         else:
             builder.CONTINUE_finish(node)
-        
+
         # NO RETURN
 
 
     elif tokenType == "try":
         node = builder.TRY_build(tokenizer)
         builder.TRY_setTryBlock(node, Block(tokenizer, staticContext))
-        
+
         while tokenizer.match("catch"):
             childNode = builder.CATCH_build(tokenizer)
             tokenizer.mustMatch("left_paren")
             nextTokenType = tokenizer.get()
-            
+
             if nextTokenType == "left_bracket" or nextTokenType == "left_curly":
                 # Destructured catch identifiers.
                 tokenizer.unget()
                 exception = DestructuringExpression(tokenizer, staticContext, True)
-            
+
             elif nextTokenType == "identifier":
                 exception = builder.CATCH_wrapException(tokenizer)
-            
+
             else:
                 raise SyntaxError("Missing identifier in catch", tokenizer)
-                
+
             builder.CATCH_setException(childNode, exception)
-            
+
             if tokenizer.match("if"):
                 if staticContext.ecma3OnlyMode:
                     raise SyntaxError("Illegal catch guard", tokenizer)
-                    
+
                 if node.getChildrenLength() > 0 and not node.getUnrelatedChildren()[0].guard:
                     raise SyntaxError("Guarded catch after unguarded", tokenizer)
-                    
+
                 builder.CATCH_setGuard(childNode, Expression(tokenizer, staticContext))
-                
+
             else:
                 builder.CATCH_setGuard(childNode, None)
-            
+
             tokenizer.mustMatch("right_paren")
-            
+
             builder.CATCH_setBlock(childNode, Block(tokenizer, staticContext))
             builder.CATCH_finish(childNode)
-            
+
             builder.TRY_addCatch(node, childNode)
-        
+
         builder.TRY_finishCatches(node)
-        
+
         if tokenizer.match("finally"):
             builder.TRY_setFinallyBlock(node, Block(tokenizer, staticContext))
-            
+
         if node.getChildrenLength() == 0 and not hasattr(node, "finallyBlock"):
             raise SyntaxError("Invalid try statement", tokenizer)
-            
+
         builder.TRY_finish(node)
         return node
-        
+
 
     elif tokenType == "catch" or tokenType == "finally":
-        raise SyntaxError(tokenizer.tokens[tokenType] + " without preceding try", tokenizer)
+        raise SyntaxError(tokens[tokenType] + " without preceding try", tokenizer)
 
 
     elif tokenType == "throw":
         node = builder.THROW_build(tokenizer)
-        
+
         builder.THROW_setException(node, Expression(tokenizer, staticContext))
         builder.THROW_finish(node)
-        
+
         # NO RETURN
 
 
     elif tokenType == "return":
         node = returnOrYield(tokenizer, staticContext)
-        
+
         # NO RETURN
 
 
@@ -511,31 +510,31 @@
 
     elif tokenType == "var" or tokenType == "const":
         node = Variables(tokenizer, staticContext)
-        
+
         # NO RETURN
-        
+
 
     elif tokenType == "let":
         if tokenizer.peek() == "left_paren":
             node = LetBlock(tokenizer, staticContext, True)
         else:
             node = Variables(tokenizer, staticContext)
-        
+
         # NO RETURN
-        
+
 
     elif tokenType == "debugger":
         node = builder.DEBUGGER_build(tokenizer)
-        
+
         # NO RETURN
-        
+
 
     elif tokenType == "newline" or tokenType == "semicolon":
         node = builder.SEMICOLON_build(tokenizer)
 
         builder.SEMICOLON_setExpression(node, None)
         builder.SEMICOLON_finish(tokenizer)
-        
+
         return node
 
 
@@ -547,21 +546,21 @@
             if tokenType == "colon":
                 label = tokenizer.token.value
                 statementStack = staticContext.statementStack
-               
+
                 i = len(statementStack)-1
                 while i >= 0:
                     if getattr(statementStack[i], "label", None) == label:
                         raise SyntaxError("Duplicate label", tokenizer)
-                    
+
                     i -= 1
-               
+
                 tokenizer.get()
                 node = builder.LABEL_build(tokenizer)
-                
+
                 builder.LABEL_setLabel(node, label)
                 builder.LABEL_setStatement(node, nest(tokenizer, staticContext, node, Statement))
                 builder.LABEL_finish(node)
-                
+
                 return node
 
         # Expression statement.
@@ -571,9 +570,9 @@
         builder.SEMICOLON_setExpression(node, Expression(tokenizer, staticContext))
         node.end = node.expression.end
         builder.SEMICOLON_finish(node)
-        
+
         # NO RETURN
-        
+
 
     MagicalSemicolon(tokenizer)
     return node
@@ -583,13 +582,13 @@
 def MagicalSemicolon(tokenizer):
     if tokenizer.line == tokenizer.token.line:
         tokenType = tokenizer.peekOnSameLine()
-    
+
         if tokenType != "end" and tokenType != "newline" and tokenType != "semicolon" and tokenType != "right_curly":
             raise SyntaxError("Missing ; before statement", tokenizer)
-    
+
     tokenizer.match("semicolon")
 
-    
+
 
 def returnOrYield(tokenizer, staticContext):
     builder = staticContext.builder
@@ -598,13 +597,13 @@
     if tokenType == "return":
         if not staticContext.inFunction:
             raise SyntaxError("Return not in function", tokenizer)
-            
+
         node = builder.RETURN_build(tokenizer)
-        
+
     else:
         if not staticContext.inFunction:
             raise SyntaxError("Yield not in function", tokenizer)
-            
+
         staticContext.isGenerator = True
         node = builder.YIELD_build(tokenizer)
 
@@ -615,7 +614,7 @@
             staticContext.hasReturnWithValue = True
         else:
             builder.YIELD_setValue(node, AssignExpression(tokenizer, staticContext))
-        
+
     elif tokenType == "return":
         staticContext.hasEmptyReturn = True
 
@@ -635,14 +634,14 @@
 def FunctionDefinition(tokenizer, staticContext, requireName, functionForm):
     builder = staticContext.builder
     functionNode = builder.FUNCTION_build(tokenizer)
-    
+
     if tokenizer.match("identifier"):
         builder.FUNCTION_setName(functionNode, tokenizer.token.value)
     elif requireName:
         raise SyntaxError("Missing def identifier", tokenizer)
 
     tokenizer.mustMatch("left_paren")
-    
+
     if not tokenizer.match("right_paren"):
         builder.FUNCTION_initParams(functionNode, tokenizer)
         prevParamNode = None
@@ -652,21 +651,21 @@
                 # Destructured formal parameters.
                 tokenizer.unget()
                 paramNode = DestructuringExpression(tokenizer, staticContext)
-                
+
             elif tokenType == "identifier":
                 paramNode = builder.FUNCTION_wrapParam(tokenizer)
-                
+
             else:
                 raise SyntaxError("Missing formal parameter", tokenizer)
-                
+
             builder.FUNCTION_addParam(functionNode, tokenizer, paramNode)
             builder.COMMENTS_add(paramNode, prevParamNode, tokenizer.getComments())
-        
+
             if not tokenizer.match("comma"):
                 break
-                
+
             prevParamNode = paramNode
-        
+
         tokenizer.mustMatch("right_paren")
 
     # Do we have an expression closure or a normal body?
@@ -676,8 +675,7 @@
         tokenizer.unget()
 
     childContext = StaticContext(True, builder)
-    tokenizer.save()
-    
+
     if staticContext.inFunction:
         # Inner functions don't reset block numbering, only functions at
         # the top level of the program do.
@@ -687,128 +685,49 @@
         builder.FUNCTION_setBody(functionNode, AssignExpression(tokenizer, staticContext))
         if staticContext.isGenerator:
             raise SyntaxError("Generator returns a value", tokenizer)
-            
+
     else:
         builder.FUNCTION_hoistVars(childContext.blockId)
         builder.FUNCTION_setBody(functionNode, Script(tokenizer, childContext))
 
-    # 
-    # Hoisting makes parse-time binding analysis tricky. A taxonomy of hoists:
-    # 
-    # 1. vars hoist to the top of their function:
-    # 
-    #    var x = 'global';
-    #    function f() {
-    #      x = 'f';
-    #      if (false)
-    #        var x;
-    #    }
-    #    f();
-    #    print(x); // "global"
-    # 
-    # 2. lets hoist to the top of their block:
-    # 
-    #    function f() { // id: 0
-    #      var x = 'f';
-    #      {
-    #        {
-    #          print(x); // "undefined"
-    #        }
-    #        let x;
-    #      }
-    #    }
-    #    f();
-    # 
-    # 3. inner functions at function top-level hoist to the beginning
-    #    of the function.
-    # 
-    # If the builder used is doing parse-time analyses, hoisting may
-    # invalidate earlier conclusions it makes about variable scope.
-    # 
-    # The builder can opt to set the needsHoisting flag in a
-    # CompilerContext (in the case of var and function hoisting) or in a
-    # node of type BLOCK (in the case of let hoisting). This signals for
-    # the parser to reparse sections of code.
-    # 
-    # To avoid exponential blowup, if a function at the program top-level
-    # has any hoists in its child blocks or inner functions, we reparse
-    # the entire toplevel function. Each toplevel function is parsed at
-    # most twice.
-    # 
-    # The list of declarations can be tied to block ids to aid talking
-    # about declarations of blocks that have not yet been fully parsed.
-    # 
-    # Blocks are already uniquely numbered; see the comment in
-    # Statements.
-    # 
-    
-    #
-    # wpbasti: 
-    # Don't have the feeling that I need this functionality because the
-    # tree is often modified before the variables and names inside are 
-    # of any interest. So better doing this in a post-scan.
-    #
-    
-    #
-    # if childContext.needsHoisting:
-    #     # Order is important here! Builders expect functions to come after variables!
-    #     builder.setHoists(functionNode.body.id, childContext.variables.concat(childContext.functions))
-    # 
-    #     if staticContext.inFunction:
-    #         # If an inner function needs hoisting, we need to propagate
-    #         # this flag up to the parent function.
-    #         staticContext.needsHoisting = True
-    #     
-    #     else:
-    #         # Only re-parse functions at the top level of the program.
-    #         childContext = StaticContext(True, builder)
-    #         tokenizer.rewind(rp)
-    #         
-    #         # Set a flag in case the builder wants to have different behavior
-    #         # on the second pass.
-    #         builder.secondPass = True
-    #         builder.FUNCTION_hoistVars(functionNode.body.id, True)
-    #         builder.FUNCTION_setBody(functionNode, Script(tokenizer, childContext))
-    #         builder.secondPass = False
-
     if tokenType == "left_curly":
         tokenizer.mustMatch("right_curly")
 
     functionNode.end = tokenizer.token.end
     functionNode.functionForm = functionForm
-    
+
     builder.COMMENTS_add(functionNode.body, functionNode.body, tokenizer.getComments())
     builder.FUNCTION_finish(functionNode, staticContext)
-    
+
     return functionNode
 
 
 
 def Variables(tokenizer, staticContext, letBlock=None):
     """Parses a comma-separated list of var declarations (and maybe initializations)."""
-    
+
     builder = staticContext.builder
     if tokenizer.token.type == "var":
         build = builder.VAR_build
         addDecl = builder.VAR_addDecl
         finish = builder.VAR_finish
         childContext = staticContext
-            
+
     elif tokenizer.token.type == "const":
         build = builder.CONST_build
         addDecl = builder.CONST_addDecl
         finish = builder.CONST_finish
         childContext = staticContext
-        
+
     elif tokenizer.token.type == "let" or tokenizer.token.type == "left_paren":
         build = builder.LET_build
         addDecl = builder.LET_addDecl
         finish = builder.LET_finish
-        
+
         if not letBlock:
             statementStack = staticContext.statementStack
             i = len(statementStack) - 1
-            
+
             # a BLOCK *must* be found.
             while statementStack[i].type != "block":
                 i -= 1
@@ -822,12 +741,12 @@
 
             else:
                 childContext = statementStack[i]
-            
+
         else:
             childContext = letBlock
 
     node = build(tokenizer)
-    
+
     while True:
         tokenType = tokenizer.get()
 
@@ -836,20 +755,20 @@
         # IDENTIFIER to mean both identifier declarations and destructured
         # declarations.
         childNode = builder.DECL_build(tokenizer)
-        
+
         if tokenType == "left_bracket" or tokenType == "left_curly":
             # Pass in childContext if we need to add each pattern matched into
             # its variables, else pass in staticContext.
             # Need to unget to parse the full destructured expression.
             tokenizer.unget()
             builder.DECL_setNames(childNode, DestructuringExpression(tokenizer, staticContext, True, childContext))
-            
+
             if staticContext.inForLoopInit and tokenizer.peek() == "in":
                 addDecl(node, childNode, childContext)
-                if tokenizer.match("comma"): 
+                if tokenizer.match("comma"):
                     continue
-                else: 
-                    break            
+                else:
+                    break
 
             tokenizer.mustMatch("assign")
             if tokenizer.token.assignOp:
@@ -859,15 +778,15 @@
             builder.DECL_setInitializer(childNode, AssignExpression(tokenizer, staticContext))
             builder.DECL_finish(childNode)
             addDecl(node, childNode, childContext)
-            
+
             # Copy over names for variable list
             # for nameNode in childNode.names:
             #    childContext.variables.add(nameNode.value)
-                
-            if tokenizer.match("comma"): 
+
+            if tokenizer.match("comma"):
                 continue
-            else: 
-                break            
+            else:
+                break
 
         if tokenType != "identifier":
             raise SyntaxError("Missing variable name", tokenizer)
@@ -884,16 +803,16 @@
             builder.DECL_setInitializer(childNode, initializerNode)
 
         builder.DECL_finish(childNode)
-        
+
         # If we directly use the node in "let" constructs
         # if not hasattr(childContext, "variables"):
         #    childContext.variables = set()
-        
+
         # childContext.variables.add(childNode.name)
-        
+
         if not tokenizer.match("comma"):
             break
-        
+
     finish(node)
     return node
 
@@ -921,7 +840,7 @@
     if isStatement:
         childNode = Block(tokenizer, staticContext)
         builder.LETBLOCK_setBlock(node, childNode)
-        
+
     else:
         childNode = AssignExpression(tokenizer, staticContext)
         builder.LETBLOCK_setExpression(node, childNode)
@@ -933,7 +852,7 @@
 def checkDestructuring(tokenizer, staticContext, node, simpleNamesOnly=None, data=None):
     if node.type == "array_comp":
         raise SyntaxError("Invalid array comprehension left-hand side", tokenizer)
-        
+
     if node.type != "array_init" and node.type != "object_init":
         return
 
@@ -942,23 +861,23 @@
     for child in node:
         if child == None:
             continue
-        
+
         if child.type == "property_init":
             lhs = child[0]
             rhs = child[1]
         else:
             lhs = None
             rhs = None
-            
-    
+
+
         if rhs and (rhs.type == "array_init" or rhs.type == "object_init"):
             checkDestructuring(tokenizer, staticContext, rhs, simpleNamesOnly, data)
-            
+
         if lhs and simpleNamesOnly:
             # In declarations, lhs must be simple names
             if lhs.type != "identifier":
                 raise SyntaxError("Missing name in pattern", tokenizer)
-                
+
             elif data:
                 childNode = builder.DECL_build(tokenizer)
                 builder.DECL_setName(childNode, lhs.value)
@@ -969,7 +888,7 @@
 
                 # Each pattern needs to be added to variables.
                 # data.variables.add(childNode.name)
-                
+
 
 # JavaScript 1.7
 def DestructuringExpression(tokenizer, staticContext, simpleNamesOnly=None, data=None):
@@ -987,20 +906,20 @@
     builder.GENERATOR_setExpression(node, expression)
     builder.GENERATOR_setTail(node, comprehensionTail(tokenizer, staticContext))
     builder.GENERATOR_finish(node)
-    
+
     return node
 
 
 # JavaScript 1.7 Comprehensions Tails (Generators / Arrays)
 def comprehensionTail(tokenizer, staticContext):
     builder = staticContext.builder
-    
+
     # tokenizer.token.type must be "for"
     body = builder.COMPTAIL_build(tokenizer)
-    
+
     while True:
         node = builder.FOR_build(tokenizer)
-        
+
         # Comprehension tails are always for..in loops.
         builder.FOR_rebuildForIn(node)
         if tokenizer.match("identifier"):
@@ -1011,7 +930,7 @@
                 tokenizer.unget()
 
         tokenizer.mustMatch("left_paren")
-        
+
         tokenType = tokenizer.get()
         if tokenType == "left_bracket" or tokenType == "left_curly":
             tokenizer.unget()
@@ -1021,7 +940,7 @@
         elif tokenType == "identifier":
             # Removed variable/declaration substructure in Python port.
             # Variable declarations are not allowed here. So why process them in such a way?
-            
+
             # declaration = builder.DECL_build(tokenizer)
             # builder.DECL_setName(declaration, tokenizer.token.value)
             # builder.DECL_finish(declaration)
@@ -1032,18 +951,18 @@
 
             # Don't add to variables since the semantics of comprehensions is
             # such that the variables are in their own def when desugared.
-            
+
             identifier = builder.PRIMARY_build(tokenizer, "identifier")
             builder.FOR_setIterator(node, identifier)
 
         else:
             raise SyntaxError("Missing identifier", tokenizer)
-        
+
         tokenizer.mustMatch("in")
         builder.FOR_setObject(node, Expression(tokenizer, staticContext))
         tokenizer.mustMatch("right_paren")
         builder.COMPTAIL_addFor(body, node)
-        
+
         if not tokenizer.match("for"):
             break
 
@@ -1071,10 +990,10 @@
     if tokenizer.match("for"):
         if node.type == "yield" and not node.parenthesized:
             raise SyntaxError("Yield " + err, tokenizer)
-            
+
         if node.type == "comma" and not node.parenthesized:
             raise SyntaxError("Generator " + err, tokenizer)
-            
+
         node = GeneratorExpression(tokenizer, staticContext, node)
 
     tokenizer.mustMatch("right_paren")
@@ -1096,10 +1015,10 @@
             if childNode.type == "yield" and not childNode.parenthesized:
                 raise SyntaxError("Yield expression must be parenthesized", tokenizer)
             builder.COMMA_addOperand(node, AssignExpression(tokenizer, staticContext))
-            
+
             if not tokenizer.match("comma"):
                 break
-                
+
         builder.COMMA_finish(node)
 
     return node
@@ -1128,7 +1047,7 @@
         pass
     else:
         raise SyntaxError("Bad left-hand side of assignment", tokenizer)
-        
+
     builder.ASSIGN_setAssignOp(node, tokenizer.token.assignOp)
     builder.ASSIGN_addOperand(node, lhs)
     builder.ASSIGN_addOperand(node, AssignExpression(tokenizer, staticContext))
@@ -1153,20 +1072,20 @@
         staticContext.inForLoopInit = False
         builder.HOOK_setThenPart(node, AssignExpression(tokenizer, staticContext))
         staticContext.inForLoopInit = oldLoopInit
-        
+
         if not tokenizer.match("colon"):
             raise SyntaxError("Missing : after ?", tokenizer)
-            
+
         builder.HOOK_setElsePart(node, AssignExpression(tokenizer, staticContext))
         builder.HOOK_finish(node)
 
     return node
-    
+
 
 def OrExpression(tokenizer, staticContext):
     builder = staticContext.builder
     node = AndExpression(tokenizer, staticContext)
-    
+
     while tokenizer.match("or"):
         childNode = builder.OR_build(tokenizer)
         builder.OR_addOperand(childNode, node)
@@ -1194,7 +1113,7 @@
 def BitwiseOrExpression(tokenizer, staticContext):
     builder = staticContext.builder
     node = BitwiseXorExpression(tokenizer, staticContext)
-    
+
     while tokenizer.match("bitwise_or"):
         childNode = builder.BITWISEOR_build(tokenizer)
         builder.BITWISEOR_addOperand(childNode, node)
@@ -1208,7 +1127,7 @@
 def BitwiseXorExpression(tokenizer, staticContext):
     builder = staticContext.builder
     node = BitwiseAndExpression(tokenizer, staticContext)
-    
+
     while tokenizer.match("bitwise_xor"):
         childNode = builder.BITWISEXOR_build(tokenizer)
         builder.BITWISEXOR_addOperand(childNode, node)
@@ -1236,7 +1155,7 @@
 def EqualityExpression(tokenizer, staticContext):
     builder = staticContext.builder
     node = RelationalExpression(tokenizer, staticContext)
-    
+
     while tokenizer.match("eq") or tokenizer.match("ne") or tokenizer.match("strict_eq") or tokenizer.match("strict_ne"):
         childNode = builder.EQUALITY_build(tokenizer)
         builder.EQUALITY_addOperand(childNode, node)
@@ -1262,7 +1181,7 @@
         builder.RELATIONAL_addOperand(childNode, ShiftExpression(tokenizer, staticContext))
         builder.RELATIONAL_finish(childNode)
         node = childNode
-    
+
     staticContext.inForLoopInit = oldLoopInit
 
     return node
@@ -1271,7 +1190,7 @@
 def ShiftExpression(tokenizer, staticContext):
     builder = staticContext.builder
     node = AddExpression(tokenizer, staticContext)
-    
+
     while tokenizer.match("lsh") or tokenizer.match("rsh") or tokenizer.match("ursh"):
         childNode = builder.SHIFT_build(tokenizer)
         builder.SHIFT_addOperand(childNode, node)
@@ -1285,7 +1204,7 @@
 def AddExpression(tokenizer, staticContext):
     builder = staticContext.builder
     node = MultiplyExpression(tokenizer, staticContext)
-    
+
     while tokenizer.match("plus") or tokenizer.match("minus"):
         childNode = builder.ADD_build(tokenizer)
         builder.ADD_addOperand(childNode, node)
@@ -1299,7 +1218,7 @@
 def MultiplyExpression(tokenizer, staticContext):
     builder = staticContext.builder
     node = UnaryExpression(tokenizer, staticContext)
-    
+
     while tokenizer.match("mul") or tokenizer.match("div") or tokenizer.match("mod"):
         childNode = builder.MULTIPLY_build(tokenizer)
         builder.MULTIPLY_addOperand(childNode, node)
@@ -1317,7 +1236,7 @@
     if tokenType in ["delete", "void", "typeof", "not", "bitwise_not", "plus", "minus"]:
         node = builder.UNARY_build(tokenizer)
         builder.UNARY_addOperand(node, UnaryExpression(tokenizer, staticContext))
-    
+
     elif tokenType == "increment" or tokenType == "decrement":
         # Prefix increment/decrement.
         node = builder.UNARY_build(tokenizer)
@@ -1346,13 +1265,13 @@
     if tokenizer.match("new"):
         node = builder.MEMBER_build(tokenizer)
         builder.MEMBER_addOperand(node, MemberExpression(tokenizer, staticContext, False))
-        
+
         if tokenizer.match("left_paren"):
             builder.MEMBER_rebuildNewWithArgs(node)
             builder.MEMBER_addOperand(node, ArgumentList(tokenizer, staticContext))
-        
+
         builder.MEMBER_finish(node)
-    
+
     else:
         node = PrimaryExpression(tokenizer, staticContext)
 
@@ -1360,7 +1279,7 @@
         tokenType = tokenizer.get()
         if tokenType == "end":
             break
-        
+
         if tokenType == "dot":
             childNode = builder.MEMBER_build(tokenizer)
             builder.MEMBER_addOperand(childNode, node)
@@ -1391,20 +1310,20 @@
 def ArgumentList(tokenizer, staticContext):
     builder = staticContext.builder
     node = builder.LIST_build(tokenizer)
-    
+
     if tokenizer.match("right_paren", True):
         return node
-    
-    while True:    
+
+    while True:
         childNode = AssignExpression(tokenizer, staticContext)
         if childNode.type == "yield" and not childNode.parenthesized and tokenizer.peek() == "comma":
             raise SyntaxError("Yield expression must be parenthesized", tokenizer)
-            
+
         if tokenizer.match("for"):
             childNode = GeneratorExpression(tokenizer, staticContext, childNode)
             if len(node) > 1 or tokenizer.peek(True) == "comma":
                 raise SyntaxError("Generator expression must be parenthesized", tokenizer)
-        
+
         builder.LIST_addOperand(node, childNode)
         if not tokenizer.match("comma"):
             break
@@ -1428,7 +1347,7 @@
             tokenType = tokenizer.peek(True)
             if tokenType == "right_bracket":
                 break
-        
+
             if tokenType == "comma":
                 tokenizer.get()
                 builder.ARRAYINIT_addElement(node, None)
@@ -1446,7 +1365,7 @@
             builder.ARRAYCOMP_setExpression(childNode, node[0])
             builder.ARRAYCOMP_setTail(childNode, comprehensionTail(tokenizer, staticContext))
             node = childNode
-        
+
         builder.COMMENTS_add(node, node, tokenizer.getComments())
         tokenizer.mustMatch("right_bracket")
         builder.PRIMARY_finish(node)
@@ -1459,26 +1378,26 @@
                 tokenType = tokenizer.get()
                 tokenValue = getattr(tokenizer.token, "value", None)
                 comments = tokenizer.getComments()
-                
+
                 if tokenValue in ("get", "set") and tokenizer.peek() == "identifier":
                     if staticContext.ecma3OnlyMode:
                         raise SyntaxError("Illegal property accessor", tokenizer)
-                        
+
                     fd = FunctionDefinition(tokenizer, staticContext, True, "expressed_form")
                     builder.OBJECTINIT_addProperty(node, fd)
-                    
+
                 else:
                     if tokenType == "identifier" or tokenType == "number" or tokenType == "string":
                         id = builder.PRIMARY_build(tokenizer, "identifier")
                         builder.PRIMARY_finish(id)
-                        
+
                     elif tokenType == "right_curly":
                         if staticContext.ecma3OnlyMode:
                             raise SyntaxError("Illegal trailing ,", tokenizer)
-                            
+
                         tokenizer.unget()
                         break
-                            
+
                     else:
                         if tokenValue in jasy.js.tokenize.Lang.keywords:
                             id = builder.PRIMARY_build(tokenizer, "identifier")
@@ -1486,7 +1405,7 @@
                         else:
                             print("Value is '%s'" % tokenValue)
                             raise SyntaxError("Invalid property name", tokenizer)
-                    
+
                     if tokenizer.match("colon"):
                         childNode = builder.PROPERTYINIT_build(tokenizer)
                         builder.COMMENTS_add(childNode, node, comments)
@@ -1494,14 +1413,14 @@
                         builder.PROPERTYINIT_addOperand(childNode, AssignExpression(tokenizer, staticContext))
                         builder.PROPERTYINIT_finish(childNode)
                         builder.OBJECTINIT_addProperty(node, childNode)
-                        
+
                     else:
                         # Support, e.g., |var {staticContext, y} = o| as destructuring shorthand
                         # for |var {staticContext: staticContext, y: y} = o|, per proposed JS2/ES4 for JS1.8.
                         if tokenizer.peek() != "comma" and tokenizer.peek() != "right_curly":
                             raise SyntaxError("Missing : after property", tokenizer)
                         builder.OBJECTINIT_addProperty(node, id)
-                    
+
                 if not tokenizer.match("comma"):
                     break
 

eric ide

mercurial