pyvbaanalysis 2.2.0__tar.gz → 2.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/CHANGELOG.md +196 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/CONTRIBUTING.md +17 -1
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/PKG-INFO +1 -1
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/docs/api-reference.md +3 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/docs/diagnostics-catalogue.md +40 -6
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/docs/usage.md +13 -1
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/__init__.py +1 -1
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/call/call_context.py +4 -1
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/cli.py +36 -22
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/completion/member_access.py +363 -86
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/conditional/__init__.py +2 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/conditional/conditional_compilation.py +58 -29
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/constants/integer_constant_expression.py +23 -9
- pyvbaanalysis-2.3.0/pyvbaanalysis/data/access_host_model.json +1 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/data/diagnostic_influence_audit.json +511 -2
- pyvbaanalysis-2.3.0/pyvbaanalysis/data/excel_host_model.json +1 -0
- pyvbaanalysis-2.3.0/pyvbaanalysis/data/host_closed_types.json +646 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/data/manifest.json +79 -11
- pyvbaanalysis-2.3.0/pyvbaanalysis/data/powerpoint_host_model.json +1 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/data/rule_metadata.json +395 -2
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/data/vba_runtime_tables.json +1 -1
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/data/vbe_oracle_cases.json +1793 -0
- pyvbaanalysis-2.3.0/pyvbaanalysis/data/word_host_model.json +1 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/analyze_module.py +31 -8
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/argument_inference.py +73 -9
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/call_extraction.py +6 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/callable_signatures.py +37 -2
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/context.py +5 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/dataflow.py +146 -50
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/exprwalk.py +31 -30
- pyvbaanalysis-2.3.0/pyvbaanalysis/diagnostics/known_locals.py +274 -0
- pyvbaanalysis-2.3.0/pyvbaanalysis/diagnostics/module_analysis.py +106 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/registry.py +48 -5
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/arrays.py +572 -86
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/assignments.py +176 -15
- pyvbaanalysis-2.3.0/pyvbaanalysis/diagnostics/rules/collection_state.py +399 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/control_flow.py +104 -81
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/dead_code.py +85 -67
- pyvbaanalysis-2.3.0/pyvbaanalysis/diagnostics/rules/declaration_forms.py +211 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/declarations.py +116 -46
- pyvbaanalysis-2.3.0/pyvbaanalysis/diagnostics/rules/directive_forms.py +105 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/duplicates.py +38 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/expressions.py +398 -23
- pyvbaanalysis-2.3.0/pyvbaanalysis/diagnostics/rules/file_statements.py +397 -0
- pyvbaanalysis-2.3.0/pyvbaanalysis/diagnostics/rules/handler_flow.py +345 -0
- pyvbaanalysis-2.3.0/pyvbaanalysis/diagnostics/rules/host_arguments.py +749 -0
- pyvbaanalysis-2.3.0/pyvbaanalysis/diagnostics/rules/implements_members.py +275 -0
- pyvbaanalysis-2.3.0/pyvbaanalysis/diagnostics/rules/late_bound_members.py +234 -0
- pyvbaanalysis-2.3.0/pyvbaanalysis/diagnostics/rules/line_continuations.py +127 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/module_kind.py +28 -0
- pyvbaanalysis-2.3.0/pyvbaanalysis/diagnostics/rules/numeric_literals.py +277 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/object_state.py +160 -17
- pyvbaanalysis-2.3.0/pyvbaanalysis/diagnostics/rules/overflow.py +1025 -0
- pyvbaanalysis-2.3.0/pyvbaanalysis/diagnostics/rules/runtime_values.py +964 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/shared.py +27 -25
- pyvbaanalysis-2.3.0/pyvbaanalysis/diagnostics/rules/statement_forms.py +190 -0
- pyvbaanalysis-2.3.0/pyvbaanalysis/diagnostics/rules/stray_tokens.py +162 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/type_of_is.py +126 -22
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/undeclared.py +90 -10
- pyvbaanalysis-2.3.0/pyvbaanalysis/diagnostics/rules/variant_values.py +189 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/walker.py +18 -22
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/flow/procedure_labels.py +22 -11
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/flow/procedure_unstructured.py +6 -13
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/host/__init__.py +2 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/host/host_model.py +13 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/host/type_extensibility.py +36 -12
- pyvbaanalysis-2.3.0/pyvbaanalysis/js_compat.py +111 -0
- pyvbaanalysis-2.3.0/pyvbaanalysis/lexer/contextual_keywords.py +179 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/lexer/keyword_table.py +13 -3
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/lexer/stripped_lines.py +11 -8
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/lexer/token_helpers.py +33 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/lexer/token_kinds.py +12 -2
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/lexer/tokenize.py +93 -16
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/lexer/trivia.py +15 -9
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/parser/nodes.py +62 -1
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/parser/parse_expression.py +15 -8
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/parser/parse_module.py +245 -41
- pyvbaanalysis-2.3.0/pyvbaanalysis/parser/parser_state.py +186 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/reader/vbe_module.py +19 -5
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/runtime/vba_runtime.py +12 -1
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/symbols/build_module_symbols.py +3 -7
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/symbols/name_resolution.py +25 -6
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/symbols/project_index.py +34 -6
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/symbols/symbol_model.py +5 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/types/type_inference.py +9 -5
- pyvbaanalysis-2.3.0/tests/test_analyzer_lexes_module_once.py +52 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_cli.py +60 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_conditional_arms.py +3 -2
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_dataflow.py +16 -0
- pyvbaanalysis-2.3.0/tests/test_deep_nesting.py +171 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_diagnostics_engine.py +3 -1
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_evidence.py +2 -2
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_host_libraries.py +3 -1
- pyvbaanalysis-2.3.0/tests/test_member_access_chains.py +176 -0
- pyvbaanalysis-2.3.0/tests/test_module_analysis.py +122 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_reader.py +20 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_registry_parity.py +12 -4
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rule_metadata.py +5 -5
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_argument_types.py +9 -2
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_assignments_types.py +49 -1
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_control_flow.py +8 -3
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_declarations.py +3 -1
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_property_setter_value_parameters.py +10 -12
- pyvbaanalysis-2.3.0/tests/test_upstream_sync_10_12_0.py +721 -0
- pyvbaanalysis-2.3.0/tests/test_upstream_sync_10_13_0.py +45 -0
- pyvbaanalysis-2.3.0/tests/test_upstream_sync_10_14_0.py +277 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_upstream_sync_10_6_0.py +3 -3
- pyvbaanalysis-2.3.0/tests/test_upstream_sync_10_7_1.py +351 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tools/extract_host_model.mjs +18 -6
- pyvbaanalysis-2.2.0/pyvbaanalysis/data/access_host_model.json +0 -1
- pyvbaanalysis-2.2.0/pyvbaanalysis/data/excel_closed_types.json +0 -31
- pyvbaanalysis-2.2.0/pyvbaanalysis/data/excel_host_model.json +0 -1
- pyvbaanalysis-2.2.0/pyvbaanalysis/data/powerpoint_host_model.json +0 -1
- pyvbaanalysis-2.2.0/pyvbaanalysis/data/word_host_model.json +0 -1
- pyvbaanalysis-2.2.0/pyvbaanalysis/diagnostics/rules/numeric_literals.py +0 -49
- pyvbaanalysis-2.2.0/pyvbaanalysis/diagnostics/rules/runtime_values.py +0 -384
- pyvbaanalysis-2.2.0/pyvbaanalysis/parser/parser_state.py +0 -110
- pyvbaanalysis-2.2.0/tests/test_member_access_chains.py +0 -45
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/.gitattributes +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/.github/dependabot.yml +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/.github/workflows/ci.yml +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/.github/workflows/publish.yml +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/.gitignore +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/LICENSE +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/README.md +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyproject.toml +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/__main__.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/call/__init__.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/completion/__init__.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/completion/cursor_context.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/completion/event_handlers.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/completion/type_completion.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/constants/__init__.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/data/event_definitions.json +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/data/msforms_members.json +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/data/vb6_host_model.json +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/__init__.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/const_expr.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/inline_suppression.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/model.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rule_metadata.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/__init__.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/argument_shape.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/argument_types.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/binary_operand_scalar.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/call_arity.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/doc_comments.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/late_binding.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/lexical.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/missing_reference.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/diagnostics/rules/parameter_defaults.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/docs/__init__.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/docs/doc_comment.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/evidence.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/flow/__init__.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/host/host_libraries.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/host/host_registry.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/host/msforms.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/identity_cache.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/lexer/__init__.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/parser/__init__.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/parser/fixed_length_string.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/parser/type_declaration_suffix.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/project.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/py.typed +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/reader/__init__.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/reader/loose_file.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/reader/workbook.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/references/__init__.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/references/reference_kinds.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/runtime/__init__.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/symbols/__init__.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/symbols/user_form_controls.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/types/__init__.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/pyvbaanalysis/types/type_names.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/conftest.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/oracle_support.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_conditional_compilation.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_host_model.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_host_seam.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_inline_suppression.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_integer_constant_expression.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_language_matrix.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_lexer.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_parser.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_project.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_project_index.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_public_api.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_real_world_false_positives.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_reference_kinds.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_ambiguous_enum_member.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_argument_shape.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_arrays.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_assignments.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_binary_operand_scalar.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_call_arity.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_dead_code.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_division_by_zero.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_doc_comments.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_duplicates.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_event_handler_module_scope.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_expression_calls.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_expressions.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_invalid_as_type_names.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_is_operator_non_object.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_late_binding.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_lexical.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_member_not_found.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_missing_reference.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_module_kind.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_numeric_literals.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_object_state.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_parameter_defaults.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_runtime_values.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_scalar_and_foreach.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_type_of_is.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_typeof_is_always_false.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_rules_undeclared.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_runtime_tables.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_statement_token_derivation.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_stripped_lines.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_symbols.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_token_helpers.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_type_completion.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_type_names.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_upstream_sync_10_5_0.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tests/test_upstream_sync_6_1_2.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tools/extract_event_definitions.mjs +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tools/extract_rule_metadata.mjs +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tools/extract_runtime_tables.mjs +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tools/generate_diagnostics_catalogue.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tools/generate_manifest.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tools/oracle/build_combining_mark_probe.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tools/pin_analyzer.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tools/vendor_data.py +0 -0
- {pyvbaanalysis-2.2.0 → pyvbaanalysis-2.3.0}/tools/xlide_source.mjs +0 -0
|
@@ -5,6 +5,202 @@ All notable changes to pyVBAanalysis are recorded here. The format follows
|
|
|
5
5
|
follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html): a minor version
|
|
6
6
|
per milestone.
|
|
7
7
|
|
|
8
|
+
## 2.3.0 - 2026-09-26
|
|
9
|
+
|
|
10
|
+
Sync to XLIDE 10.14.0 (commit 110c76e), from 10.7.1. Upstream measured the
|
|
11
|
+
analyzer against Excel, Word and PowerPoint 16.0 (build 20326) through
|
|
12
|
+
pyVBAharness and answered each finding (XLIDE issues #96 to #148): 34 new
|
|
13
|
+
diagnostics, 19 of them runtime errors in code the VBE compiles, and false
|
|
14
|
+
positives removed on code that compiles and runs. XLIDE 10.7.2, 10.8.0, 10.11.0
|
|
15
|
+
and 10.12.0 changed nothing the port reads.
|
|
16
|
+
|
|
17
|
+
The port now returns what XLIDE shows, not its raw rule list, and it analyzes
|
|
18
|
+
procedures nested past Python's recursion limit and long With blocks and member
|
|
19
|
+
chains in linear time.
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
* Nineteen runtime errors in code the VBE compiles, each reported as "This will
|
|
24
|
+
raise Run-time error ...":
|
|
25
|
+
* Overflow (#116): `arithmetic-overflow` for Integer arithmetic such as
|
|
26
|
+
`60 * 60 * 24`, an assignment that rounds past its target, and conversions
|
|
27
|
+
out of range; `for-counter-overflow` for `For i = 1 To 32767` on an Integer.
|
|
28
|
+
* Control flow (#117): `handler-fall-through` into an error handler that
|
|
29
|
+
re-raises, `resume-without-error`, `return-without-gosub`, and
|
|
30
|
+
`recursive-property-accessor`.
|
|
31
|
+
* Collections and Variants (#121): `collection-index-out-of-range`,
|
|
32
|
+
`collection-key-not-found`, `collection-key-in-use`, `variant-value-misuse`
|
|
33
|
+
and `runtime-member-not-found` (438 on a late-bound object).
|
|
34
|
+
* Host arguments (#122): `host-argument-out-of-range` for index 0 into a
|
|
35
|
+
1-based Office collection, `Cells(0, 1)` or an Offset off the sheet;
|
|
36
|
+
`multi-cell-range-as-scalar`; `sheet-name-invalid`.
|
|
37
|
+
* File statements (#123): `file-number-zero`, `file-used-after-close`,
|
|
38
|
+
`file-mode-mismatch`, `file-already-open` and `file-record-zero`.
|
|
39
|
+
* Fifteen compile errors: `const-overflow` (#116); `array-parameter-form`,
|
|
40
|
+
`bracketed-variable-name` and `duplicate-deftype` (#124);
|
|
41
|
+
`collection-operand`, `sub-used-as-value`, `implements-member-missing`,
|
|
42
|
+
`implements-member-signature` and `rem-after-then` (#125);
|
|
43
|
+
`directive-trailing-statement` and `duplicate-const-directive` (#130);
|
|
44
|
+
`stray-character` for characters VBA does not use and a no-break space
|
|
45
|
+
(#132); `line-too-long`, `date-literal-invalid` and `float-literal-overflow`
|
|
46
|
+
(#133).
|
|
47
|
+
* Existing rules report more of what the code states (#118 to #120, #124 to
|
|
48
|
+
#126): `Asc("")`, `Sqr(-1)`, `Log(0)`, `CLng("abc")`, `"abc" + 1` into a
|
|
49
|
+
Variant, a divisor local that holds 0, array bounds known from `Split`,
|
|
50
|
+
`Array` or a Range literal's `Value`, `ReDim a(-1)`, `Next i, j` out of
|
|
51
|
+
order, and the line continuations the VBE refuses.
|
|
52
|
+
* `AnalyzeModuleOptions.raw_rule_output`: the rules' own list, as upstream's
|
|
53
|
+
`analyzeModule` returns it, without the two steps below.
|
|
54
|
+
* `resolve_host_member` in `pyvbaanalysis.host`, and `declaredType` on a host
|
|
55
|
+
model member: the type its library declares, where the model's `returns`
|
|
56
|
+
is repaired from the reference documentation.
|
|
57
|
+
|
|
58
|
+
### Changed
|
|
59
|
+
|
|
60
|
+
* `analyze_module`, and everything built on it, returns what XLIDE shows. A
|
|
61
|
+
runtime-error finding under `On Error Resume Next`, from that statement to the
|
|
62
|
+
next `On Error` or the end of the procedure, is dropped, since the error is
|
|
63
|
+
raised and handled there (`n = UBound(a)` is the usual allocated-array
|
|
64
|
+
test, XLIDE issue #106). Findings with one code and span are merged, the later
|
|
65
|
+
one kept. `diagnostics/module_analysis.py` ports both from XLIDE's
|
|
66
|
+
`analyzeVbaModuleSource`.
|
|
67
|
+
* `member-not-found` works in Word, PowerPoint and Access: their models carry
|
|
68
|
+
the type libraries' hidden members and prove a member absent where the
|
|
69
|
+
library marks the interface NONEXTENSIBLE (#127). Document, Form, Report and
|
|
70
|
+
Control stay open. The data file `excel_closed_types.json` is replaced by
|
|
71
|
+
`host_closed_types.json`, which covers all four hosts.
|
|
72
|
+
* A host member the type library declares `As Object`, such as `ActiveSheet`
|
|
73
|
+
or a `Worksheets(1)` item, is late bound (#114).
|
|
74
|
+
* A hex or octal literal is the signed value of its bits: `&H8000` is -32768
|
|
75
|
+
and `&H80000000` is -2147483648 (#141). `parse_vba_integer_literal` returns
|
|
76
|
+
that value.
|
|
77
|
+
* The parser opens and closes a block written in a one-line If's tail (#128),
|
|
78
|
+
reads `Else:` as the If's Else (#129), counts a block keyword restated in both
|
|
79
|
+
arms of an `#If` once (#130), and reads a numbered one-line If with an `=`
|
|
80
|
+
condition as an If (#131).
|
|
81
|
+
* An Enum value or Optional default keeps its leading number, so `= 300 - 100`
|
|
82
|
+
is not the literal -100, and a module's Consts fold once with a procedure's
|
|
83
|
+
own Consts layered on top (XLIDE 10.13.0).
|
|
84
|
+
|
|
85
|
+
### Fixed
|
|
86
|
+
|
|
87
|
+
* False positives on code the VBE compiles and runs (#96 to #115): `Choose` and
|
|
88
|
+
`Switch` arity, `Open path` without `For`, `On Local Error`, a ReDim that
|
|
89
|
+
declares its array, `total&+1`, a library qualifier such as `Excel.`, a
|
|
90
|
+
`#Const` never defined, DAO constants in Access, `Left(Null, 1)`, a string
|
|
91
|
+
into a Byte array, a division the code guards, the Let and Set pairings of a
|
|
92
|
+
property, Nothing tracking past a GoSub or an early `Exit For`, two project
|
|
93
|
+
types sharing an instance, a Public Enum in a class, a Const or parenthesized
|
|
94
|
+
ByRef argument, `Len` in an Enum value, Option placement after a Deftype, and
|
|
95
|
+
a Function's return assigned by For, ReDim, `Line Input #` or `Get #`.
|
|
96
|
+
* False positives found by this port's own hunt and fixed upstream in 10.14.0
|
|
97
|
+
(#140 to #147): `If c Is Nothing Then Set c = New Collection`, `Set a(i) = c`
|
|
98
|
+
and `AddressOf` a Sub reported as compile errors; Win32 flag Enums such as
|
|
99
|
+
`GENERIC_READ = &H80000000` as Overflow; `Err.Raise vbObjectError + 513` as
|
|
100
|
+
error 5; the `;` of `If x Then Debug.Print a; b`; a string default holding a
|
|
101
|
+
comma in an Implements signature; `32000 \ 2 * 4` folded at the wrong
|
|
102
|
+
precedence; a For counter in a loop that leaves through `Exit For`; a file
|
|
103
|
+
reopened after `Reset` or a closing helper, an error handler's `Print #`,
|
|
104
|
+
and hex file numbers; and an item added through `Set o = c`.
|
|
105
|
+
* Misses from the same issues: `1 Mod 200 * 200` (error 6), `Resume Next`
|
|
106
|
+
after `On Error GoTo -1` (20), a `Print #` after `Reset` (52), a duplicate
|
|
107
|
+
key added through an alias (457), and a read-write interface property
|
|
108
|
+
implemented with its Get alone.
|
|
109
|
+
* `analyze_project` raised RecursionError on a procedure nested about 490 blocks
|
|
110
|
+
deep, where the VBE compiles a thousand. Every walk over a procedure body now
|
|
111
|
+
runs on an explicit stack, and `tests/test_deep_nesting.py` fails on one that
|
|
112
|
+
recurses per block.
|
|
113
|
+
|
|
114
|
+
### Performance
|
|
115
|
+
|
|
116
|
+
* A long With block and a long member chain are analyzed in linear time: the
|
|
117
|
+
pass keeps upstream's With-scan index (XLIDE issue #134) and receiver-chain
|
|
118
|
+
results (#135). A 500-line With block took 14.2 seconds in 2.2.1 and takes
|
|
119
|
+
0.19; a 3,000-member chain took 16 seconds and takes 0.56.
|
|
120
|
+
* Expression strings the parser carried on their own are lexed without
|
|
121
|
+
evicting the module from the token cache, and a test fails if one pass lexes
|
|
122
|
+
a module twice (#139). On two parts of the differential corpus's Office files
|
|
123
|
+
(66 modules), 2.3.0 is 12% faster than 2.2.1, new rules included.
|
|
124
|
+
|
|
125
|
+
### Verified
|
|
126
|
+
|
|
127
|
+
* Upstream's own 10.14.0 test suite, recorded and replayed through the port:
|
|
128
|
+
1419 standalone and 992 project calls, identical in code, span and message.
|
|
129
|
+
* The oracle corpus (2155 diagnostics in 1229 modules), 16 real workbooks, 195
|
|
130
|
+
Office files of every host, 693 further projects (948 modules) and 7 VB6
|
|
131
|
+
projects: identical findings from both analyzers, compared at what XLIDE
|
|
132
|
+
shows.
|
|
133
|
+
* Every expectation in the new sync tests was also run through the pinned
|
|
134
|
+
upstream analyzer.
|
|
135
|
+
|
|
136
|
+
## 2.2.1 - 2026-09-23
|
|
137
|
+
|
|
138
|
+
Sync to XLIDE 10.7.1 (commit 6ead73d), from 10.6.0. Upstream fixed how its
|
|
139
|
+
lexer and parser read a handful of lines the VBE compiles (XLIDE issues #82 to
|
|
140
|
+
#90), and the port takes each fix. XLIDE 10.7.0 changed nothing the port reads.
|
|
141
|
+
|
|
142
|
+
### Added
|
|
143
|
+
|
|
144
|
+
* `LoadedModule.designer_block`: the export header a reader stripped ahead of
|
|
145
|
+
`source`, empty when there was none. `designer_block + source` is the module
|
|
146
|
+
text as read, so a span in the analyzed body can be placed in the file.
|
|
147
|
+
|
|
148
|
+
### Changed
|
|
149
|
+
|
|
150
|
+
* A contextual keyword is a `KEYWORD` token only inside the statement that
|
|
151
|
+
makes it one: `Text` after `Option Compare`, `Step` in a `For` header,
|
|
152
|
+
`Output` in an `Open` statement. Elsewhere, as in `Dim text As String`, it is
|
|
153
|
+
an `IDENTIFIER` (XLIDE issue #86). `PtrSafe` joins these words, as it did
|
|
154
|
+
upstream with issue #41.
|
|
155
|
+
* A comment ending in ` _` runs on through the next line, so its token can span
|
|
156
|
+
physical lines (#82). A line continuation may have whitespace after its `_`
|
|
157
|
+
(#83).
|
|
158
|
+
* `1.` lexes as a float and `&17` as an octal literal. `=>`, `=<` and `><` are
|
|
159
|
+
one operator token, whose `canonical_text` gives the standard spelling (#87).
|
|
160
|
+
|
|
161
|
+
### Fixed
|
|
162
|
+
|
|
163
|
+
False positives 2.2.0 reported on code that compiles, and two errors it missed:
|
|
164
|
+
|
|
165
|
+
* `unreachable-code` on the line after
|
|
166
|
+
`If conn Is Nothing Then ACCT = CVErr(xlErrNA): Exit Function`. Every
|
|
167
|
+
statement a one-line `If` runs after a colon belongs to the If (MS-VBAL
|
|
168
|
+
5.4.2.9). After a `Set x = Nothing` or an `Erase` there, the next line no
|
|
169
|
+
longer reports an unset object or an unallocated array. A `Set` inside a
|
|
170
|
+
one-line `If` no longer leaves the object reported as Nothing after it.
|
|
171
|
+
* Findings on the line after a comment ending in ` _` (#82), and a missing
|
|
172
|
+
`Then` or a call to a variable on the line after a continuation with spaces
|
|
173
|
+
after its `_` (#83).
|
|
174
|
+
* `If x Then:` read as a block If (#84), and a one-word `EndIf` read as no
|
|
175
|
+
closer, so the lines after it reported as unreachable (#88).
|
|
176
|
+
* `invalid-expression-syntax` on `1.`, `&17`, `a => b`, `a < > b` and the other
|
|
177
|
+
spellings the VBE reads (#87). `s = "a" &1`, which the VBE refuses, is now
|
|
178
|
+
reported, and `s = "a" &9` is still a concatenation.
|
|
179
|
+
* `argument-count` missed on `Needs, 2`: a comma touching the callee opens its
|
|
180
|
+
argument list, as the VBE reads it (#85).
|
|
181
|
+
* `assignment-object-type-mismatch` on `Shape.Duplicate` assigned to a `Shape`,
|
|
182
|
+
on `SparklineGroup.SeriesColor` assigned to a `FormatColor`, and on a
|
|
183
|
+
`Charts` or `Worksheets` collection assigned to a `Sheets` variable (#90).
|
|
184
|
+
* `Err.LastDllError` is spelled the way the VBE writes it (#89).
|
|
185
|
+
* The command line counted lines in a `.cls` or `.frm` export from the end of
|
|
186
|
+
its designer header (the `VERSION` line and `Begin ... End` block the reader
|
|
187
|
+
strips before analysis), so a class module's findings printed four lines
|
|
188
|
+
early and a UserForm's early by the height of its form block. Lines, and the
|
|
189
|
+
JSON `start` and `end` offsets, now count the file as saved. Modules read
|
|
190
|
+
from an Office container are numbered as before, since pyOpenVBA reads them
|
|
191
|
+
without a designer header. The library's spans still index the code body.
|
|
192
|
+
|
|
193
|
+
### Verified
|
|
194
|
+
|
|
195
|
+
* Upstream's own 10.7.1 test suite, recorded and replayed through the port:
|
|
196
|
+
1081 standalone and 936 project calls, every result identical in code, span
|
|
197
|
+
and message. Before the port changes 24 of them differed, so the replay sees
|
|
198
|
+
what this release changes.
|
|
199
|
+
* The oracle corpus (1820 diagnostics), 16 real workbooks, 195 Office files of
|
|
200
|
+
every host, 693 further projects (948 modules) and 7 VB6 projects: identical
|
|
201
|
+
diagnostics from both analyzers.
|
|
202
|
+
* Against 2.2.0, the largest module (26,721 lines) takes the same CPU time.
|
|
203
|
+
|
|
8
204
|
## 2.2.0 - 2026-09-22
|
|
9
205
|
|
|
10
206
|
Sync to XLIDE 10.6.0 (commit 5682c8f), from 6.2.0: twelve new diagnostics, early
|
|
@@ -80,7 +80,8 @@ python tools/differential/harness.py projects artifacts/differential/cases/mine.
|
|
|
80
80
|
the port, rebuilding the project index behind a call made with project context,
|
|
81
81
|
and compares the diagnostics by code, span and message. It finds the gaps
|
|
82
82
|
nothing else exercises: whole checks never ported, fixes older than the last
|
|
83
|
-
sync point.
|
|
83
|
+
sync point. The recorded calls are the rules alone, so the port is asked for its
|
|
84
|
+
`raw_rule_output`.
|
|
84
85
|
* `corpus` runs the oracle corpus through both analyzers, each module standalone
|
|
85
86
|
and with its case's modules as a project.
|
|
86
87
|
* `cases` turns Office files, and folders searched for them and for exported
|
|
@@ -88,6 +89,16 @@ python tools/differential/harness.py projects artifacts/differential/cases/mine.
|
|
|
88
89
|
block of upstream's syntax corpus, and `--host` names a host for the cases no
|
|
89
90
|
file implies one for. `projects` runs a cases file through both analyzers.
|
|
90
91
|
|
|
92
|
+
`corpus` and `projects` compare what XLIDE shows. Upstream runs its rules
|
|
93
|
+
through `analyzeVbaModuleSource`, which drops a runtime-error finding under
|
|
94
|
+
`On Error Resume Next` and merges findings with one code and span, as
|
|
95
|
+
`analyze_module` does (`pyvbaanalysis/diagnostics/module_analysis.py`). Its own
|
|
96
|
+
additions the port leaves out, the structural block-balance pass and XLIDE's test
|
|
97
|
+
and suppression directives, are cut from its list by keeping only what its rules
|
|
98
|
+
produced (`tools/differential/upstream/shown.mjs`). One step the port lacks does
|
|
99
|
+
remove findings: a procedure marked `'@xlide-test expected-error=N` hides a runtime
|
|
100
|
+
finding for error N. No corpus has one.
|
|
101
|
+
|
|
91
102
|
`replay`, `corpus` and `projects` exit 1 when anything differs and print what only
|
|
92
103
|
one side reports. Where the port reports more, the port is wrong. Where upstream
|
|
93
104
|
reports more it may be an upstream false positive, so check before porting it.
|
|
@@ -104,6 +115,11 @@ run ends. `harness.py unpatch` restores a pin a run left patched, and
|
|
|
104
115
|
## Adding or changing a rule
|
|
105
116
|
|
|
106
117
|
* Port the rule from its XLIDE source; match the behavior, not just the shape.
|
|
118
|
+
* Walk a procedure body with `iter_body_nodes` or `iter_body_nodes_in_context`
|
|
119
|
+
(`pyvbaanalysis/parser/nodes.py`), not with a function that calls itself for
|
|
120
|
+
each nested block. XLIDE's walks recurse, which JavaScript's stack absorbs;
|
|
121
|
+
Python stops at 1,000 frames, and the VBE compiles blocks nested a thousand
|
|
122
|
+
deep. `tests/test_deep_nesting.py` fails on a walk that recurses per block.
|
|
107
123
|
* A rule ships only with oracle backing. Validate it against the vendored corpus
|
|
108
124
|
and add direct tests for the positive and the no-false-positive control cases.
|
|
109
125
|
* The diagnostic rule registry order is a contract: it is the diagnostic
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: pyvbaanalysis
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Pure-Python static analysis for Excel VBA
|
|
5
5
|
Project-URL: Homepage, https://github.com/WilliamSmithEdward/pyVBAanalysis
|
|
6
6
|
Project-URL: Repository, https://github.com/WilliamSmithEdward/pyVBAanalysis
|
|
@@ -54,6 +54,9 @@ These are re-exported at the package root for convenience:
|
|
|
54
54
|
`modules`, the `host` its extension implies, and `referenced_hosts`, the other
|
|
55
55
|
Office libraries its project references (`None` when the reference list could
|
|
56
56
|
not be read).
|
|
57
|
+
* A `LoadedModule` carries a module's `name`, `kind`, and `source` (the code body
|
|
58
|
+
the analyzer reads), plus `designer_block`, the export header the reader stripped
|
|
59
|
+
ahead of `source` (empty when there was none).
|
|
57
60
|
* Building blocks: `LoadedModule`, `strip_export_header`, `classify_module_kind`,
|
|
58
61
|
`module_name_from_text`, `loaded_module_from_text`, `WorkbookReadError`,
|
|
59
62
|
`LooseFileReadError`, and the extension sets `LOOSE_EXTENSIONS`,
|
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
# Diagnostic catalogue
|
|
2
2
|
|
|
3
|
-
The diagnostic codes pyVBAanalysis can emit, generated from the rule metadata (`tools/generate_diagnostics_catalogue.py`). This table lists the
|
|
3
|
+
The diagnostic codes pyVBAanalysis can emit, generated from the rule metadata (`tools/generate_diagnostics_catalogue.py`). This table lists the 165 rule-metadata codes across 6 categories. A further 3 structural block-balance codes (`mismatched-end-keyword`, `missing-block-closer`, `unmatched-block-closer`) are emitted by the parser pass and are not in the metadata table, for a full set of 168 codes.
|
|
4
4
|
|
|
5
5
|
Each code is reported only when it is provably correct; anything unknown or ambiguous stays quiet (the no-false-positive discipline). The **kind** column says what a code means: a *compile error* is rejected by the VBE compiler, a *runtime error* is a deterministic Run-time error, a *runtime risk* is a likely fault, and *style* is advisory.
|
|
6
6
|
|
|
7
7
|
Override a code's severity with `AnalyzeModuleOptions.severity_overrides` (or the `severity_overrides` argument of `analyze_project` / the reader functions), keyed by code. Use `"off"`, `"information"`, `"warning"`, or `"error"`; the allowed values per code are constrained by policy (some codes can be downgraded but not disabled). See [docs/usage.md](usage.md).
|
|
8
8
|
|
|
9
|
-
## Declaration (
|
|
9
|
+
## Declaration (46)
|
|
10
10
|
|
|
11
11
|
| Code | Title | Default | Kind | Spec reference |
|
|
12
12
|
| --- | --- | --- | --- | --- |
|
|
13
|
+
| `array-parameter-form` | Array parameter cannot be ByVal or Optional | error | compile error | MS-VBAL 5.3.1.5; VBE "Array argument must be ByRef" / "Optional argument must be Variant or intrinsic type with a default value" (issue #124, Excel 16.0) |
|
|
13
14
|
| `byval-udt-parameter` | User-defined type parameter cannot be ByVal | error | compile error | MS-VBAL 5.3.1 (parameter passing) / VBE compiler |
|
|
15
|
+
| `const-overflow` | Const value overflows | error | compile error | MS-VBAL 5.6.9.3; VBE compile error: Overflow (issue #116, Excel 16.0) |
|
|
14
16
|
| `const-value-not-constant` | Const value must be a constant expression | error | compile error | MS-VBAL 5.2.4 (Const declaration value is a constant-expression) |
|
|
15
17
|
| `declare-missing-ptrsafe` | Declare statement missing PtrSafe for 64-bit Office | error | compile error | VBA 7 Declare statement PtrSafe requirement for 64-bit Office |
|
|
16
18
|
| `dim-initializer` | Declaration cannot include an initializer (VB.NET syntax) | error | compile error | MS-VBAL 5.2.3.1 |
|
|
19
|
+
| `duplicate-const-directive` | Duplicate #Const | error | compile error | MS-VBAL 3.4.1 #Const; VBE "Duplicate definition" (issue #130, Excel 16.0) |
|
|
17
20
|
| `duplicate-declaration` | Duplicate declaration in the current scope | error | compile error | MS-VBAL 5.2 / 5.3 |
|
|
21
|
+
| `duplicate-deftype` | Duplicate Deftype statement | error | compile error | MS-VBAL 5.2.3.1.3; VBE "Duplicate Deftype statement" (issue #124, Excel 16.0) |
|
|
18
22
|
| `duplicate-enum-member` | Duplicate Enum member | error | compile error | MS-VBAL 5.2.3.4 |
|
|
19
23
|
| `duplicate-module-variable` | Duplicate module-level declaration | error | compile error | MS-VBAL 5.2.3 |
|
|
20
24
|
| `duplicate-option` | Duplicate Option statement | error | compile error | MS-VBAL 5.2.1 (module options) |
|
|
@@ -34,7 +38,7 @@ Override a code's severity with `AnalyzeModuleOptions.severity_overrides` (or th
|
|
|
34
38
|
| `module-declaration-after-procedure` | Module-level declaration after procedure | error | compile error | MS-VBAL 5.2 / 5.3 |
|
|
35
39
|
| `module-declaration-in-procedure` | Module-level declaration inside procedure | error | compile error | MS-VBAL 5.2 / 5.3 |
|
|
36
40
|
| `object-module-public-member` | Invalid public member in object module | error | compile error | VBE compiler: public object-module member restrictions |
|
|
37
|
-
| `option-after-declaration` | Option statement
|
|
41
|
+
| `option-after-declaration` | Option statement after a procedure | error | compile error | MS-VBAL 5.2.1 |
|
|
38
42
|
| `optional-udt-parameter` | Optional parameter cannot be a user-defined type | error | compile error | MS-VBAL 5.3.1 (Optional parameter) / VBE compiler |
|
|
39
43
|
| `paramarray-non-variant` | ParamArray elements must be Variant | error | compile error | MS-VBAL 5.3.1.6 |
|
|
40
44
|
| `paramarray-not-last` | ParamArray must be the final parameter | error | compile error | MS-VBAL 5.3.1.6 |
|
|
@@ -70,7 +74,7 @@ Override a code's severity with `AnalyzeModuleOptions.severity_overrides` (or th
|
|
|
70
74
|
| `undeclared-variable` | Variable not defined | error | compile error | MS-VBAL 5.2.4.1.1 |
|
|
71
75
|
| `unknown-call` | Sub or Function not defined | error | compile error | MS-VBAL 5.4.2.1 |
|
|
72
76
|
|
|
73
|
-
## Semantic (
|
|
77
|
+
## Semantic (75)
|
|
74
78
|
|
|
75
79
|
| Code | Title | Default | Kind | Spec reference |
|
|
76
80
|
| --- | --- | --- | --- | --- |
|
|
@@ -80,6 +84,7 @@ Override a code's severity with `AnalyzeModuleOptions.severity_overrides` (or th
|
|
|
80
84
|
| `argument-object-type-mismatch` | Object argument type mismatch | error | compile error | MS-VBAL 5.3.1 |
|
|
81
85
|
| `argument-shape-mismatch` | Argument shape (array/Type vs scalar) mismatch | error | compile error | MS-VBAL 5.3.1 (argument passing) / VBE compiler: ByRef argument type mismatch; array or user-defined type expected |
|
|
82
86
|
| `argument-type-mismatch` | Argument type mismatch | error | runtime error | MS-VBAL 5.3.1 / runtime type coercion and numeric overflow |
|
|
87
|
+
| `arithmetic-overflow` | Arithmetic overflow | error | runtime error | MS-VBAL 5.6.9.3 operator result types; VBE runtime error 6: Overflow (issue #116, Excel 16.0) |
|
|
83
88
|
| `array-assignment-to-scalar` | Array cannot be assigned to scalar | error | compile error | MS-VBAL 5.4.3 / VBE compiler: Type mismatch |
|
|
84
89
|
| `array-bound-requires-array` | Array bound function requires array | error | compile error | MS-VBAL LBound/UBound / VBE compiler: Expected array |
|
|
85
90
|
| `array-declaration-impossible-bounds` | Array declaration lower bound is greater than upper bound | error | compile error | MS-VBAL 5.2.3.1 (array declaration bounds) |
|
|
@@ -88,6 +93,10 @@ Override a code's severity with `AnalyzeModuleOptions.severity_overrides` (or th
|
|
|
88
93
|
| `assignment-type-mismatch` | Assignment type mismatch | error | runtime error | MS-VBAL 5.4.3 / runtime type coercion and numeric overflow |
|
|
89
94
|
| `byref-argument-type-mismatch` | ByRef argument type mismatch | error | compile error | MS-VBAL 5.3.1 / VBE compiler: ByRef argument type mismatch |
|
|
90
95
|
| `case-outside-select` | Case statement outside Select Case | error | compile error | MS-VBAL 5.4.2.4 |
|
|
96
|
+
| `collection-index-out-of-range` | Collection index out of range | error | runtime error | VBE runtime errors 5 and 9 on VBA.Collection (issue #121, Excel 16.0) |
|
|
97
|
+
| `collection-key-in-use` | Collection key already in use | error | runtime error | VBE runtime error 457 on VBA.Collection (issue #121, Excel 16.0) |
|
|
98
|
+
| `collection-key-not-found` | Collection key not found | error | runtime error | VBE runtime error 5 on VBA.Collection (issue #121, Excel 16.0) |
|
|
99
|
+
| `collection-operand` | Collection used as an operand | error | compile error | VBE "Argument not optional" on a Collection whose default member Item takes an index (issue #125, Excel 16.0) |
|
|
91
100
|
| `const-assignment` | Assignment to a constant | error | compile error | MS-VBAL 5.4.3.1 |
|
|
92
101
|
| `division-by-zero` | Division by zero | error | runtime error | MS-VBAL 5.6 / runtime division by zero |
|
|
93
102
|
| `duplicate-case-else` | Duplicate Case Else in Select Case | error | compile error | MS-VBAL 5.4.2.10 (Select Case) |
|
|
@@ -96,9 +105,19 @@ Override a code's severity with `AnalyzeModuleOptions.severity_overrides` (or th
|
|
|
96
105
|
| `erase-requires-array` | Erase target must be array or Variant | error | compile error | MS-VBAL Erase statement / VBE compiler: Expected array |
|
|
97
106
|
| `exit-outside-block` | Loop exit statement outside matching loop | error | compile error | MS-VBAL 5.4.1.3 |
|
|
98
107
|
| `exit-wrong-proc` | Exit statement does not match the enclosing procedure | error | compile error | MS-VBAL 5.4.1.3 |
|
|
108
|
+
| `file-already-open` | File number opened twice | error | runtime error | VBE runtime error 55: File already open (issue #123, Excel 16.0) |
|
|
109
|
+
| `file-mode-mismatch` | File statement the open mode forbids | error | runtime error | VBE runtime error 54: Bad file mode (issue #123, Excel 16.0) |
|
|
110
|
+
| `file-number-zero` | File number 0 | error | runtime error | VBE runtime error 52: Bad file name or number (issue #123, Excel 16.0) |
|
|
111
|
+
| `file-record-zero` | Record number 0 | error | runtime error | VBE runtime error 63: Bad record number (issue #123, Excel 16.0) |
|
|
112
|
+
| `file-used-after-close` | File statement on a closed file number | error | runtime error | VBE runtime error 52: Bad file name or number (issue #123, Excel 16.0) |
|
|
99
113
|
| `fixed-array-redim` | Fixed-size array cannot be ReDimmed | error | compile error | MS-VBAL ReDim statement |
|
|
114
|
+
| `for-counter-overflow` | For counter overflows after its last pass | error | runtime error | MS-VBAL 5.4.2.3; VBE runtime error 6: Overflow (issue #116, Excel 16.0) |
|
|
100
115
|
| `for-each-control-variable-type` | For Each control variable must be Variant or Object | error | compile error | MS-VBAL 5.4.2.5 |
|
|
101
116
|
| `for-each-source-type` | For Each source must be collection or array | error | compile error | MS-VBAL 5.4.2.5 / VBE compiler: For Each may only iterate over a collection object or an array |
|
|
117
|
+
| `handler-fall-through` | Execution falls into an error handler that re-raises | error | runtime error | VBE runtime error 5 from Err.Raise Err.Number with Err.Number 0 (issue #117, Excel 16.0) |
|
|
118
|
+
| `host-argument-out-of-range` | Host argument out of range | error | runtime error | Office object model: 1-based collections, cell rows and columns from 1 (issue #122, Excel/Word/PowerPoint 16.0) |
|
|
119
|
+
| `implements-member-missing` | Interface member not implemented | error | compile error | MS-VBAL 5.2.4.1; VBE "Object module needs to implement ... for interface ..." (issue #125, Excel 16.0) |
|
|
120
|
+
| `implements-member-signature` | Interface member implemented with another signature | error | compile error | MS-VBAL 5.2.4.1; VBE "Procedure declaration does not match description of event or procedure having the same name" (issue #125, Excel 16.0) |
|
|
102
121
|
| `invalid-assignment-target` | Cannot assign to a literal value | error | compile error | MS-VBAL 5.4.3 (assignment) / VBE compiler |
|
|
103
122
|
| `is-operator-non-object` | 'Is' operator requires object operands | error | compile error | MS-VBAL 5.6 (Is operator) |
|
|
104
123
|
| `late-bound-friend-member` | Friend member reached through a late-bound receiver | error | runtime error | VBE runtime error 438: Object does not support this property or method |
|
|
@@ -108,24 +127,32 @@ Override a code's severity with `AnalyzeModuleOptions.severity_overrides` (or th
|
|
|
108
127
|
| `mid-statement-literal-target` | Mid statement target must be a writable String variable | error | compile error | MS-VBAL 5.4.3.4 (Mid/MidB statement) |
|
|
109
128
|
| `missing-library-reference` | Type library not referenced | error | compile error | VBE compiler: User-defined type not defined |
|
|
110
129
|
| `missing-return-assignment` | Function has no return assignment | warning | runtime risk | VBA Function return variable semantics |
|
|
130
|
+
| `multi-cell-range-as-scalar` | Multi-cell range read as a scalar | error | runtime error | VBE runtime error 13: Type mismatch on a Range value that is an array (issue #122, Excel 16.0) |
|
|
111
131
|
| `next-variable-mismatch` | Next variable does not match active For loop | error | compile error | MS-VBAL 5.4.2.5 |
|
|
112
132
|
| `non-callable-call` | Identifier is not callable | error | compile error | MS-VBAL 5.4.2.1 |
|
|
113
133
|
| `non-scalar-binary-operand` | Operator requires a scalar operand | error | compile error | MS-VBAL 5.6 (binary operators) / VBE compiler: array operand Type mismatch |
|
|
114
134
|
| `object-variable-not-set` | Object variable not set | error | runtime error | VBE runtime error 91: Object variable or With block variable not set |
|
|
115
135
|
| `raiseevent-undeclared-event` | RaiseEvent target is not declared | error | compile error | MS-VBAL RaiseEvent statement: event name resolution |
|
|
116
136
|
| `readonly-member-assignment` | Assignment to a read-only member | error | compile error | VBE compiler: Can't assign to read-only property |
|
|
137
|
+
| `recursive-property-accessor` | Property procedure calls itself | error | runtime error | VBE runtime error 28: Out of stack space (issue #117, Excel 16.0) |
|
|
117
138
|
| `redim-impossible-bounds` | ReDim lower bound is greater than upper bound | error | runtime error | MS-VBAL ReDim statement / VBE compiler runtime error 9 |
|
|
118
139
|
| `redim-preserve-dimension-change` | ReDim Preserve can only resize the last dimension | error | runtime error | MS-VBAL ReDim Preserve statement |
|
|
140
|
+
| `resume-without-error` | Resume with no error handler installed | error | runtime error | VBE runtime error 20: Resume without error (issue #117, Excel 16.0) |
|
|
141
|
+
| `return-without-gosub` | Execution falls into a GoSub target | error | runtime error | VBE runtime error 3: Return without GoSub (issue #117, Excel 16.0) |
|
|
119
142
|
| `runtime-argument-value` | Invalid runtime argument value | error | runtime error | MS-VBAL 5.6 / VBA runtime argument bounds and VBE compiler runtime error 5 |
|
|
120
143
|
| `runtime-conversion-value` | Invalid runtime conversion value | error | runtime error | MS-VBAL 5.6 / VBA runtime conversion and VBE compiler runtime error 13 |
|
|
144
|
+
| `runtime-member-not-found` | Member not found at run time | error | runtime error | VBE runtime error 438: Object doesn't support this property or method (issue #121, Excel 16.0) |
|
|
121
145
|
| `scalar-member-access` | Member access on scalar variable | error | compile error | VBE compiler: Invalid qualifier / Syntax error |
|
|
122
146
|
| `scalar-redim` | Scalar variable cannot be ReDimmed | error | compile error | MS-VBAL ReDim statement / VBE compiler: Expected array |
|
|
123
147
|
| `set-required` | Object assignment requires Set | error | runtime error | VBE runtime error 91: Object variable or With block variable not set (MS-VBAL 5.4.3 / Set statement) |
|
|
124
148
|
| `set-requires-object` | Set assignment requires an object variable | error | compile error | MS-VBAL 5.4.3 |
|
|
149
|
+
| `sheet-name-invalid` | Sheet name Excel refuses | error | runtime error | Excel runtime error 1004: invalid name for a sheet or chart (issue #122, Excel 16.0) |
|
|
125
150
|
| `string-arithmetic-coercion` | Nonnumeric string in numeric expression | error | runtime error | MS-VBAL 5.6 / runtime type coercion |
|
|
151
|
+
| `sub-used-as-value` | Sub used as a value | error | compile error | VBE "Expected Function or variable" (issue #125, Excel 16.0) |
|
|
126
152
|
| `typeof-is-always-false` | 'TypeOf ... Is' is always False | warning | runtime risk | MS-VBAL 5.6 (TypeOf...Is expression) |
|
|
127
153
|
| `unallocated-dynamic-array-access` | Dynamic array is not allocated | error | runtime error | VBE runtime error 9: Subscript out of range |
|
|
128
154
|
| `undefined-label` | Label not defined | error | compile error | MS-VBAL 5.4.1 / VBE compiler: Label not defined |
|
|
155
|
+
| `variant-value-misuse` | Variant value used as another kind | error | runtime error | VBE runtime errors 424 and 13 on a Variant holding a scalar or an array (issue #121, Excel 16.0) |
|
|
129
156
|
|
|
130
157
|
## Style (13)
|
|
131
158
|
|
|
@@ -145,23 +172,30 @@ Override a code's severity with `AnalyzeModuleOptions.severity_overrides` (or th
|
|
|
145
172
|
| `variable-never-read` | Variable is assigned but never read | information | style-policy | MS-VBAL 5.4.3 (assignment) plus dead-code policy |
|
|
146
173
|
| `vba-test-directive` | Invalid VBA test directive | warning | style-policy | VBA test directive comment syntax |
|
|
147
174
|
|
|
148
|
-
## Syntax (
|
|
175
|
+
## Syntax (24)
|
|
149
176
|
|
|
150
177
|
| Code | Title | Default | Kind | Spec reference |
|
|
151
178
|
| --- | --- | --- | --- | --- |
|
|
179
|
+
| `bracketed-variable-name` | Bracketed name in a variable declaration | error | compile error | MS-VBAL 3.3.5.3 foreign-name; VBE "Syntax error" on Dim [name] (issue #124, Excel 16.0) |
|
|
152
180
|
| `call-requires-parens` | Call statement requires parentheses around arguments | error | compile error | MS-VBAL 5.4.2.1 |
|
|
153
181
|
| `call-statement-forbids-parens` | Standalone zero-argument call cannot use empty parentheses | error | compile error | MS-VBAL 5.4.2.1 |
|
|
154
182
|
| `call-statement-multi-arg-parens` | Standalone call cannot parenthesize multiple arguments | error | compile error | MS-VBAL 5.4.2.1 |
|
|
183
|
+
| `date-literal-invalid` | Date literal the VBE refuses | error | compile error | MS-VBAL 3.3.3 date tokens; VBE "Syntax error" (issue #133, Excel 16.0) |
|
|
184
|
+
| `directive-trailing-statement` | Code after a compiler directive on its line | error | compile error | MS-VBAL 3.4 conditional compilation; VBE "An # ElseIf, # Else, or # EndIf must be preceded by an # If clause" (issue #130, Excel 16.0) |
|
|
155
185
|
| `else-branch-order` | Else branch must be final in conditional block | error | compile error | MS-VBAL 3.4 / 5.4.2.1 |
|
|
156
186
|
| `expression-call-requires-parens` | Function call in an expression requires parentheses around arguments | error | compile error | MS-VBAL 5.6.9 |
|
|
187
|
+
| `float-literal-overflow` | Floating-point literal overflows | error | compile error | MS-VBAL 3.3.2 FLOAT; VBE "Syntax error" on 1E400 (issue #125, Excel 16.0) |
|
|
157
188
|
| `if-missing-then` | If statement is missing Then | error | compile error | MS-VBAL 5.4.2.1 |
|
|
158
189
|
| `if-reserved-keyword-in-condition` | Reserved keyword in If condition | error | compile error | MS-VBAL 5.4.2.1 (If block) / 3.3.5.2 (reserved identifiers) / VBE compiler: Syntax error |
|
|
159
190
|
| `invalid-erase-target` | Erase target must be a variable or array name | error | compile error | MS-VBAL Erase statement |
|
|
160
191
|
| `invalid-explicit-call-target` | Invalid explicit Call target | error | compile error | VBE compiler: Syntax error |
|
|
161
192
|
| `invalid-expression-syntax` | Invalid expression syntax | error | compile error | MS-VBAL 5.6 / VBE compiler: Syntax error |
|
|
162
193
|
| `invalid-line-continuation` | Invalid line continuation | error | compile error | MS-VBAL 3.2.2 |
|
|
163
|
-
| `
|
|
194
|
+
| `line-too-long` | Physical line over 1023 characters | error | compile error | VBE line limit: 1023 characters compile, 1024 are refused (issue #133, Excel 16.0) |
|
|
195
|
+
| `open-missing-for` | 'Open' statement mode without 'For', or no 'As' clause | error | compile error | MS-VBAL 5.4.5.1 (Open statement) / VBE compiler |
|
|
196
|
+
| `rem-after-then` | Rem after Then | error | compile error | MS-VBAL 3.3.1 comment / 5.4.2.9 single-line If; VBE "Syntax error" (issue #125, Excel 16.0) |
|
|
164
197
|
| `statement-outside-procedure` | Statement outside procedure | error | compile error | MS-VBAL 5.2 / 5.4 |
|
|
198
|
+
| `stray-character` | Character VBA does not use | error | compile error | MS-VBAL 3.3.1 special-token; VBE "Syntax error" on ; ` { } @ ~ \| and a non-breaking space (issue #132, Excel 16.0) |
|
|
165
199
|
| `suffixed-literal-overflow` | Type-suffixed literal out of range | error | compile error | MS-VBAL 3.3.2 (number tokens / type suffixes) / VBE compiler |
|
|
166
200
|
| `typeof-missing-operand` | 'TypeOf' requires an object expression | error | compile error | MS-VBAL 5.6 (TypeOf...Is) / VBE compiler |
|
|
167
201
|
| `unbalanced-parens` | Unbalanced parentheses | error | compile error | MS-VBAL 3.3.1 |
|
|
@@ -136,6 +136,11 @@ analyze_loose_files(["Module1.bas", "Widget.cls"]) # several, as one project
|
|
|
136
136
|
skipped for it (see "Whole project vs a single file" below). Use `analyze_loose_files`
|
|
137
137
|
to analyze several files together with shared cross-module context.
|
|
138
138
|
|
|
139
|
+
Spans index the code body the analyzer reads, which starts after the stripped header.
|
|
140
|
+
`load_loose_module` returns a `LoadedModule` whose `designer_block` holds that header,
|
|
141
|
+
so `line_col(module.designer_block + module.source, len(module.designer_block) + span.start)`
|
|
142
|
+
places a span in the file. The command line reports positions this way.
|
|
143
|
+
|
|
139
144
|
### Office macro containers
|
|
140
145
|
|
|
141
146
|
The container reader reads VBA directly out of an Office file via pyOpenVBA (the one
|
|
@@ -291,6 +296,12 @@ project), or an Office macro container, whose extension selects the host model.
|
|
|
291
296
|
`pyvbaanalysis --version` prints the version, and `python -m pyvbaanalysis` is
|
|
292
297
|
equivalent to the `pyvbaanalysis` command.
|
|
293
298
|
|
|
299
|
+
Each diagnostic is placed by line and column in the module text as read. For a loose
|
|
300
|
+
file that is the file itself, so the `VERSION` and `Begin ... End` header of a `.cls`
|
|
301
|
+
or `.frm` export counts and the numbers match an editor. For an Office container it
|
|
302
|
+
is the module's stored text, which begins at its `Attribute` lines; the VBE hides
|
|
303
|
+
those lines, so its line numbers run lower by their count.
|
|
304
|
+
|
|
294
305
|
Flags:
|
|
295
306
|
|
|
296
307
|
| Flag | Effect |
|
|
@@ -336,7 +347,8 @@ diagnostics are reported or a file cannot be read, and `2` for a usage error.
|
|
|
336
347
|
]
|
|
337
348
|
```
|
|
338
349
|
|
|
339
|
-
`start` and `end` are character offsets
|
|
350
|
+
`start` and `end` are character offsets and `line` and `column` are 1-based, all in
|
|
351
|
+
the module text as read (see above).
|
|
340
352
|
|
|
341
353
|
## Use in CI
|
|
342
354
|
|
|
@@ -142,7 +142,10 @@ def bare_call_statement_target(source: str, span: Span) -> BareCallStatementTarg
|
|
|
142
142
|
after_close = toks[close + 1] if 0 <= close and close + 1 < len(toks) else None
|
|
143
143
|
if after_close is None or after_close.raw_text in (".", "("):
|
|
144
144
|
return None
|
|
145
|
-
elif not explicit_call:
|
|
145
|
+
elif not explicit_call and r != ",":
|
|
146
|
+
# A comma cannot continue the callee, so it opens the argument list with
|
|
147
|
+
# or without a space: the VBE reads `Needs, 2` as `Needs , 2`, a missing
|
|
148
|
+
# first argument and 2 (XLIDE issue #85).
|
|
146
149
|
gap = source[span.start + callee.end : span.start + next_tok.start]
|
|
147
150
|
if _WHITESPACE.search(gap) is None:
|
|
148
151
|
return None
|
|
@@ -33,6 +33,7 @@ from .project import analyze_project
|
|
|
33
33
|
from .reader import (
|
|
34
34
|
LOOSE_EXTENSIONS,
|
|
35
35
|
OFFICE_EXTENSIONS,
|
|
36
|
+
LoadedModule,
|
|
36
37
|
LooseFileReadError,
|
|
37
38
|
WorkbookReadError,
|
|
38
39
|
load_loose_module,
|
|
@@ -137,8 +138,7 @@ def _analyze_loose_group(
|
|
|
137
138
|
whole_project=whole_project,
|
|
138
139
|
inline_suppression=inline_suppression,
|
|
139
140
|
)
|
|
140
|
-
|
|
141
|
-
return [_ProjectResult("(loose files)", diagnostics, sources)], warnings, errors
|
|
141
|
+
return [_ProjectResult("(loose files)", diagnostics, unique)], warnings, errors
|
|
142
142
|
|
|
143
143
|
|
|
144
144
|
def _analyze_workbook_group(
|
|
@@ -167,8 +167,7 @@ def _analyze_workbook_group(
|
|
|
167
167
|
host=project.host,
|
|
168
168
|
referenced_hosts=project.referenced_hosts,
|
|
169
169
|
)
|
|
170
|
-
|
|
171
|
-
results.append(_ProjectResult(str(path), diagnostics, sources))
|
|
170
|
+
results.append(_ProjectResult(str(path), diagnostics, modules))
|
|
172
171
|
return results, errors
|
|
173
172
|
|
|
174
173
|
|
|
@@ -179,11 +178,23 @@ class _ProjectResult:
|
|
|
179
178
|
self,
|
|
180
179
|
label: str,
|
|
181
180
|
diagnostics: dict[str, list[VbaDiagnostic]],
|
|
182
|
-
|
|
181
|
+
modules: Sequence[LoadedModule],
|
|
183
182
|
) -> None:
|
|
184
183
|
self.label = label
|
|
185
184
|
self.diagnostics = diagnostics
|
|
186
|
-
self.
|
|
185
|
+
self.modules = {module.name: module for module in modules}
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
def _text_as_read(module: LoadedModule | None) -> tuple[str, int]:
|
|
189
|
+
"""A module's text as read, and where the body the analyzer saw starts in it.
|
|
190
|
+
|
|
191
|
+
The reader strips a .cls or .frm export's designer block before analysis, so a
|
|
192
|
+
span indexes the body; shifting it by the block's length places it in the file
|
|
193
|
+
as saved, which is where a user will look for it.
|
|
194
|
+
"""
|
|
195
|
+
if module is None:
|
|
196
|
+
return "", 0
|
|
197
|
+
return module.designer_block + module.source, len(module.designer_block)
|
|
187
198
|
|
|
188
199
|
|
|
189
200
|
def _render_text(results: Sequence[_ProjectResult]) -> str:
|
|
@@ -195,10 +206,10 @@ def _render_text(results: Sequence[_ProjectResult]) -> str:
|
|
|
195
206
|
if not diagnostics:
|
|
196
207
|
continue
|
|
197
208
|
any_in_project = True
|
|
198
|
-
|
|
209
|
+
text, shift = _text_as_read(result.modules.get(module_name))
|
|
199
210
|
lines.append(f" {module_name}")
|
|
200
211
|
for diag in diagnostics:
|
|
201
|
-
line, column = line_col(
|
|
212
|
+
line, column = line_col(text, shift + diag.span.start)
|
|
202
213
|
lines.append(
|
|
203
214
|
f" {line}:{column} {diag.severity.value} {diag.code} {diag.message}"
|
|
204
215
|
)
|
|
@@ -207,28 +218,31 @@ def _render_text(results: Sequence[_ProjectResult]) -> str:
|
|
|
207
218
|
return "\n".join(lines)
|
|
208
219
|
|
|
209
220
|
|
|
221
|
+
def _diagnostic_json(diag: VbaDiagnostic, text: str, shift: int) -> dict[str, object]:
|
|
222
|
+
start = shift + diag.span.start
|
|
223
|
+
line, column = line_col(text, start)
|
|
224
|
+
return {
|
|
225
|
+
"code": diag.code,
|
|
226
|
+
"severity": diag.severity.value,
|
|
227
|
+
"message": diag.message,
|
|
228
|
+
"start": start,
|
|
229
|
+
"end": shift + diag.span.end,
|
|
230
|
+
"line": line,
|
|
231
|
+
"column": column,
|
|
232
|
+
"spec_reference": diag.spec_reference,
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
|
|
210
236
|
def _render_json(results: Sequence[_ProjectResult]) -> str:
|
|
211
237
|
payload = []
|
|
212
238
|
for result in results:
|
|
213
239
|
modules = []
|
|
214
240
|
for module_name, diagnostics in result.diagnostics.items():
|
|
215
|
-
|
|
241
|
+
text, shift = _text_as_read(result.modules.get(module_name))
|
|
216
242
|
modules.append(
|
|
217
243
|
{
|
|
218
244
|
"module": module_name,
|
|
219
|
-
"diagnostics": [
|
|
220
|
-
{
|
|
221
|
-
"code": diag.code,
|
|
222
|
-
"severity": diag.severity.value,
|
|
223
|
-
"message": diag.message,
|
|
224
|
-
"start": diag.span.start,
|
|
225
|
-
"end": diag.span.end,
|
|
226
|
-
"line": line_col(source, diag.span.start)[0],
|
|
227
|
-
"column": line_col(source, diag.span.start)[1],
|
|
228
|
-
"spec_reference": diag.spec_reference,
|
|
229
|
-
}
|
|
230
|
-
for diag in diagnostics
|
|
231
|
-
],
|
|
245
|
+
"diagnostics": [_diagnostic_json(diag, text, shift) for diag in diagnostics],
|
|
232
246
|
}
|
|
233
247
|
)
|
|
234
248
|
payload.append({"project": result.label, "modules": modules})
|