Constants
ANY_BINDING_RE =
Regex.union(
SPRING_WEB_BIND_PACKAGE,
FEIGN_CLIENT_PACKAGE, "@
FeignClient",
SPRING_HTTP_EXCHANGE_PACKAGE, "@
HttpExchange", "@
GetExchange", "@
PostExchange", "@
PutExchange", "@
PatchExchange", "@
DeleteExchange", "
RouteLocatorBuilder", "
PredicateSpec", "org.springframework.cloud.gateway", "org.springframework.web.socket.config.annotation", "
WebSocketMessageBrokerConfigurer", "@
EnableWebSocketMessageBroker", "org.springframework.messaging.handler.annotation", "@
MessageMapping", "@
SubscribeMapping", "
ResourceHandlerRegistry", "add
ResourceHandler")
The OR of every marker the annotation branch keys off. A file that
misses this cannot set any of the individual flags, so the per-flag
scans only run for the handful of files that get past it.
CONVERTER_TARGET_RE = /\b(?:Formatter|Converter)\s*<\s*(?:[\w.]+\s*,\s*)?(?:[\w]+\.)*(\w+)\s*>/
implements Formatter<PetType> / Converter<String, PetType>: the target type.
CUSTOM_ENDPOINT_DEFAULT = "api.console.halo.run/v1alpha1"
CUSTOM_ENDPOINT_RE = /\bclass\s+\w+[^{;]*\bimplements\s+[^{;]*\bCustomEndpoint\b[^{;]*\{/
Halo mounts what a CustomEndpoint bean's endpoint() returns under
/apis/<group>/<version>, the pair its groupVersion() names (the
interface's default when the class does not override it).
CUSTOM_GROUP_VERSION_RE = /\bgroupVersion\s*\(\s*\)\s*\{[^}]*?(parseAPIVersion|new\s+GroupVersion)\s*\(/m
DISALLOWED_FIELDS_RE = /\bsetDisallowedFields\s*\(([^)]*)\)/
dataBinder.setDisallowedFields("id", "*.id") in an @InitBinder.
FEIGN_CLIENT_PACKAGE = "org.springframework.cloud.openfeign.FeignClient"
INJECTED_META_RE =
Regex.union(
Noir::TreeSitterJavaParameterExtractor::INJECTED_PARAM_ANNOTATIONS.map do |name| "@#{name}" end)
INTERFACE_OR_ABSTRACT_RE =
Regex.union("interface", "abstract")
collect_interface_route_index gates.
INTERFACE_ROUTE_MARKER_RE =
Regex.union(
SPRING_WEB_BIND_PACKAGE,
SPRING_HTTP_EXCHANGE_PACKAGE, "@
HttpExchange", "@
GetExchange", "@
PostExchange", "@
PutExchange", "@
PatchExchange", "@
DeleteExchange", "@
RequestMapping", "@
GetMapping", "@
PostMapping")
LAMBDA_RECEIVER_RE = /\A\(?\s*(?:[\w.<>]+\s+)?(\w+)\s*\)?\s*->/
MESSAGE_MAPPING_BINDING_RE =
Regex.union("org.springframework.messaging.handler.annotation", "@
MessageMapping", "@
SubscribeMapping")
META_ANNOTATION_RE =
Regex.union("@interface")
NEST_CALL_RE = /(?<![\w$])(?:(nest|andNest)|(?<=\.)path)\s*\(/
REGEX_ROUTE_CALL = /((?:andRoute|route)\s*\(|\.)\s*(?:RequestPredicates\.)?(GET|POST|DELETE|PUT|PATCH|HEAD|OPTIONS)\s*\(/
REGEX_ROUTER_CODE_BLOCK = /route\(\)?.*?\);/m
RESOURCE_HANDLER_BINDING_RE =
Regex.union("
ResourceHandlerRegistry", "add
ResourceHandler")
ROUTER_BLOCK_START_RE = /(?<![\w$])(?:route|nest)\s*\(/
Where a router statement starts: route( / route() and the
RouterFunctions.nest(path(...), route()...) form, whose prefix sits
before the route(.
SERVER_REQUEST_BODY_RE = /\b(\w+)\s*\.\s*(?:bodyToMono|bodyToFlux|body)\s*\(\s*([\w.]+)\s*\.\s*class\b/
SERVER_REQUEST_HEADER_RE = /\b(\w+)\s*\.\s*headers\s*\(\s*\)\s*\.\s*(?:firstHeader|header)\s*\(\s*"([^"]+)"/
SERVER_REQUEST_PARAM_RE = /\b(\w+)\s*\.\s*(query
Param|param)\s*\(\s*"([^"]+)"/
SPLIT_CONCAT_RULES =
Noir::TopLevelSplit::Rules.new(nest: (
Noir::TopLevelSplit::Nest::Paren |
Noir::TopLevelSplit::Nest::Bracket) |
Noir::TopLevelSplit::Nest::Brace, quotes: "\"", escape:
Noir::TopLevelSplit::Escape::InQuotes, strip: true, empties:
Noir::TopLevelSplit::Empties::DropAll, per_kind: false, clamp: true)
Rules::JAVA minus the single-quote quote style, and dropping EVERY
empty part rather than only a trailing one — the old body ended in
.map(&.strip).reject(&.empty?), so "a" + + "b" yielded two terms, not
three. Both matter to the caller, which concatenates the terms it gets
back into a route path. File-local because spring is the only splitter
with this combination.
SPRING_HTTP_EXCHANGE_PACKAGE = "org.springframework.web.service.annotation."
SPRING_INDEX_PRESCREEN_RE =
Regex.union("set
ApplicationDestinationPrefixes",
SPRING_WEB_BIND_PACKAGE)
SPRING_WEB_BIND_PACKAGE = "org.springframework.web.bind.annotation."
SPRING_WEB_BIND_RE =
Regex.union(
SPRING_WEB_BIND_PACKAGE)
STOMP_PREFIX_RE =
Regex.union("set
ApplicationDestinationPrefixes")
build_spring_indexes gate: neither index can want a file that
mentions neither marker.
WEBSOCKET_BINDING_RE =
Regex.union("org.springframework.web.socket.config.annotation", "
WebSocketMessageBrokerConfigurer", "@
EnableWebSocketMessageBroker")
Every content.includes?(...) below used to be its own Rabin-Karp
pass over the whole file. This analyzer asks ~30 such questions per
.java file across three walks, and on a monorepo the overwhelming
majority of files answer "no" to all of them. One precompiled
Regex.union (PCRE2 JIT, via content_matches?) is the same
predicate in a single pass — see the note on Analyzer#content_matches?.