Analyzer::Scala::Cli
Inherits CliEndpointSupport < Analyzer < FileHelper < Reference < Object
Surfaces the command-line attack surface of Scala programs as cli://
endpoints: scopt/decline (options/args/subcommands), Scallop
(ScallopConf options/args/subcommands), com.twitter.app (flags), and
sys.env reads. Line-scan, merged by URL.
Each library is gated on its own distinct import/marker, and only that
library's regex family runs against the file. This matters because
Scallop's bare opt[T]("name") call is textually identical to scopt's
opt[T]("name") -- without per-library gating, scopt's extractor would
also fire on Scallop code and attach subcommand-only flags to the root
endpoint even though Scallop's own subcommand scoping correctly bound
them to the subcommand.
Constants
One precompiled Regex.union scan (PCRE2 JIT) replaces four separate
String#includes? scans of the same buffer -- Crystal's includes? is
not Boyer-Moore accelerated, so a single regex pass over lower is
cheaper than four. Equivalent to the OR-of-substrings it replaces
(union escapes each literal).
--- Scallop (org.rogach.scallop) -----------------------------------
opt[T]/trailArg[T] take an explicit name, or (via a Scallop macro)
infer it from the enclosing val when the name is omitted -- this is
a real, documented Scallop feature, unlike com.twitter.app's flag.
Subcommands are declared either as val x = (new )?Subcommand("name") { ... } or the idiomatic object x extends Subcommand("name") { ... }
shown in Scallop's own docs; both open their scope with a { on the
same line, closed via brace-depth tracking.
--- scopt / decline -----------------------------------------------
--- com.twitter.app --------------------------------------------------
flag[T]("name", ...) always requires an explicit name -- there is no
reflection/macro-based no-arg overload the way Scallop infers names
from a val, so only the explicitly-named form is extracted.
Class methods
Instance methods
Instance-side view of the same declaration. The per-file rescues live on
this base class, which has no way to name the analyzer that is running
inside them, so a skipped file could not be attributed to a tech.
Deriving it from analyzer_for keeps the name written exactly once.