~/bend-docscommunity

src/rules/suspicious/ring.bend checks

raw source on the hub · import 0xd96f2ab40f5df4925c42e96d0ba857ff/src/rules/suspicious/ring.bend as Ring

rule ring: a self-call replaces a binder with List.append of List.drop (or String.append / ++, or tail) by a constant count, passing it back in the binder's own parameter position. Each step copies that fixed window. Keep it in an Array and advance an index. A list the def matches and walks (as any scrutinee of a match) is variable-length input, a window dropped into another parameter's slot is not carried, and a one-shot trim is not a loop: all stay quiet. Growing an accumulator by append, with no drop of that same value, is concat. Laws and proofs do not run (a def with no type at all fills a law: it is a proof).

7 imports
import Base
import ../../src.bend as Src
import ../../finding.bend as F
import ../../syntax/lex.bend as Lex
import ../../syntax/tree.bend as Tree
import ../calls.bend as Calls
import ../../lazy/lazy.bend as Lazy

Definitions

def or_tok source · line 19 · raw

@aa:Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok> -> @+bb:Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok> -> Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok>

the first of two maybes

def is_num source · line 27 · raw

@nn:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> Bool

is the chain exactly one number?

def name_text source · line 35 · raw

@nn:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> String

the chain is exactly one lowercase name; its text, or empty

def win_name source · line 43 · raw

@nn:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> @+wins:List<&2, String> -> Bool

this argument is a window binder

def has_name source · line 48 · raw

@as:List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node> -> @+wins:List<&2, String> -> Bool

does any argument name the window?

def last_num source · line 57 · raw

@as:List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node> -> Bool

is the last argument a number?

def drop_ok source · line 67 · raw

@+tt:String -> @+as:List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node> -> @+wins:List<&2, String> -> Bool

a fixed drop or tail of a named window

def drop_tok source · line 73 · raw

@kk:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.TokKind -> @+tt:String -> @+line:U32 -> @+col:U32 -> @kids:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> @+wins:List<&2, String> -> Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok>

the callee token when this call is a fixed drop

def here_of source · line 84 · raw

@+open:Bool -> @kk:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.TokKind -> @+tt:String -> @+line:U32 -> @+col:U32 -> @kids:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> @+wins:List<&2, String> -> Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok>

the drop this call is, when the group is an application

def drop_in source · line 100 · raw

@nn:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> @+wins:List<&2, String> -> Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok>

a drop anywhere under the node

def receiver_is source · line 117 · raw

@+list:Bool -> @+str:Bool -> @+as:List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node> -> @+wins:List<&2, String> -> Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok>

which list an append extends

def receiver source · line 127 · raw

@+tt:String -> @kids:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> @+wins:List<&2, String> -> Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok>

the drop an append copies onto, when this call is List.append or String.append

def pp_found source · line 131 · raw

@+is_pp:Bool -> @seen:Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok> -> Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok>

a ++ whose left already dropped: that drop; otherwise nothing

def pp_seen source · line 141 · raw

@+is_pp:Bool -> @+seen:Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok> -> Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok>

the drop still in play after this operator (++ starts a new left side)

def call_recv source · line 149 · raw

@+open:Bool -> @+tt:String -> @kids:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> @+wins:List<&2, String> -> Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok>

an application's append-receiver drop; a bracket is not an application

def call_drop source · line 157 · raw

@+open:Bool -> @+kk:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.TokKind -> @+tt:String -> @+line:U32 -> @+col:U32 -> @+kids:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> @+wins:List<&2, String> -> Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok>

a drop this node itself is: the call when it is an application, else under a bracket

def plus_scan source · line 173 · raw

@nn:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> @+seen:Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok> -> @+wins:List<&2, String> -> Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok>

a drop then ++, or an append onto a drop, in this chain

def slide_at source · line 197 · raw

@mm:Maybe<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/lex.Tok> -> @+path:String -> List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>

a finding at the drop the scan found

def slide source · line 206 · raw

@aa:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> @+path:String -> @+wins:List<&2, String> -> List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>

a finding at the drop, when the argument slides a window

def slot_wins source · line 211 · raw

@+slot:String -> @+wins:List<&2, String> -> List<&2, String>

the windows an argument in this parameter's slot may slide: the parameter itself when it is a window, else none

def slides source · line 216 · raw

@as:List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node> -> @+params:List<&2, String> -> @+path:String -> @+wins:List<&2, String> -> List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>

every self-call argument that slides the window of its own slot (params, from the argument's position on)

def walk source · line 231 · raw

@nn:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> @+self:String -> @+params:List<&2, String> -> @+path:String -> @+wins:List<&2, String> -> List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>

every self-call's sliding arguments

def names_in source · line 254 · raw

@nn:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> @acc:List<&2, String> -> List<&2, String>

the top-level names of a chain, onto acc

def match_names source · line 264 · raw

@kids:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> @+acc:List<&2, String> -> List<&2, String>

every scrutinee of match a b ..:, onto acc (acc alone for any other chain)

def matched source · line 272 · raw

@nn:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> @+acc:List<&2, String> -> List<&2, String>

names the def matches, as any scrutinee: variable-length input, not a window

def windows.go source · line 287 · raw

@ps:List<&2, String> -> @+bad:List<&2, String> -> @+acc:List<&2, String> -> List<&2, String>

parameters that are not matched as input

def windows source · line 296 · raw

@sig:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> @body:0xd96f2ab40f5df4925c42e96d0ba857ff/src/syntax/tree.Node -> List<&2, String>

parameters that are not matched as input

def check.go source · line 299 · raw

@ds:List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/rules/calls.Def> -> @+path:String -> @acc:List<&2, List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>> -> List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>

def check source · line 310 · raw

@ss:0xd96f2ab40f5df4925c42e96d0ba857ff/src/src.Src -> List<&2, 0xd96f2ab40f5df4925c42e96d0ba857ff/src/finding.Finding>

the rule