From 6537c3af031e7933bb06e94db87f6eb1a412d26c Mon Sep 17 00:00:00 2001 From: Colin Date: Sun, 18 Mar 2012 22:08:55 +0000 Subject: [PATCH] Still experimenting with walking the JS ast --- Src/Javascript.TypeProvider/Parser.fs | 64 ++++++++++++++++++--------- 1 file changed, 44 insertions(+), 20 deletions(-) diff --git a/Src/Javascript.TypeProvider/Parser.fs b/Src/Javascript.TypeProvider/Parser.fs index 9bbb3466..c06a9f0a 100644 --- a/Src/Javascript.TypeProvider/Parser.fs +++ b/Src/Javascript.TypeProvider/Parser.fs @@ -9,9 +9,10 @@ open IronJS.Compiler module Parser = - type TypeDef = + type TypeDef = + | TypeDef of TypeDef list | Object of string * TypeDef list - | Method of string * seq + | Method of uint64 * string * seq let private walkAst (scopeData : Parser.ScopeData) (ast : Ast.Tree) = let scopeMap = @@ -20,42 +21,65 @@ module Parser = let methodDef n (scope : Ast.FunctionScope ref) = match scopeMap.TryFind (!scope).Id with - | Some(scopeEntry) -> Method(n, !scopeEntry.Parameters) - | None -> Method(n, []) + | Some(scopeEntry) -> + if not <| String.IsNullOrEmpty(n) + then Some <| Method(scopeEntry.Id, n, !scopeEntry.Parameters) + else None + | None -> None - let addObject t = function - | Object(n, defns) -> Object(n, t :: defns) - | a -> failwithf "Could not enhance %A with a function" a + let addToObject methd = + Option.bind (fun s -> + match s with + | TypeDef(ns) -> Some <| TypeDef(methd:: ns) + | Object(n, defns) -> Some <| Object(n, methd :: defns) + | a -> None) - let addFunc scopedName scope = function - | Object(n, defns) -> Object(n, (methodDef scopedName scope) :: defns) - | Method(_,_) -> methodDef scopedName scope + let addFunc scopedName scope t = + methodDef scopedName scope + |> Option.fold (fun s methd -> addToObject methd s) t + + let isPass = function + | Ast.Pass -> true + | _ -> false - let rec walk' (scopedName : string) (typedef : TypeDef) (tree : Ast.Tree) = + let rec walk' (scopedName : string) (typedef : TypeDef option) (tree : Ast.Tree) = match tree with | Ast.Function(_, scope, tree) -> walk' "" (addFunc scopedName scope typedef) tree | Ast.Property(tree, id) -> - printfn "Property %s" id walk' id typedef tree | Ast.Block(trees) -> - List.fold (walk' scopedName) typedef trees + List.fold (walk' scopedName) typedef (trees |> List.filter (not << isPass)) | Ast.Var(tree) -> (walk' scopedName typedef tree) - | Ast.Assign(Ast.Identifier(id), tree) -> - walk' id typedef tree + | Ast.Assign(treeL, treeR) -> + walk' scopedName (walk' scopedName typedef treeL) treeR | Ast.Object(properties) -> - Object(scopedName, List.map (fun (n,t) -> walk' (Method(n, []) t)) + if not <| String.IsNullOrEmpty(scopedName) + then + let props = + properties + |> List.choose (fun (n, t) -> + match t with + | Ast.Function(_, scope, tree) -> methodDef n scope + | _ -> None + ) + addToObject (Object(scopedName, props)) typedef + else typedef | Ast.Return(tree) -> walk' scopedName typedef tree | Ast.Identifier(id) -> - walk' id typedef (Ast.Null) - | Ast.Invoke(Ast.Function(_, scope, tree), treeF) -> - walk' scopedName (addFunc scope typedef) tree + walk' scopedName typedef (Ast.Pass) + | Ast.Invoke(tree, treeF) -> + List.fold (walk' scopedName) (walk' scopedName typedef tree) treeF | a -> + let (caseInfo, _) = Microsoft.FSharp.Reflection.FSharpValue.GetUnionFields(a, typeof) + printfn "%s" (caseInfo.Name) typedef - walk' "" (Object("", [])) ast + match walk' "" (Some <| TypeDef([])) ast with + | Some(TypeDef(v)) -> v |> List.rev + | _ -> [] let getTypeDefinition (filePath : string) = let (ast, scopeData) = Parser.parseFile (Env()) filePath