Inheritance: AST, ICanModifyContext
Example #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]);
                    //
                }
            }
        }
Example #2
0
		internal void Add (VariableDeclaration varDecl)
		{
			var_decls.Add (varDecl);
		}
Example #3
0
        AST Variables(AST parent, bool in_for_init)
        {
            VariableStatement pn = new VariableStatement (parent, new Location (ts.SourceName, ts.LineNumber));
            bool first = true;
            decompiler.AddToken (Token.VAR);

            for (;;) {
                VariableDeclaration name;
                AST init = null;
                MustMatchToken (Token.NAME, "msg.bad.var");
                string s = ts.GetString;

                if (!first)
                    decompiler.AddToken (Token.COMMA);
                first = false;

                decompiler.AddName (s);
                name = new VariableDeclaration (parent, s, null, null, new Location (ts.SourceName, ts.LineNumber));

                // ommited check for argument hiding
                if (ts.MatchToken (Token.ASSIGN)) {
                    decompiler.AddToken (Token.ASSIGN);
                    init = AssignExpr (parent, in_for_init);
                    name.val = init;
                }
                pn.Add (name);

                if (!ts.MatchToken (Token.COMMA))
                    break;
            }
            return pn;
        }
Example #4
0
		internal static void AddMethodVarsUsedNested (string name, VariableDeclaration decl)
		{
			object contained = methods_with_vars_used_nested [name];
			if (contained == null)
				methods_with_vars_used_nested.Add (name, decl);
		}
Example #5
0
		internal static void AddMethodReferenceOutterScopeVar (string name, VariableDeclaration decl)
		{
			object contained = methods_with_outter_scope_refs [name];
			if (contained == null)
				methods_with_outter_scope_refs.Add (name, decl);
		}
Example #6
0
      //---------------------------------------------------------------------------------------
      // ParseIdentifierInitializer
      //
      //  Does the real work of parsing a single variable declaration.
      //  inToken is JSToken.In whenever the potential expression that initialize a variable
      //  cannot contain an 'in', as in the for statement. inToken is JSToken.None otherwise
      //---------------------------------------------------------------------------------------
      private AST ParseIdentifierInitializer(JSToken inToken,
                                                              FieldAttributes visibility,
                                                              CustomAttributeList customAttributes,
                                                              JSToken kind){
        Lookup id = null;
        TypeExpression typeExpr = null;
        AST assignmentExpr = null;
        RecoveryTokenException except = null;

        GetNextToken();
        if (JSToken.Identifier != this.currentToken.token){
          String identifier = JSKeyword.CanBeIdentifier(this.currentToken.token);
          if (null != identifier){
            ForceReportInfo(JSError.KeywordUsedAsIdentifier);
            id = new Lookup(identifier, this.currentToken.Clone());
          }else{
            // make up an identifier and keep going; life goes on...
            ReportError(JSError.NoIdentifier);
            id = new Lookup("#_Missing Identifier_#" + s_cDummyName++, CurrentPositionContext());
          }
        }else
          id = new Lookup(this.scanner.GetIdentifier(), this.currentToken.Clone());
        GetNextToken();
        Context context = id.context.Clone();

        this.noSkipTokenSet.Add(NoSkipTokenSet.s_VariableDeclNoSkipTokenSet);
        try{
          if (JSToken.Colon == this.currentToken.token){
            try{
              typeExpr = ParseTypeExpression();
            }catch(RecoveryTokenException exc){
              typeExpr = (TypeExpression)exc._partiallyComputedNode;
              throw exc;
            }finally{
              if (null != typeExpr)
                context.UpdateWith(typeExpr.context);
            }
          }
              
          if (JSToken.Assign == this.currentToken.token || JSToken.Equal == this.currentToken.token){
            if (JSToken.Equal == this.currentToken.token)
              ReportError(JSError.NoEqual, true);
            GetNextToken();
            try{
              assignmentExpr = ParseExpression(true, inToken);
            }catch(RecoveryTokenException exc){
              assignmentExpr = exc._partiallyComputedNode;
              throw exc;
            }finally{
              if (null != assignmentExpr)
                context.UpdateWith(assignmentExpr.context);
            }
          }
        }catch(RecoveryTokenException exc){
          // If the exception is in the vardecl no-skip set then we successfully
          // recovered to the end of the declaration and can just return
          // normally.  Otherwise we re-throw after constructing the partial result.  
          if (IndexOfToken(NoSkipTokenSet.s_VariableDeclNoSkipTokenSet, exc) == -1)
            except = exc;
        }finally{
          this.noSkipTokenSet.Remove(NoSkipTokenSet.s_VariableDeclNoSkipTokenSet);
        }

        AST result = null;
        if (JSToken.Var == kind)
          result = new VariableDeclaration(context, id, typeExpr, assignmentExpr, visibility, customAttributes);
        else{
          if (assignmentExpr == null)
            ForceReportInfo(JSError.NoEqual);
          result = new Constant(context, id, typeExpr, assignmentExpr, visibility, customAttributes);
        }
        if (customAttributes != null)
          customAttributes.SetTarget(result);
        if (null != except){
          except._partiallyComputedNode = result;
          throw except;
        }
        return result;
      }
 private AST ParseIdentifierInitializer(JSToken inToken, FieldAttributes visibility, CustomAttributeList customAttributes, JSToken kind)
 {
     Lookup identifier = null;
     TypeExpression type = null;
     AST initializer = null;
     RecoveryTokenException exception = null;
     this.GetNextToken();
     if (JSToken.Identifier != this.currentToken.token)
     {
         string name = JSKeyword.CanBeIdentifier(this.currentToken.token);
         if (name != null)
         {
             this.ForceReportInfo(JSError.KeywordUsedAsIdentifier);
             identifier = new Lookup(name, this.currentToken.Clone());
         }
         else
         {
             this.ReportError(JSError.NoIdentifier);
             identifier = new Lookup("#_Missing Identifier_#" + s_cDummyName++, this.CurrentPositionContext());
         }
     }
     else
     {
         identifier = new Lookup(this.scanner.GetIdentifier(), this.currentToken.Clone());
     }
     this.GetNextToken();
     Context context = identifier.context.Clone();
     this.noSkipTokenSet.Add(NoSkipTokenSet.s_VariableDeclNoSkipTokenSet);
     try
     {
         if (JSToken.Colon == this.currentToken.token)
         {
             try
             {
                 type = this.ParseTypeExpression();
             }
             catch (RecoveryTokenException exception2)
             {
                 type = (TypeExpression) exception2._partiallyComputedNode;
                 throw exception2;
             }
             finally
             {
                 if (type != null)
                 {
                     context.UpdateWith(type.context);
                 }
             }
         }
         if ((JSToken.Assign == this.currentToken.token) || (JSToken.Equal == this.currentToken.token))
         {
             if (JSToken.Equal == this.currentToken.token)
             {
                 this.ReportError(JSError.NoEqual, true);
             }
             this.GetNextToken();
             try
             {
                 initializer = this.ParseExpression(true, inToken);
             }
             catch (RecoveryTokenException exception3)
             {
                 initializer = exception3._partiallyComputedNode;
                 throw exception3;
             }
             finally
             {
                 if (initializer != null)
                 {
                     context.UpdateWith(initializer.context);
                 }
             }
         }
     }
     catch (RecoveryTokenException exception4)
     {
         if (this.IndexOfToken(NoSkipTokenSet.s_VariableDeclNoSkipTokenSet, exception4) == -1)
         {
             exception = exception4;
         }
     }
     finally
     {
         this.noSkipTokenSet.Remove(NoSkipTokenSet.s_VariableDeclNoSkipTokenSet);
     }
     AST target = null;
     if (JSToken.Var == kind)
     {
         target = new VariableDeclaration(context, identifier, type, initializer, visibility, customAttributes);
     }
     else
     {
         if (initializer == null)
         {
             this.ForceReportInfo(JSError.NoEqual);
         }
         target = new Constant(context, identifier, type, initializer, visibility, customAttributes);
     }
     if (customAttributes != null)
     {
         customAttributes.SetTarget(target);
     }
     if (exception != null)
     {
         exception._partiallyComputedNode = target;
         throw exception;
     }
     return target;
 }