class Analyzer::Python::Bottle

Defined in:

analyzer/analyzers/python/bottle.cr

Constant Summary

BARE_DECORATOR_PATTERNS = BARE_DECORATORS.map do |deco_name| {deco_name, "@#{deco_name}", /^@#{deco_name}\([rf]?['"]([^'"]*)['"](.*)/, /@#{deco_name}\s*\(\s*[rf]?['"]([^'"]*)['"]/, /^\s*@#{deco_name}\s*\([^)]*\b(?:path|rule|uri)\s*=\s*[rf]?['"]([^'"]*)['"]/m} end

Per-line matchers, hoisted so they compile once: an interpolated regex literal recompiles (PCRE2 JIT) on every evaluation, and the bare-decorator patterns ran per decorator name on every source line. The .to_s expansion is byte-identical to the previous inline form, so matching behaviour is unchanged. Tuple shape: {deco_name, "@deco" guard, bare_re, original_line_re, keyword_path_re}

BARE_DECORATORS = ["route", "get", "post", "put", "delete", "patch", "head", "options"] of ::String
BOTTLE_INSTANCE_RE = /^(#{PYTHON_VAR_NAME_REGEX})(?::#{PYTHON_VAR_NAME_REGEX})?=(?:bottle\.)?Bottle\(/
DICT_ACCESSOR_PATTERNS = DICT_ACCESSORS.map do |accessor, param_type| {param_type, /request\.#{accessor}\.get\s*\(\s*['"]([^'"]+)['"]/, /request\.#{accessor}\s*\[\s*['"]([^'"]+)['"]\s*\]/, /request\.#{accessor}\.([A-Za-z_][A-Za-z0-9_]*)\b/} end

extract_request_params runs once per route and used to rebuild three PCRE2 patterns per accessor on every call. The accessor set is fixed, so precompile the access patterns once here. Tuple shape: {noir_param_type, get_re, bracket_re, attribute_re}

DICT_ACCESSORS = {"query" => "query", "forms" => "form", "json" => "json", "headers" => "header", "cookies" => "cookie"}

Bottle attributes whose parameter type is independent of HTTP method. Maps the Python accessor name on request.<name> to the noir param_type.

DICT_METHOD_NAMES = Set {"get", "getall", "getone", "items", "keys", "values", "pop"}

Attribute names on accessor objects that are not user parameters.

MOUNT_RE = /\b(#{PYTHON_VAR_NAME_REGEX})\.mount\s*\(\s*[rf]?['"]([^'"]*)['"]\s*,\s*(#{PYTHON_VAR_NAME_REGEX})/
PROGRAMMATIC_ROUTE_RE = /\b(#{PYTHON_VAR_NAME_REGEX})\.route\s*\((.*)\)\s*$/m

Instance Method Summary

Instance methods inherited from class Analyzer::Python::PythonEngine

build_callees_from(body : String, body_start_line : Int32, path : String, *, definition_base_path : String | Nil = nil, source : String | Nil = nil) : Array(Callee) build_callees_from, find_def_line(lines : Array(String), decorator_line : Int32) : Int32 | Nil find_def_line, find_imported_modules(app_base_path : String, file_path : String, content : String | Nil = nil) : Hash(String, Tuple(String, Int32)) find_imported_modules, find_imported_package(package_path : String, dotted_as_names : String) : Array(Tuple(String, String, Int32)) find_imported_package, find_json_params(codeblock_lines : Array(String), json_var_names : Array(String)) : Array(Param) find_json_params, join_until_python_call_closes(lines : Array(String), index : Int32, line : String) : String join_until_python_call_closes, parse_code_block(data : String | Array(String), after : Regex | Nil = nil) : String | Nil parse_code_block, parse_function_def(source_lines : Array(String), start_index : Int32) : FunctionDefinition | Nil parse_function_def, push_callees_from(endpoint : Endpoint, body : String, body_start_line : Int32, path : String, *, definition_base_path : String | Nil = nil, source : String | Nil = nil) : Nil push_callees_from, python_paren_delta(line : String) : Int32 python_paren_delta, python_signature_line_span(lines : Array(String)) : Int32 python_signature_line_span, return_literal_value(data : String) : String return_literal_value

Class methods inherited from class Analyzer::Python::PythonEngine

python_test_path?(path : String, base_path : String | Nil = nil) : Bool python_test_path?

Instance methods inherited from class Analyzer

analyze analyze, base_path : String base_path, base_paths : Array(String) base_paths, callees_needed? : Bool callees_needed?, logger : NoirLogger logger, parallel_analyze(files : Array(String), &block : String -> Nil) parallel_analyze, read_file_content(path : String) : String read_file_content, result : Array(Endpoint) result, url : String url

Constructor methods inherited from class Analyzer

new(options : Hash(String, YAML::Any)) new

Macros inherited from class Analyzer

define_getter_methods(names) define_getter_methods

Instance methods inherited from module FileHelper

all_files : Array(String) all_files, get_files_by_extension(extension : String) : Array(String) get_files_by_extension, get_files_by_prefix(prefix : String) : Array(String) get_files_by_prefix, get_files_by_prefix_and_extension(prefix : String, extension : String) : Array(String) get_files_by_prefix_and_extension, get_public_dir_files(base_path : String, folder : String) : Array(String) get_public_dir_files, get_public_files(base_path : String, anchors : Array(String) = ["shard.yml", "Gemfile"]) : Array(String) get_public_files

Instance Method Detail

def analyze #

[View source]