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]); // } } }
internal void Add (VariableDeclaration varDecl) { var_decls.Add (varDecl); }
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; }
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); }
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); }
//--------------------------------------------------------------------------------------- // 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; }