local check_state = require "luacheck.check_state" local core_utils = require "luacheck.core_utils" local parse_inline_options = require "luacheck.stages.parse_inline_options" local parser = require "luacheck.parser" local stages = require "luacheck.stages" local utils = require "luacheck.utils" local inline_option_fields = utils.array_to_set(parse_inline_options.inline_option_fields) local function validate_fields(tables, per_code_fields) for _, t in ipairs(tables) do local fields_set if per_code_fields then if not t.code then error("Warning has no code", 0) end local warning_info = stages.warnings[t.code] if not warning_info then error("Unknown issue code " .. t.code, 0) end fields_set = warning_info.fields_set else fields_set = inline_option_fields end for field in pairs(t) do if not fields_set[field] then error("Unknown field " .. field .. " in " .. (per_code_fields and "issue with code " .. t.code or "inline option table"), 0) end end end end --- Checks source. -- Returns a table with results, with the following fields: -- `events`: array of issues and inline option events (options, push, or pop). -- `per_line_options`: map from line numbers to arrays of inline option events. -- `line_lengths`: map from line numbers to line lengths. -- `line_endings`: map from line numbers to "comment", "string", or `nil` base on -- whether the line ending is within a token. -- If `events` array contains a syntax error, the other fields are empty tables. local function check(source) local chstate = check_state.new(source) local ok, error_wrapper = utils.try(stages.run, chstate) local warnings, inline_options, line_lengths, line_endings if ok then warnings = chstate.warnings core_utils.sort_by_location(warnings) inline_options = chstate.inline_options line_lengths = chstate.line_lengths line_endings = chstate.line_endings else local err = error_wrapper.err if not utils.is_instance(err, parser.SyntaxError) then error(error_wrapper, 0) end local syntax_error = { code = "011", line = err.line, column = chstate:offset_to_column(err.line, err.offset), end_column = chstate:offset_to_column(err.line, err.end_offset), msg = err.msg } if err.prev_line then syntax_error.prev_line = err.prev_line syntax_error.prev_column = chstate:offset_to_column(err.prev_line, err.prev_offset) syntax_error.prev_end_column = chstate:offset_to_column(err.prev_line, err.prev_end_offset) end warnings = {syntax_error} inline_options = {} line_lengths = {} line_endings = {} end validate_fields(warnings, true) validate_fields(inline_options) return { warnings = warnings, inline_options = inline_options, line_lengths = line_lengths, line_endings = line_endings } end return check