Beispiel #1
0
        private void ParseAst(JS.AST ast, string sp)
        {
            if (ast == null)
            {
                return;
            }
            if (CheckWorker())
            {
                return;
            }

            //_logView.LogStr("JSM->" + sp + ast.ToString() + "\t\t" + ast.GetType().Name);

            if (ast is JS.FunctionDeclaration)
            {
                JS.Function func = ast as JS.Function;
                ParseAstList(func.func_obj.body.elems, sp + "  ");
            }
            else if (ast is JS.Assign)
            {
                JS.Assign ass = ast as JS.Assign;

                ParseAst(ass.left, sp + "l ");
                ParseAst(ass.right, sp + "r ");
            }
            else if (ast is JS.Binary)
            {
                JS.Binary bin = ast as JS.Binary;

                string[] parts = bin.ToString().Split('.');
                if (parts.Length > 1)
                {
                    if (parts[parts.Length - 2] == "This")
                    {
                        string calledId = parts[parts.Length - 1] + "()";

                        //dup
                        // If we have a method of this name in this file/class
                        if (_addedNodes.ContainsKey(calledId))
                        {
                            // Create an edge.
                            // A definite functional assignment link.
                            AddEdge(_methodNodeId, calledId, EdgeStyle.NormalArrow, Color.Aqua);
                        }
                        else
                        {
                            // It's a call to a method outside this class/file.
                            //
                            //_logView.LogStr("skipped assign ref -->" + _methodNodeId + " --------> " + calledId);
                            //
                        }
                    }
                    else if (parts[parts.Length - 2] == "self")
                    {
                        string calledId = parts[parts.Length - 1] + "()";

                        //dup
                        // If we have a method of this name in this file/class
                        if (_addedNodes.ContainsKey(calledId))
                        {
                            // Get the graph node that we're linking to.
                            //Node calledNode = _addedNodes[calledId];

                            // Create an edge.
                            // A definite functional assignment link.
                            AddEdge(_methodNodeId, calledId, EdgeStyle.NormalArrow, Color.Aqua);
                        }
                        else
                        {
                            // It's a call to a method outside this class/file.
                            _logView.LogStr("skipped assign ref -->" + _methodNodeId + " --------> " + calledId);
                        }
                    }
                }
            }
            else if (ast is JS.Expression)
            {
                JS.Expression expr = ast as JS.Expression;
                ParseAstList(expr.exprs, sp + "  ");
            }
            else if (ast is JS.FunctionExpression)
            {
                JS.FunctionExpression expr = ast as JS.FunctionExpression;
                ParseAstList(expr.func_obj.body.elems, sp + "  ");
            }
            else if (ast is JS.For)
            {
                JS.For fr = ast as JS.For;
                ParseAst(fr.stms, sp + "  ");
            }
            else if (ast is JS.If)
            {
                JS.If iff = ast as JS.If;
                ParseAst(iff.false_stm, sp + "f  ");
                ParseAst(iff.true_stm, sp + "t  ");
            }
            else if (ast is JS.Block)
            {
                JS.Block block = ast as JS.Block;
                ParseAstList(block.elems, sp + "  ");
            }
            else if (ast is JS.VariableStatement)
            {
                JS.VariableStatement var = ast as JS.VariableStatement;
                //var.
                ParseAstList(var.var_decls, sp + "  ");
            }
            else if (ast is JS.Return)
            {
                JS.Return ret = ast as JS.Return;

                ParseAst(ret.expression, sp + "  ");
            }
            else if (ast is JS.VariableDeclaration)
            {
                JS.VariableDeclaration var = ast as JS.VariableDeclaration;

                Microsoft.JScript.New newval = var.val as Microsoft.JScript.New;

                if (newval != null && newval.exp != null)
                {
                    //_logView.LogStr("new:" + newval.exp.ToString());
                    string[] parts = newval.exp.ToString().Split('.');
                    if (parts.Length > 0)
                    {
                        string calledId = parts[parts.Length - 1] + "()";

                        // If we have a method of this name in this file/class, then
                        // we have a possible constructor link.
                        if (_addedNodes.ContainsKey(calledId))
                        {
                            // Create an edge.
                            AddEdge(_methodNodeId, calledId, EdgeStyle.NormalArrow, Color.Green);
                        }
                    }
                }
                else
                {
                    if (var.val != null)
                    {
                        string   valStr = var.val.ToString();
                        string[] parts  = valStr.Split('.');

                        if (parts.Length > 1 && parts[0] == "self")
                        {
                            // dup..

                            string calledId = parts[parts.Length - 1] + "()";

                            // If we have a method of this name in this file/class, then
                            // we have a possible constructor link.
                            if (_addedNodes.ContainsKey(calledId))
                            {
                                // Create an edge.
                                AddEdge(_methodNodeId, calledId, EdgeStyle.NormalArrow, Color.Green);
                            }
                        }
                    }
                }

                //ParseAstList(var.var_decls, sp + "  ");
            }
            else if (ast is JS.Call)
            {
                JS.Call  call     = ast as JS.Call;
                string[] parts    = call.ToString().Split(' ');
                string[] bits     = parts[0].Split('.');
                string   calledId = bits[bits.Length - 1] + "()";

                bool methodInThisClass = true;
                if (bits.Length > 1)
                {
                    if ((bits[bits.Length - 2] != "This") &&
                        (bits[bits.Length - 2] != "self"))
                    {
                        methodInThisClass = false;
                    }
                }

                // If we have a method of this name in this file/class
                if (_addedNodes.ContainsKey(calledId))
                {
                    // Create an edge.
                    if (methodInThisClass)
                    {
                        // A definite link.
                        AddEdge(_methodNodeId, calledId, EdgeStyle.NormalArrow, Color.Black);
                    }
                    else
                    {
                        // A tentative link.
                        AddEdge(_methodNodeId, calledId, EdgeStyle.NormalArrow, Color.Gray);
                    }
                }
                else
                {
                    // It's a call to a method outside this class/file.
                    //
                    //_logView.LogStr("skipped -------->" + _methodNodeId + " --------> " + parts[0]);
                    //
                }
            }
        }
Beispiel #2
0
        AST MemberExprTail(AST parent, bool allow_call_syntax, AST pn)
        {
            int tt;

            while ((tt = ts.GetToken ()) > Token.EOF) {
                if (tt == Token.DOT) {
                    decompiler.AddToken (Token.DOT);
                    MustMatchToken (Token.NAME, "msg.no.name.after.dot");
                    string s = ts.GetString;
                    decompiler.AddName (s);
                    // FIXME: is 'new Identifier' appropriate here?
                    pn = new Binary (parent, pn,
                         new Identifier (parent, ts.GetString, new Location (ts.SourceName, ts.LineNumber)),
                         JSToken.AccessField, new Location (ts.SourceName, ts.LineNumber));
                } else if (tt == Token.LB) {
                    decompiler.AddToken (Token.LB);
                    Binary b = new Binary (parent, pn, JSToken.LeftBracket,
                               new Location (ts.SourceName, ts.LineNumber));
                    b.right = Expr (b, false);
                    pn = b;
                    MustMatchToken (Token.RB, "msg.no.bracket.index");
                    decompiler.AddToken (Token.RB);
                } else if (allow_call_syntax && tt == Token.LP) {
                    /* make a call node */
                    decompiler.AddToken (Token.LP);
                    pn = new Call (parent, pn, new Location (ts.SourceName, ts.LineNumber));

                    /* Add the arguments to pn, if any are supplied. */
                    ArgumentList (parent, (ICallable) pn);
                } else {
                    ts.UnGetToken (tt);
                    break;
                }
            }
            return pn;
        }
Beispiel #3
0
      private AST MemberExpression(AST expression, ArrayList newContexts, out bool canBeQualid, ref bool canBeAttribute){
        bool noMoreForAttr = false;
        canBeQualid = true;
        for(;;){
          this.noSkipTokenSet.Add(NoSkipTokenSet.s_MemberExprNoSkipTokenSet);
          try{
            switch (this.currentToken.token){
              case JSToken.LeftParen:
                if (noMoreForAttr)
                  canBeAttribute = false;
                else
                  noMoreForAttr = true;
                canBeQualid = false;

                ASTList args = null;
                RecoveryTokenException callError = null;
                this.noSkipTokenSet.Add(NoSkipTokenSet.s_ParenToken);
                try{
                  args = ParseExpressionList(JSToken.RightParen);
                }catch(RecoveryTokenException exc){
                  args = (ASTList)exc._partiallyComputedNode;
                  if (IndexOfToken(NoSkipTokenSet.s_ParenToken, exc) == -1)
                    callError = exc; // thrown later on
                }finally{
                  this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ParenToken);
                }

                //treat eval and print specially
                if (expression is Lookup){
                  String name = expression.ToString();
                  if (name.Equals("eval")){
                    expression.context.UpdateWith(args.context);
                    if (args.count > 0)
                      expression = new Eval(expression.context, args[0]);
                    else
                      expression = new Eval(expression.context, new ConstantWrapper("", CurrentPositionContext()));
                  }else if (this.Globals.engine.doPrint && name.Equals("print")){
                    expression.context.UpdateWith(args.context);
                    expression = new Print(expression.context, args);
                  }else{
                    if (name == "GetObject")
                      this.ForceReportInfo(JSError.GetObjectNotSupportedOnRotor);
                    expression = new Call(expression.context.CombineWith(args.context), expression, args, false);
                  }
                }else
                  expression = new Call(expression.context.CombineWith(args.context), expression, args, false);

                if (null != newContexts && newContexts.Count > 0){
                  ((Context)newContexts[newContexts.Count - 1]).UpdateWith(expression.context);
                  if (!(expression is Call))
                    expression = new Call((Context)newContexts[newContexts.Count - 1], expression, new ASTList(CurrentPositionContext()), false);
                  else
                    expression.context = (Context)newContexts[newContexts.Count - 1];
                  ((Call)expression).isConstructor = true;
                  newContexts.RemoveAt(newContexts.Count - 1);
                }

                if (callError != null){
                  callError._partiallyComputedNode = expression;
                  throw callError;
                }

                GetNextToken();
              break;

              case JSToken.LeftBracket:
                canBeQualid = false;
                canBeAttribute = false;
                this.noSkipTokenSet.Add(NoSkipTokenSet.s_BracketToken);
                try{
                  args = ParseExpressionList(JSToken.RightBracket);
                }catch(RecoveryTokenException exc){
                  if(IndexOfToken(NoSkipTokenSet.s_BracketToken, exc) == -1){
                    if (exc._partiallyComputedNode != null){
                      exc._partiallyComputedNode =
                         new Call(expression.context.CombineWith(this.currentToken.Clone()), expression, (ASTList)exc._partiallyComputedNode, true);
                    }else{
                      exc._partiallyComputedNode = expression;
                    }
                    throw exc;
                  }else
                    args = (ASTList)exc._partiallyComputedNode;
                }finally{
                  this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BracketToken);
                }
                expression = new Call(expression.context.CombineWith(this.currentToken.Clone()), expression, args, true);

                if (null != newContexts && newContexts.Count > 0){
                  ((Context)newContexts[newContexts.Count - 1]).UpdateWith(expression.context);
                  expression.context = (Context)newContexts[newContexts.Count - 1];
                  ((Call)expression).isConstructor = true;
                  newContexts.RemoveAt(newContexts.Count - 1);
                }
                GetNextToken();
              break;

              case JSToken.AccessField:
                if (noMoreForAttr)
                  canBeAttribute = false;
                ConstantWrapper id = null;
                GetNextToken();
                if (JSToken.Identifier != this.currentToken.token){
                  string identifier = JSKeyword.CanBeIdentifier(this.currentToken.token);
                  if (null != identifier){
                    ForceReportInfo(JSError.KeywordUsedAsIdentifier);
                    id = new ConstantWrapper(identifier, this.currentToken.Clone());
                  }else{
                    ReportError(JSError.NoIdentifier);
                    SkipTokensAndThrow(expression);
                  }
                }else
                  id = new ConstantWrapper(this.scanner.GetIdentifier(), this.currentToken.Clone());
                GetNextToken();
                expression = new Member(expression.context.CombineWith(id.context), expression, id);
              break;
              default:
                if (null != newContexts){
                  while (newContexts.Count > 0){
                    ((Context)newContexts[newContexts.Count - 1]).UpdateWith(expression.context);
                    expression = new Call((Context)newContexts[newContexts.Count - 1],
                                          expression,
                                          new ASTList(CurrentPositionContext()),
                                          false);
                    ((Call)expression).isConstructor = true;
                    newContexts.RemoveAt(newContexts.Count - 1);
                  }
                }
                return expression;
            }
          }catch(RecoveryTokenException exc){
            if (IndexOfToken(NoSkipTokenSet.s_MemberExprNoSkipTokenSet, exc) != -1)
              expression = exc._partiallyComputedNode;
            else{
              Debug.Assert(exc._partiallyComputedNode == expression);
              throw exc;
            }
          }finally{
            this.noSkipTokenSet.Remove(NoSkipTokenSet.s_MemberExprNoSkipTokenSet);
          }
        }
      }
Beispiel #4
0
      private AST ParseFunction(FieldAttributes visibilitySpec,
                                bool inExpression,
                                Context fncCtx,
                                bool isMethod,
                                bool isAbstract,
                                bool isFinal,
                                bool isInterface,
                                CustomAttributeList customAttributes,
                                Call function){
        IdentifierLiteral name = null;
        AST interfaceName = null;
        ArrayList formalParameters = null;
        TypeExpression returnType = null;
        Block body = null;
        bool isGetter = false;
        bool isSetter = false;

        if (function == null){
          GetNextToken();
          if (isMethod)
            if (JSToken.Get == this.currentToken.token){
              isGetter = true;
              GetNextToken();
            }else if (JSToken.Set == this.currentToken.token){
              isSetter = true;
              GetNextToken();
            }

          // get the function name or make an anonymous function if in expression "position"
          if (JSToken.Identifier == this.currentToken.token){
            name = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone());
            GetNextToken();
            if (JSToken.AccessField == this.currentToken.token){
              if (isInterface) // "function IBar.foo()" is illegal in an interface declaration
                ReportError(JSError.SyntaxError, true);
              GetNextToken();
              if (JSToken.Identifier == this.currentToken.token){
                interfaceName = new Lookup(name.context);
                name = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone());
                GetNextToken();
                while (JSToken.AccessField == this.currentToken.token){
                  GetNextToken();
                  if (JSToken.Identifier == this.currentToken.token){
                    interfaceName = new Member(interfaceName.context.CombineWith(this.currentToken), interfaceName,
                      new ConstantWrapper(name.ToString(), name.context));
                    name = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone());
                    GetNextToken();
                  }else
                    ReportError(JSError.NoIdentifier, true);
                }
              }else
                ReportError(JSError.NoIdentifier, true);
            }
          }else{
            string identifier = JSKeyword.CanBeIdentifier(this.currentToken.token);
            if (null != identifier){
              ForceReportInfo(JSError.KeywordUsedAsIdentifier, isMethod);
              name = new IdentifierLiteral(identifier, this.currentToken.Clone());
              GetNextToken();
            }else{
              if (!inExpression){
                identifier = this.currentToken.GetCode();
                ReportError(JSError.NoIdentifier, true);
                GetNextToken();
              }else
                identifier = "";
              name = new IdentifierLiteral(identifier, CurrentPositionContext());
            }
          }
        }else{ // function was passed in, this is an error condition
          name = function.GetName();
        }

        // make a new state and save the old one
        ArrayList blockType = this.blockType;
        this.blockType = new ArrayList(16);
        SimpleHashtable labelTable = this.labelTable;
        this.labelTable = new SimpleHashtable(16);
        FunctionScope fscope = new FunctionScope(Globals.ScopeStack.Peek(), isMethod);
        Globals.ScopeStack.Push(fscope); //Give declarations a place to go while building AST

        try{
          formalParameters = new ArrayList();
          Context paramArrayContext = null;
          if (function == null){
            // get the formal parameters
            if (JSToken.LeftParen != this.currentToken.token)
              ReportError(JSError.NoLeftParen);
            GetNextToken();
            // create the list of arguments and update the context
            while (JSToken.RightParen != this.currentToken.token){
              if (paramArrayContext != null){
                ReportError(JSError.ParamListNotLast, paramArrayContext, true);
                paramArrayContext = null;
              }
              String id = null;
              TypeExpression typeExpr = null;
              this.noSkipTokenSet.Add(NoSkipTokenSet.s_FunctionDeclNoSkipTokenSet);
              try{
                if (JSToken.ParamArray == this.currentToken.token){
                  paramArrayContext = this.currentToken.Clone();
                  GetNextToken();
                }
                if (JSToken.Identifier != this.currentToken.token && (id = JSKeyword.CanBeIdentifier(this.currentToken.token)) == null){
                  if (JSToken.LeftCurly == this.currentToken.token){
                    ReportError(JSError.NoRightParen);
                    break;
                  }else if (JSToken.Comma == this.currentToken.token){
                    // We're missing an argument (or previous argument was malformed and
                    // we skipped to the comma.)  Keep trying to parse the argument list --
                    // we will skip the comma below.
                    ReportError(JSError.SyntaxError, true);
                  }else{
                    ReportError(JSError.SyntaxError, true);
                    SkipTokensAndThrow();
                  }
                }else{
                  if (null == id)
                    id = this.scanner.GetIdentifier();
                  else
                    ForceReportInfo(JSError.KeywordUsedAsIdentifier);
                  Context paramCtx = this.currentToken.Clone();
                  GetNextToken();
                  if (JSToken.Colon == this.currentToken.token){
                    typeExpr = ParseTypeExpression();
                    if (null != typeExpr)
                      paramCtx.UpdateWith(typeExpr.context);
                  }
                  
                  
                  CustomAttributeList custAttrs = null;
                  if (paramArrayContext != null){
                    custAttrs = new CustomAttributeList(paramArrayContext);
                    custAttrs.Append(new CustomAttribute(paramArrayContext, new Lookup("...", paramArrayContext), new ASTList(null)));
                  }
                  formalParameters.Add(new ParameterDeclaration(paramCtx, id, typeExpr, custAttrs));
                }

                // got an arg, it should be either a ',' or ')'
                if (JSToken.RightParen == this.currentToken.token)
                  break;
                else if (JSToken.Comma != this.currentToken.token){
                  // deal with error in some "intelligent" way
                  if (JSToken.LeftCurly == this.currentToken.token){
                    ReportError(JSError.NoRightParen);
                    break;
                  }else{
                    if (JSToken.Identifier == this.currentToken.token && typeExpr == null){
                      // it's possible that the guy was writing the type in C/C++ style (i.e. int x)
                      ReportError(JSError.NoCommaOrTypeDefinitionError);
                    }else
                      ReportError(JSError.NoComma);
                  }
                }
                GetNextToken();
              }catch(RecoveryTokenException exc){
                if (IndexOfToken(NoSkipTokenSet.s_FunctionDeclNoSkipTokenSet, exc) == -1)
                  throw exc;
              }finally{
                this.noSkipTokenSet.Remove(NoSkipTokenSet.s_FunctionDeclNoSkipTokenSet);
              }
            }
            fncCtx.UpdateWith(this.currentToken);
            // if it is a getter/setter must have 0/1 arg only
            if (isGetter && formalParameters.Count != 0){
              ReportError(JSError.BadPropertyDeclaration, true);
              isGetter = false;
            }else if (isSetter && formalParameters.Count != 1){
              ReportError(JSError.BadPropertyDeclaration, true);
              isSetter = false;
            }
            GetNextToken();

            // check the return type
            if (JSToken.Colon == this.currentToken.token){
              if (isSetter)
                ReportError(JSError.SyntaxError);
              this.noSkipTokenSet.Add(NoSkipTokenSet.s_StartBlockNoSkipTokenSet);
              try{
                returnType = ParseTypeExpression();
              }catch(RecoveryTokenException exc){
                if (IndexOfToken(NoSkipTokenSet.s_StartBlockNoSkipTokenSet, exc) == -1){
                  exc._partiallyComputedNode = null;
                  throw exc;
                }else{
                  if (exc._partiallyComputedNode != null)
                    returnType = (TypeExpression)exc._partiallyComputedNode;
                }
              }finally{
                this.noSkipTokenSet.Remove(NoSkipTokenSet.s_StartBlockNoSkipTokenSet);
              }
              if (isSetter)
                returnType = null;
            }
          }else{ // function was passed in, this is an error condition
            function.GetParameters(formalParameters);
          }

          // read the function body of non-abstract functions.

          if (JSToken.LeftCurly != this.currentToken.token && (isAbstract || (isMethod && GuessIfAbstract()))){
            if (!isAbstract){
              isAbstract = true;
              ReportError(JSError.ShouldBeAbstract, fncCtx, true);
            }
            body = new Block(this.currentToken.Clone());
          }else{
            if (JSToken.LeftCurly != this.currentToken.token)
              ReportError(JSError.NoLeftCurly, true);
            else if (isAbstract)
              ReportError(JSError.AbstractWithBody, fncCtx, true);

            this.blockType.Add(BlockType.Block);
            this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockNoSkipTokenSet);
            this.noSkipTokenSet.Add(NoSkipTokenSet.s_StartStatementNoSkipTokenSet);
            try{
              // parse the block locally to get the exact end of function
              body = new Block(this.currentToken.Clone());
              GetNextToken();

              while (JSToken.RightCurly != this.currentToken.token){
                try{
                  body.Append(ParseStatement());
                }catch(RecoveryTokenException exc){
                  if (exc._partiallyComputedNode != null){
                    body.Append(exc._partiallyComputedNode);
                  }
                  if (IndexOfToken(NoSkipTokenSet.s_StartStatementNoSkipTokenSet, exc) == -1)
                    throw exc;
                }
              }

              body.context.UpdateWith(this.currentToken);
              fncCtx.UpdateWith(this.currentToken);
            }catch(RecoveryTokenException exc){
              if (IndexOfToken(NoSkipTokenSet.s_BlockNoSkipTokenSet, exc) == -1){
                Globals.ScopeStack.Pop(); //Pop current scope so that FunctionDeclaration sees proper scope stack
                try{
                  ParameterDeclaration[] foParameters = new ParameterDeclaration[formalParameters.Count]; formalParameters.CopyTo(foParameters);
                  if (inExpression)
                    exc._partiallyComputedNode =
                      new FunctionExpression(fncCtx, name, foParameters, returnType, body, fscope, visibilitySpec);
                  else
                    exc._partiallyComputedNode =
                      new FunctionDeclaration(fncCtx, interfaceName, name, foParameters, returnType, body, fscope, visibilitySpec,
                      isMethod, isGetter, isSetter, isAbstract, isFinal, customAttributes);
                  if (customAttributes != null) customAttributes.SetTarget(exc._partiallyComputedNode);
                }finally{
                  Globals.ScopeStack.Push(fscope); //Push it back so that the next finally can pop it
                }
                throw exc;
              }
            }finally{
              this.blockType.RemoveAt(this.blockType.Count - 1);
              this.noSkipTokenSet.Remove(NoSkipTokenSet.s_StartStatementNoSkipTokenSet);
              this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockNoSkipTokenSet);
            }

            GetNextToken();
          }
        }finally{
          // restore state
          this.blockType = blockType;
          this.labelTable = labelTable;
          Globals.ScopeStack.Pop();
        }

        ParameterDeclaration[] fParameters = new ParameterDeclaration[formalParameters.Count]; formalParameters.CopyTo(fParameters);
        AST func;
        if (inExpression)
          func = new FunctionExpression(fncCtx, name, fParameters, returnType, body, fscope, visibilitySpec);
        else
          func = new FunctionDeclaration(fncCtx, interfaceName, name, fParameters, returnType, body, fscope, visibilitySpec,
                                         isMethod, isGetter, isSetter, isAbstract, isFinal, customAttributes);

        if (customAttributes != null) customAttributes.SetTarget(func);
        return func;

      }
        private AST MemberExpression(AST expression, ArrayList newContexts, out bool canBeQualid, ref bool canBeAttribute)
        {
            AST ast;
            bool flag = false;
            canBeQualid = true;
        Label_0005:
            this.noSkipTokenSet.Add(NoSkipTokenSet.s_MemberExprNoSkipTokenSet);
            try
            {
                try
                {
                    ASTList list;
                    ConstantWrapper wrapper;
                    switch (this.currentToken.token)
                    {
                        case JSToken.LeftParen:
                            if (!flag)
                            {
                                break;
                            }
                            canBeAttribute = false;
                            goto Label_0048;

                        case JSToken.LeftBracket:
                            canBeQualid = false;
                            canBeAttribute = false;
                            this.noSkipTokenSet.Add(NoSkipTokenSet.s_BracketToken);
                            try
                            {
                                list = this.ParseExpressionList(JSToken.RightBracket);
                            }
                            catch (RecoveryTokenException exception3)
                            {
                                if (this.IndexOfToken(NoSkipTokenSet.s_BracketToken, exception3) == -1)
                                {
                                    if (exception3._partiallyComputedNode != null)
                                    {
                                        exception3._partiallyComputedNode = new Call(expression.context.CombineWith(this.currentToken.Clone()), expression, (ASTList) exception3._partiallyComputedNode, true);
                                    }
                                    else
                                    {
                                        exception3._partiallyComputedNode = expression;
                                    }
                                    throw exception3;
                                }
                                list = (ASTList) exception3._partiallyComputedNode;
                            }
                            finally
                            {
                                this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BracketToken);
                            }
                            expression = new Call(expression.context.CombineWith(this.currentToken.Clone()), expression, list, true);
                            if ((newContexts != null) && (newContexts.Count > 0))
                            {
                                ((Context) newContexts[newContexts.Count - 1]).UpdateWith(expression.context);
                                expression.context = (Context) newContexts[newContexts.Count - 1];
                                ((Call) expression).isConstructor = true;
                                newContexts.RemoveAt(newContexts.Count - 1);
                            }
                            this.GetNextToken();
                            goto Label_0005;

                        case JSToken.AccessField:
                        {
                            if (flag)
                            {
                                canBeAttribute = false;
                            }
                            wrapper = null;
                            this.GetNextToken();
                            if (JSToken.Identifier == this.currentToken.token)
                            {
                                goto Label_03EF;
                            }
                            string str2 = JSKeyword.CanBeIdentifier(this.currentToken.token);
                            if (str2 != null)
                            {
                                this.ForceReportInfo(JSError.KeywordUsedAsIdentifier);
                                wrapper = new ConstantWrapper(str2, this.currentToken.Clone());
                            }
                            else
                            {
                                this.ReportError(JSError.NoIdentifier);
                                this.SkipTokensAndThrow(expression);
                            }
                            goto Label_040C;
                        }
                        default:
                            if (newContexts != null)
                            {
                                while (newContexts.Count > 0)
                                {
                                    ((Context) newContexts[newContexts.Count - 1]).UpdateWith(expression.context);
                                    expression = new Call((Context) newContexts[newContexts.Count - 1], expression, new ASTList(this.CurrentPositionContext()), false);
                                    ((Call) expression).isConstructor = true;
                                    newContexts.RemoveAt(newContexts.Count - 1);
                                }
                            }
                            return expression;
                    }
                    flag = true;
                Label_0048:
                    canBeQualid = false;
                    list = null;
                    RecoveryTokenException exception = null;
                    this.noSkipTokenSet.Add(NoSkipTokenSet.s_ParenToken);
                    try
                    {
                        list = this.ParseExpressionList(JSToken.RightParen);
                    }
                    catch (RecoveryTokenException exception2)
                    {
                        list = (ASTList) exception2._partiallyComputedNode;
                        if (this.IndexOfToken(NoSkipTokenSet.s_ParenToken, exception2) == -1)
                        {
                            exception = exception2;
                        }
                    }
                    finally
                    {
                        this.noSkipTokenSet.Remove(NoSkipTokenSet.s_ParenToken);
                    }
                    if (expression is Lookup)
                    {
                        string str = expression.ToString();
                        if (str.Equals("eval"))
                        {
                            expression.context.UpdateWith(list.context);
                            if (list.count == 1)
                            {
                                expression = new Eval(expression.context, list[0], null);
                            }
                            else if (list.count > 1)
                            {
                                expression = new Eval(expression.context, list[0], list[1]);
                            }
                            else
                            {
                                expression = new Eval(expression.context, new ConstantWrapper("", this.CurrentPositionContext()), null);
                            }
                            canBeAttribute = false;
                        }
                        else if (this.Globals.engine.doPrint && str.Equals("print"))
                        {
                            expression.context.UpdateWith(list.context);
                            expression = new Print(expression.context, list);
                            canBeAttribute = false;
                        }
                        else
                        {
                            expression = new Call(expression.context.CombineWith(list.context), expression, list, false);
                        }
                    }
                    else
                    {
                        expression = new Call(expression.context.CombineWith(list.context), expression, list, false);
                    }
                    if ((newContexts != null) && (newContexts.Count > 0))
                    {
                        ((Context) newContexts[newContexts.Count - 1]).UpdateWith(expression.context);
                        if (expression is Call)
                        {
                            expression.context = (Context) newContexts[newContexts.Count - 1];
                        }
                        else
                        {
                            expression = new Call((Context) newContexts[newContexts.Count - 1], expression, new ASTList(this.CurrentPositionContext()), false);
                        }
                        ((Call) expression).isConstructor = true;
                        newContexts.RemoveAt(newContexts.Count - 1);
                    }
                    if (exception != null)
                    {
                        exception._partiallyComputedNode = expression;
                        throw exception;
                    }
                    this.GetNextToken();
                    goto Label_0005;
                Label_03EF:
                    wrapper = new ConstantWrapper(this.scanner.GetIdentifier(), this.currentToken.Clone());
                Label_040C:
                    this.GetNextToken();
                    expression = new Member(expression.context.CombineWith(wrapper.context), expression, wrapper);
                }
                catch (RecoveryTokenException exception4)
                {
                    if (this.IndexOfToken(NoSkipTokenSet.s_MemberExprNoSkipTokenSet, exception4) == -1)
                    {
                        throw exception4;
                    }
                    expression = exception4._partiallyComputedNode;
                }
                goto Label_0005;
            }
            finally
            {
                this.noSkipTokenSet.Remove(NoSkipTokenSet.s_MemberExprNoSkipTokenSet);
            }
            return ast;
        }
 private AST ParseFunction(FieldAttributes visibilitySpec, bool inExpression, Context fncCtx, bool isMethod, bool isAbstract, bool isFinal, bool isInterface, CustomAttributeList customAttributes, Call function)
 {
     AST ast2;
     if (this.demandFullTrustOnFunctionCreation)
     {
         new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
     }
     IdentifierLiteral id = null;
     AST rootObject = null;
     ArrayList parameters = null;
     TypeExpression expression = null;
     Block body = null;
     bool isGetter = false;
     bool isSetter = false;
     if (function == null)
     {
         this.GetNextToken();
         if (isMethod)
         {
             if (JSToken.Get == this.currentToken.token)
             {
                 isGetter = true;
                 this.GetNextToken();
             }
             else if (JSToken.Set == this.currentToken.token)
             {
                 isSetter = true;
                 this.GetNextToken();
             }
         }
         if (JSToken.Identifier == this.currentToken.token)
         {
             id = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone());
             this.GetNextToken();
             if (JSToken.AccessField == this.currentToken.token)
             {
                 if (isInterface)
                 {
                     this.ReportError(JSError.SyntaxError, true);
                 }
                 this.GetNextToken();
                 if (JSToken.Identifier == this.currentToken.token)
                 {
                     rootObject = new Lookup(id.context);
                     id = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone());
                     this.GetNextToken();
                     while (JSToken.AccessField == this.currentToken.token)
                     {
                         this.GetNextToken();
                         if (JSToken.Identifier == this.currentToken.token)
                         {
                             rootObject = new Member(rootObject.context.CombineWith(this.currentToken), rootObject, new ConstantWrapper(id.ToString(), id.context));
                             id = new IdentifierLiteral(this.scanner.GetIdentifier(), this.currentToken.Clone());
                             this.GetNextToken();
                         }
                         else
                         {
                             this.ReportError(JSError.NoIdentifier, true);
                         }
                     }
                 }
                 else
                 {
                     this.ReportError(JSError.NoIdentifier, true);
                 }
             }
         }
         else
         {
             string identifier = JSKeyword.CanBeIdentifier(this.currentToken.token);
             if (identifier != null)
             {
                 this.ForceReportInfo(JSError.KeywordUsedAsIdentifier, isMethod);
                 id = new IdentifierLiteral(identifier, this.currentToken.Clone());
                 this.GetNextToken();
             }
             else
             {
                 if (!inExpression)
                 {
                     identifier = this.currentToken.GetCode();
                     this.ReportError(JSError.NoIdentifier, true);
                     this.GetNextToken();
                 }
                 else
                 {
                     identifier = "";
                 }
                 id = new IdentifierLiteral(identifier, this.CurrentPositionContext());
             }
         }
     }
     else
     {
         id = function.GetName();
     }
     ArrayList blockType = this.blockType;
     this.blockType = new ArrayList(0x10);
     SimpleHashtable labelTable = this.labelTable;
     this.labelTable = new SimpleHashtable(0x10);
     FunctionScope item = new FunctionScope(this.Globals.ScopeStack.Peek(), isMethod);
     this.Globals.ScopeStack.Push(item);
     try
     {
         parameters = new ArrayList();
         Context context = null;
         if (function == null)
         {
             if (JSToken.LeftParen != this.currentToken.token)
             {
                 this.ReportError(JSError.NoLeftParen);
             }
             this.GetNextToken();
             while (JSToken.RightParen != this.currentToken.token)
             {
                 if (context != null)
                 {
                     this.ReportError(JSError.ParamListNotLast, context, true);
                     context = null;
                 }
                 string str2 = null;
                 TypeExpression type = null;
                 this.noSkipTokenSet.Add(NoSkipTokenSet.s_FunctionDeclNoSkipTokenSet);
                 try
                 {
                     try
                     {
                         if (JSToken.ParamArray == this.currentToken.token)
                         {
                             context = this.currentToken.Clone();
                             this.GetNextToken();
                         }
                         if ((JSToken.Identifier != this.currentToken.token) && ((str2 = JSKeyword.CanBeIdentifier(this.currentToken.token)) == null))
                         {
                             if (JSToken.LeftCurly == this.currentToken.token)
                             {
                                 this.ReportError(JSError.NoRightParen);
                                 break;
                             }
                             if (JSToken.Comma == this.currentToken.token)
                             {
                                 this.ReportError(JSError.SyntaxError, true);
                             }
                             else
                             {
                                 this.ReportError(JSError.SyntaxError, true);
                                 this.SkipTokensAndThrow();
                             }
                         }
                         else
                         {
                             if (str2 == null)
                             {
                                 str2 = this.scanner.GetIdentifier();
                             }
                             else
                             {
                                 this.ForceReportInfo(JSError.KeywordUsedAsIdentifier);
                             }
                             Context context2 = this.currentToken.Clone();
                             this.GetNextToken();
                             if (JSToken.Colon == this.currentToken.token)
                             {
                                 type = this.ParseTypeExpression();
                                 if (type != null)
                                 {
                                     context2.UpdateWith(type.context);
                                 }
                             }
                             CustomAttributeList list3 = null;
                             if (context != null)
                             {
                                 list3 = new CustomAttributeList(context);
                                 list3.Append(new Microsoft.JScript.CustomAttribute(context, new Lookup("...", context), new ASTList(null)));
                             }
                             parameters.Add(new ParameterDeclaration(context2, str2, type, list3));
                         }
                         if (JSToken.RightParen == this.currentToken.token)
                         {
                             break;
                         }
                         if (JSToken.Comma != this.currentToken.token)
                         {
                             if (JSToken.LeftCurly == this.currentToken.token)
                             {
                                 this.ReportError(JSError.NoRightParen);
                                 break;
                             }
                             if ((JSToken.Identifier == this.currentToken.token) && (type == null))
                             {
                                 this.ReportError(JSError.NoCommaOrTypeDefinitionError);
                             }
                             else
                             {
                                 this.ReportError(JSError.NoComma);
                             }
                         }
                         this.GetNextToken();
                     }
                     catch (RecoveryTokenException exception)
                     {
                         if (this.IndexOfToken(NoSkipTokenSet.s_FunctionDeclNoSkipTokenSet, exception) == -1)
                         {
                             throw exception;
                         }
                     }
                     continue;
                 }
                 finally
                 {
                     this.noSkipTokenSet.Remove(NoSkipTokenSet.s_FunctionDeclNoSkipTokenSet);
                 }
             }
             fncCtx.UpdateWith(this.currentToken);
             if (isGetter && (parameters.Count != 0))
             {
                 this.ReportError(JSError.BadPropertyDeclaration, true);
                 isGetter = false;
             }
             else if (isSetter && (parameters.Count != 1))
             {
                 this.ReportError(JSError.BadPropertyDeclaration, true);
                 isSetter = false;
             }
             this.GetNextToken();
             if (JSToken.Colon == this.currentToken.token)
             {
                 if (isSetter)
                 {
                     this.ReportError(JSError.SyntaxError);
                 }
                 this.noSkipTokenSet.Add(NoSkipTokenSet.s_StartBlockNoSkipTokenSet);
                 try
                 {
                     expression = this.ParseTypeExpression();
                 }
                 catch (RecoveryTokenException exception2)
                 {
                     if (this.IndexOfToken(NoSkipTokenSet.s_StartBlockNoSkipTokenSet, exception2) == -1)
                     {
                         exception2._partiallyComputedNode = null;
                         throw exception2;
                     }
                     if (exception2._partiallyComputedNode != null)
                     {
                         expression = (TypeExpression) exception2._partiallyComputedNode;
                     }
                 }
                 finally
                 {
                     this.noSkipTokenSet.Remove(NoSkipTokenSet.s_StartBlockNoSkipTokenSet);
                 }
                 if (isSetter)
                 {
                     expression = null;
                 }
             }
         }
         else
         {
             function.GetParameters(parameters);
         }
         if ((JSToken.LeftCurly != this.currentToken.token) && (isAbstract || (isMethod && this.GuessIfAbstract())))
         {
             if (!isAbstract)
             {
                 isAbstract = true;
                 this.ReportError(JSError.ShouldBeAbstract, fncCtx, true);
             }
             body = new Block(this.currentToken.Clone());
         }
         else
         {
             if (JSToken.LeftCurly != this.currentToken.token)
             {
                 this.ReportError(JSError.NoLeftCurly, true);
             }
             else if (isAbstract)
             {
                 this.ReportError(JSError.AbstractWithBody, fncCtx, true);
             }
             this.blockType.Add(BlockType.Block);
             this.noSkipTokenSet.Add(NoSkipTokenSet.s_BlockNoSkipTokenSet);
             this.noSkipTokenSet.Add(NoSkipTokenSet.s_StartStatementNoSkipTokenSet);
             try
             {
                 body = new Block(this.currentToken.Clone());
                 this.GetNextToken();
                 while (JSToken.RightCurly != this.currentToken.token)
                 {
                     try
                     {
                         body.Append(this.ParseStatement());
                         continue;
                     }
                     catch (RecoveryTokenException exception3)
                     {
                         if (exception3._partiallyComputedNode != null)
                         {
                             body.Append(exception3._partiallyComputedNode);
                         }
                         if (this.IndexOfToken(NoSkipTokenSet.s_StartStatementNoSkipTokenSet, exception3) == -1)
                         {
                             throw exception3;
                         }
                         continue;
                     }
                 }
                 body.context.UpdateWith(this.currentToken);
                 fncCtx.UpdateWith(this.currentToken);
             }
             catch (RecoveryTokenException exception4)
             {
                 if (this.IndexOfToken(NoSkipTokenSet.s_BlockNoSkipTokenSet, exception4) == -1)
                 {
                     this.Globals.ScopeStack.Pop();
                     try
                     {
                         ParameterDeclaration[] declarationArray = new ParameterDeclaration[parameters.Count];
                         parameters.CopyTo(declarationArray);
                         if (inExpression)
                         {
                             exception4._partiallyComputedNode = new FunctionExpression(fncCtx, id, declarationArray, expression, body, item, visibilitySpec);
                         }
                         else
                         {
                             exception4._partiallyComputedNode = new FunctionDeclaration(fncCtx, rootObject, id, declarationArray, expression, body, item, visibilitySpec, isMethod, isGetter, isSetter, isAbstract, isFinal, customAttributes);
                         }
                         if (customAttributes != null)
                         {
                             customAttributes.SetTarget(exception4._partiallyComputedNode);
                         }
                     }
                     finally
                     {
                         this.Globals.ScopeStack.Push(item);
                     }
                     throw exception4;
                 }
             }
             finally
             {
                 this.blockType.RemoveAt(this.blockType.Count - 1);
                 this.noSkipTokenSet.Remove(NoSkipTokenSet.s_StartStatementNoSkipTokenSet);
                 this.noSkipTokenSet.Remove(NoSkipTokenSet.s_BlockNoSkipTokenSet);
             }
             this.GetNextToken();
         }
     }
     finally
     {
         this.blockType = blockType;
         this.labelTable = labelTable;
         this.Globals.ScopeStack.Pop();
     }
     ParameterDeclaration[] array = new ParameterDeclaration[parameters.Count];
     parameters.CopyTo(array);
     if (inExpression)
     {
         ast2 = new FunctionExpression(fncCtx, id, array, expression, body, item, visibilitySpec);
     }
     else
     {
         ast2 = new FunctionDeclaration(fncCtx, rootObject, id, array, expression, body, item, visibilitySpec, isMethod, isGetter, isSetter, isAbstract, isFinal, customAttributes);
     }
     if (customAttributes != null)
     {
         customAttributes.SetTarget(ast2);
     }
     return ast2;
 }