public Cursor(ast.Node parent = default, @string name = default, ref ptr <iterator> iter = default, ast.Node node = default) { this.parent = parent; this.name = name; this.iter = iter; this.node = node; }
// updateDead puts unreachable "if" and "case" nodes into dead. private static void updateDead(ptr <types.Info> _addr_info, map <ast.Node, bool> dead, ast.Node node) { ref types.Info info = ref _addr_info.val;
// Apply traverses a syntax tree recursively, starting with root, // and calling pre and post for each node as described below. // Apply returns the syntax tree, possibly modified. // // If pre is not nil, it is called for each node before the node's // children are traversed (pre-order). If pre returns false, no // children are traversed, and post is not called for that node. // // If post is not nil, and a prior call of pre didn't return false, // post is called for each node after its children are traversed // (post-order). If post returns false, traversal is terminated and // Apply returns immediately. // // Only fields that refer to AST nodes are considered children; // i.e., token.Pos, Scopes, Objects, and fields of basic types // (strings, etc.) are ignored. // // Children are traversed in the order in which they appear in the // respective node's struct definition. A package's files are // traversed in the filenames' alphabetical order. // public static ast.Node Apply(ast.Node root, ApplyFunc pre, ApplyFunc post) => func((defer, panic, _) =>
// Both F1 and G1 should appear as functions. public static void F1(ast.Node _p0) { }
public @event(ast.Node node = default, ulong typ = default, long index = default) { this.node = node; this.typ = typ; this.index = index; }
public Function(@string name = default, types.Object @object = default, ref ptr <types.Selection> method = default, ref ptr <types.Signature> Signature = default, token.Pos pos = default, @string Synthetic = default, ast.Node syntax = default, ref ptr <Function> parent = default, ref ptr <Package> Pkg = default, ref ptr <Program> Prog = default, slice <ptr <Parameter> > Params = default, slice <ptr <FreeVar> > FreeVars = default, slice <ptr <Alloc> > Locals = default, slice <ptr <BasicBlock> > Blocks = default, ref ptr <BasicBlock> Recover = default, slice <ptr <Function> > AnonFuncs = default, slice <Instruction> referrers = default, ref ptr <BasicBlock> currentBlock = default, map <types.Object, Value> objects = default, slice <ptr <Alloc> > namedResults = default, ref ptr <targets> targets = default, map <ptr <ast.Object>, ptr <lblock> > lblocks = default) { this.name = name; this.@object = @object; this.method = method; this.Signature = Signature; this.pos = pos; this.Synthetic = Synthetic; this.syntax = syntax; this.parent = parent; this.Pkg = Pkg; this.Prog = Prog; this.Params = Params; this.FreeVars = FreeVars; this.Locals = Locals; this.Blocks = Blocks; this.Recover = Recover; this.AnonFuncs = AnonFuncs; this.referrers = referrers; this.currentBlock = currentBlock; this.objects = objects; this.namedResults = namedResults; this.targets = targets; this.lblocks = lblocks; }
private static long sourceLine(ast.Node n) { return(fset.Position(n.Pos()).Line); }
public SelectState(types.ChanDir Dir = default, Value Chan = default, Value Send = default, token.Pos Pos = default, ast.Node DebugNode = default) { this.Dir = Dir; this.Chan = Chan; this.Send = Send; this.Pos = Pos; this.DebugNode = DebugNode; }
// typeOf returns a distinct single-bit value that represents the type of n. // // Various implementations were benchmarked with BenchmarkNewInspector: // GOGC=off // - type switch 4.9-5.5ms 2.1ms // - binary search over a sorted list of types 5.5-5.9ms 2.5ms // - linear scan, frequency-ordered list 5.9-6.1ms 2.7ms // - linear scan, unordered list 6.4ms 2.7ms // - hash table 6.5ms 3.1ms // A perfect hash seemed like overkill. // // The compiler's switch statement is the clear winner // as it produces a binary tree in code, // with constant conditions and good branch prediction. // (Sadly it is the most verbose in source code.) // Binary search suffered from poor branch prediction. // private static ulong typeOf(ast.Node n) { // Fast path: nearly half of all nodes are identifiers. { ptr <ast.Ident> (_, ok) = n._ <ptr <ast.Ident> >(); if (ok) { return(1L << (int)(nIdent)); } // These cases include all nodes encountered by ast.Inspect. } // These cases include all nodes encountered by ast.Inspect. switch (n.type()) { case ptr <ast.ArrayType> _: return(1L << (int)(nArrayType)); break; case ptr <ast.AssignStmt> _: return(1L << (int)(nAssignStmt)); break; case ptr <ast.BadDecl> _: return(1L << (int)(nBadDecl)); break; case ptr <ast.BadExpr> _: return(1L << (int)(nBadExpr)); break; case ptr <ast.BadStmt> _: return(1L << (int)(nBadStmt)); break; case ptr <ast.BasicLit> _: return(1L << (int)(nBasicLit)); break; case ptr <ast.BinaryExpr> _: return(1L << (int)(nBinaryExpr)); break; case ptr <ast.BlockStmt> _: return(1L << (int)(nBlockStmt)); break; case ptr <ast.BranchStmt> _: return(1L << (int)(nBranchStmt)); break; case ptr <ast.CallExpr> _: return(1L << (int)(nCallExpr)); break; case ptr <ast.CaseClause> _: return(1L << (int)(nCaseClause)); break; case ptr <ast.ChanType> _: return(1L << (int)(nChanType)); break; case ptr <ast.CommClause> _: return(1L << (int)(nCommClause)); break; case ptr <ast.Comment> _: return(1L << (int)(nComment)); break; case ptr <ast.CommentGroup> _: return(1L << (int)(nCommentGroup)); break; case ptr <ast.CompositeLit> _: return(1L << (int)(nCompositeLit)); break; case ptr <ast.DeclStmt> _: return(1L << (int)(nDeclStmt)); break; case ptr <ast.DeferStmt> _: return(1L << (int)(nDeferStmt)); break; case ptr <ast.Ellipsis> _: return(1L << (int)(nEllipsis)); break; case ptr <ast.EmptyStmt> _: return(1L << (int)(nEmptyStmt)); break; case ptr <ast.ExprStmt> _: return(1L << (int)(nExprStmt)); break; case ptr <ast.Field> _: return(1L << (int)(nField)); break; case ptr <ast.FieldList> _: return(1L << (int)(nFieldList)); break; case ptr <ast.File> _: return(1L << (int)(nFile)); break; case ptr <ast.ForStmt> _: return(1L << (int)(nForStmt)); break; case ptr <ast.FuncDecl> _: return(1L << (int)(nFuncDecl)); break; case ptr <ast.FuncLit> _: return(1L << (int)(nFuncLit)); break; case ptr <ast.FuncType> _: return(1L << (int)(nFuncType)); break; case ptr <ast.GenDecl> _: return(1L << (int)(nGenDecl)); break; case ptr <ast.GoStmt> _: return(1L << (int)(nGoStmt)); break; case ptr <ast.Ident> _: return(1L << (int)(nIdent)); break; case ptr <ast.IfStmt> _: return(1L << (int)(nIfStmt)); break; case ptr <ast.ImportSpec> _: return(1L << (int)(nImportSpec)); break; case ptr <ast.IncDecStmt> _: return(1L << (int)(nIncDecStmt)); break; case ptr <ast.IndexExpr> _: return(1L << (int)(nIndexExpr)); break; case ptr <ast.InterfaceType> _: return(1L << (int)(nInterfaceType)); break; case ptr <ast.KeyValueExpr> _: return(1L << (int)(nKeyValueExpr)); break; case ptr <ast.LabeledStmt> _: return(1L << (int)(nLabeledStmt)); break; case ptr <ast.MapType> _: return(1L << (int)(nMapType)); break; case ptr <ast.Package> _: return(1L << (int)(nPackage)); break; case ptr <ast.ParenExpr> _: return(1L << (int)(nParenExpr)); break; case ptr <ast.RangeStmt> _: return(1L << (int)(nRangeStmt)); break; case ptr <ast.ReturnStmt> _: return(1L << (int)(nReturnStmt)); break; case ptr <ast.SelectStmt> _: return(1L << (int)(nSelectStmt)); break; case ptr <ast.SelectorExpr> _: return(1L << (int)(nSelectorExpr)); break; case ptr <ast.SendStmt> _: return(1L << (int)(nSendStmt)); break; case ptr <ast.SliceExpr> _: return(1L << (int)(nSliceExpr)); break; case ptr <ast.StarExpr> _: return(1L << (int)(nStarExpr)); break; case ptr <ast.StructType> _: return(1L << (int)(nStructType)); break; case ptr <ast.SwitchStmt> _: return(1L << (int)(nSwitchStmt)); break; case ptr <ast.TypeAssertExpr> _: return(1L << (int)(nTypeAssertExpr)); break; case ptr <ast.TypeSpec> _: return(1L << (int)(nTypeSpec)); break; case ptr <ast.TypeSwitchStmt> _: return(1L << (int)(nTypeSwitchStmt)); break; case ptr <ast.UnaryExpr> _: return(1L << (int)(nUnaryExpr)); break; case ptr <ast.ValueSpec> _: return(1L << (int)(nValueSpec)); break; } return(0L); }
private static ast.Visitor Visit(this simplifier s, ast.Node node) { switch (node.type()) { case ptr <ast.CompositeLit> n: var outer = n; ast.Expr keyType = default; ast.Expr eltType = default; switch (outer.Type.type()) { case ptr <ast.ArrayType> typ: eltType = typ.Elt; break; case ptr <ast.MapType> typ: keyType = typ.Key; eltType = typ.Value; break; } if (eltType != null) { reflect.Value ktyp = default; if (keyType != null) { ktyp = reflect.ValueOf(keyType); } var typ = reflect.ValueOf(eltType); foreach (var(i, x) in outer.Elts) { var px = _addr_outer.Elts[i]; // look at value of indexed/named elements { ptr <ast.KeyValueExpr> (t, ok) = x._ <ptr <ast.KeyValueExpr> >(); if (ok) { if (keyType != null) { s.simplifyLiteral(ktyp, keyType, t.Key, _addr_t.Key); } x = t.Value; px = _addr_t.Value; } } s.simplifyLiteral(typ, eltType, x, px); } // node was simplified - stop walk (there are no subnodes to simplify) return(null); } break; case ptr <ast.SliceExpr> n: if (n.Max != null) { // - 3-index slices always require the 2nd and 3rd index break; } { ptr <ast.Ident> (s, _) = n.X._ <ptr <ast.Ident> >(); if (s != null && s.Obj != null) { // the array/slice object is a single, resolved identifier { ptr <ast.CallExpr> (call, _) = n.High._ <ptr <ast.CallExpr> >(); if (call != null && len(call.Args) == 1L && !call.Ellipsis.IsValid()) { // the high expression is a function call with a single argument { ptr <ast.Ident> (fun, _) = call.Fun._ <ptr <ast.Ident> >(); if (fun != null && fun.Name == "len" && fun.Obj == null) { // the function called is "len" and it is not locally defined; and // because we don't have dot imports, it must be the predefined len() { ptr <ast.Ident> (arg, _) = call.Args[0L]._ <ptr <ast.Ident> >(); if (arg != null && arg.Obj == s.Obj) { // the len argument is the array/slice object n.High = null; } } } } } } } // Note: We could also simplify slice expressions of the form s[0:b] to s[:b] // but we leave them as is since sometimes we want to be very explicit // about the lower bound. // An example where the 0 helps: // x, y, z := b[0:2], b[2:4], b[4:6] // An example where it does not: // x, y := b[:n], b[n:] } // Note: We could also simplify slice expressions of the form s[0:b] to s[:b] // but we leave them as is since sometimes we want to be very explicit // about the lower bound. // An example where the 0 helps: // x, y, z := b[0:2], b[2:4], b[4:6] // An example where it does not: // x, y := b[:n], b[n:] break; case ptr <ast.RangeStmt> n: if (isBlank(n.Value)) { n.Value = null; } if (isBlank(n.Key) && n.Value == null) { n.Key = null; } break; } return(s); }
public Example(@string Name = default, @string Suffix = default, @string Doc = default, ast.Node Code = default, ref ptr <ast.File> Play = default, slice <ptr <ast.CommentGroup> > Comments = default, @string Output = default, bool Unordered = default, bool EmptyOutput = default, long Order = default) { this.Name = Name; this.Suffix = Suffix; this.Doc = Doc; this.Code = Code; this.Play = Play; this.Comments = Comments; this.Output = Output; this.Unordered = Unordered; this.EmptyOutput = EmptyOutput; this.Order = Order; }