From 0b83fe425eb26c9839e0ea0459d0c16c4bfd20f2 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Sat, 23 Dec 2023 09:03:47 -0500 Subject: [PATCH] Remove special pre-visit for module docstrings --- .../fixtures/pyflakes/{F404.py => F404_0.py} | 0 .../test/fixtures/pyflakes/F404_1.py | 5 + .../test/fixtures/pyupgrade/UP025.py | 36 +- crates/ruff_linter/src/checkers/ast/mod.rs | 22 +- crates/ruff_linter/src/rules/pyflakes/mod.rs | 3 +- ...les__pyflakes__tests__F404_F404_0.py.snap} | 2 +- ...ules__pyflakes__tests__F404_F404_1.py.snap | 12 + ...er__rules__pyupgrade__tests__UP025.py.snap | 366 +++++++++--------- crates/ruff_python_semantic/src/model.rs | 15 +- 9 files changed, 252 insertions(+), 209 deletions(-) rename crates/ruff_linter/resources/test/fixtures/pyflakes/{F404.py => F404_0.py} (100%) create mode 100644 crates/ruff_linter/resources/test/fixtures/pyflakes/F404_1.py rename crates/ruff_linter/src/rules/pyflakes/snapshots/{ruff_linter__rules__pyflakes__tests__F404_F404.py.snap => ruff_linter__rules__pyflakes__tests__F404_F404_0.py.snap} (72%) create mode 100644 crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F404_F404_1.py.snap diff --git a/crates/ruff_linter/resources/test/fixtures/pyflakes/F404.py b/crates/ruff_linter/resources/test/fixtures/pyflakes/F404_0.py similarity index 100% rename from crates/ruff_linter/resources/test/fixtures/pyflakes/F404.py rename to crates/ruff_linter/resources/test/fixtures/pyflakes/F404_0.py diff --git a/crates/ruff_linter/resources/test/fixtures/pyflakes/F404_1.py b/crates/ruff_linter/resources/test/fixtures/pyflakes/F404_1.py new file mode 100644 index 00000000000000..97b4292da91fa8 --- /dev/null +++ b/crates/ruff_linter/resources/test/fixtures/pyflakes/F404_1.py @@ -0,0 +1,5 @@ +"""Docstring""" + +"""Non-docstring""" + +from __future__ import absolute_import diff --git a/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP025.py b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP025.py index d53c197a1f65aa..899f827f808668 100644 --- a/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP025.py +++ b/crates/ruff_linter/resources/test/fixtures/pyupgrade/UP025.py @@ -1,30 +1,28 @@ -# These should change -x = u"Hello" +u"Hello" -u'world' +x = u"Hello" # UP025 -print(u"Hello") +u'world' # UP025 -print(u'world') +print(u"Hello") # UP025 -import foo - -foo(u"Hello", U"world", a=u"Hello", b=u"world") +print(u'world') # UP025 -# These should stay quoted they way they are +import foo -x = u'hello' -x = u"""hello""" -x = u'''hello''' -x = u'Hello "World"' +foo(u"Hello", U"world", a=u"Hello", b=u"world") # UP025 -# These should not change -u = "Hello" +# Retain quotes when fixing. +x = u'hello' # UP025 +x = u"""hello""" # UP025 +x = u'''hello''' # UP025 +x = u'Hello "World"' # UP025 -u = u +u = "Hello" # OK +u = u # OK def hello(): - return"Hello" + return"Hello" # OK -f"foo"u"bar" -f"foo" u"bar" +f"foo"u"bar" # OK +f"foo" u"bar" # OK diff --git a/crates/ruff_linter/src/checkers/ast/mod.rs b/crates/ruff_linter/src/checkers/ast/mod.rs index fa47d9c77cc445..8c95d3a9dd7ec4 100644 --- a/crates/ruff_linter/src/checkers/ast/mod.rs +++ b/crates/ruff_linter/src/checkers/ast/mod.rs @@ -287,6 +287,15 @@ where // Track whether we've seen docstrings, non-imports, etc. match stmt { + Stmt::Expr(ast::StmtExpr { value, .. }) + if !self + .semantic + .flags + .intersects(SemanticModelFlags::MODULE_DOCSTRING) + && value.is_string_literal_expr() => + { + self.semantic.flags |= SemanticModelFlags::MODULE_DOCSTRING; + } Stmt::ImportFrom(ast::StmtImportFrom { module, names, .. }) => { // Allow __future__ imports until we see a non-__future__ import. if let Some("__future__") = module.as_deref() { @@ -1435,11 +1444,8 @@ where impl<'a> Checker<'a> { /// Visit a [`Module`]. Returns `true` if the module contains a module-level docstring. - fn visit_module(&mut self, python_ast: &'a Suite) -> bool { + fn visit_module(&mut self, python_ast: &'a Suite) { analyze::module(python_ast, self); - - let docstring = docstrings::extraction::docstring_from(python_ast); - docstring.is_some() } /// Visit a list of [`Comprehension`] nodes, assumed to be the comprehensions that compose a @@ -2006,14 +2012,8 @@ pub(crate) fn check_ast( ); checker.bind_builtins(); - // Check for module docstring. - let python_ast = if checker.visit_module(python_ast) { - &python_ast[1..] - } else { - python_ast - }; - // Iterate over the AST. + checker.visit_module(python_ast); checker.visit_body(python_ast); // Visit any deferred syntax nodes. Take care to visit in order, such that we avoid adding diff --git a/crates/ruff_linter/src/rules/pyflakes/mod.rs b/crates/ruff_linter/src/rules/pyflakes/mod.rs index 721e7dceb72563..e4a313f54b40db 100644 --- a/crates/ruff_linter/src/rules/pyflakes/mod.rs +++ b/crates/ruff_linter/src/rules/pyflakes/mod.rs @@ -55,7 +55,8 @@ mod tests { #[test_case(Rule::UnusedImport, Path::new("F401_20.py"))] #[test_case(Rule::ImportShadowedByLoopVar, Path::new("F402.py"))] #[test_case(Rule::UndefinedLocalWithImportStar, Path::new("F403.py"))] - #[test_case(Rule::LateFutureImport, Path::new("F404.py"))] + #[test_case(Rule::LateFutureImport, Path::new("F404_0.py"))] + #[test_case(Rule::LateFutureImport, Path::new("F404_1.py"))] #[test_case(Rule::UndefinedLocalWithImportStarUsage, Path::new("F405.py"))] #[test_case(Rule::UndefinedLocalWithNestedImportStarUsage, Path::new("F406.py"))] #[test_case(Rule::FutureFeatureNotDefined, Path::new("F407.py"))] diff --git a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F404_F404.py.snap b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F404_F404_0.py.snap similarity index 72% rename from crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F404_F404.py.snap rename to crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F404_F404_0.py.snap index fee99fc907f0d4..6934119f5b95ad 100644 --- a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F404_F404.py.snap +++ b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F404_F404_0.py.snap @@ -1,7 +1,7 @@ --- source: crates/ruff_linter/src/rules/pyflakes/mod.rs --- -F404.py:6:1: F404 `from __future__` imports must occur at the beginning of the file +F404_0.py:6:1: F404 `from __future__` imports must occur at the beginning of the file | 4 | from collections import namedtuple 5 | diff --git a/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F404_F404_1.py.snap b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F404_F404_1.py.snap new file mode 100644 index 00000000000000..c9fbd78db83dda --- /dev/null +++ b/crates/ruff_linter/src/rules/pyflakes/snapshots/ruff_linter__rules__pyflakes__tests__F404_F404_1.py.snap @@ -0,0 +1,12 @@ +--- +source: crates/ruff_linter/src/rules/pyflakes/mod.rs +--- +F404_1.py:5:1: F404 `from __future__` imports must occur at the beginning of the file + | +3 | """Non-docstring""" +4 | +5 | from __future__ import absolute_import + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ F404 + | + + diff --git a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP025.py.snap b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP025.py.snap index 256e6222ec3295..e5cd73cc97314c 100644 --- a/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP025.py.snap +++ b/crates/ruff_linter/src/rules/pyupgrade/snapshots/ruff_linter__rules__pyupgrade__tests__UP025.py.snap @@ -1,284 +1,302 @@ --- source: crates/ruff_linter/src/rules/pyupgrade/mod.rs --- -UP025.py:2:5: UP025 [*] Remove unicode literals from strings +UP025.py:1:1: UP025 [*] Remove unicode literals from strings | -1 | # These should change -2 | x = u"Hello" +1 | u"Hello" + | ^^^^^^^^ UP025 +2 | +3 | x = u"Hello" # UP025 + | + = help: Remove unicode prefix + +ℹ Safe fix +1 |-u"Hello" + 1 |+"Hello" +2 2 | +3 3 | x = u"Hello" # UP025 +4 4 | + +UP025.py:3:5: UP025 [*] Remove unicode literals from strings + | +1 | u"Hello" +2 | +3 | x = u"Hello" # UP025 | ^^^^^^^^ UP025 -3 | -4 | u'world' +4 | +5 | u'world' # UP025 | = help: Remove unicode prefix ℹ Safe fix -1 1 | # These should change -2 |-x = u"Hello" - 2 |+x = "Hello" -3 3 | -4 4 | u'world' -5 5 | +1 1 | u"Hello" +2 2 | +3 |-x = u"Hello" # UP025 + 3 |+x = "Hello" # UP025 +4 4 | +5 5 | u'world' # UP025 +6 6 | -UP025.py:4:1: UP025 [*] Remove unicode literals from strings +UP025.py:5:1: UP025 [*] Remove unicode literals from strings | -2 | x = u"Hello" -3 | -4 | u'world' +3 | x = u"Hello" # UP025 +4 | +5 | u'world' # UP025 | ^^^^^^^^ UP025 -5 | -6 | print(u"Hello") +6 | +7 | print(u"Hello") # UP025 | = help: Remove unicode prefix ℹ Safe fix -1 1 | # These should change -2 2 | x = u"Hello" -3 3 | -4 |-u'world' - 4 |+'world' -5 5 | -6 6 | print(u"Hello") -7 7 | +2 2 | +3 3 | x = u"Hello" # UP025 +4 4 | +5 |-u'world' # UP025 + 5 |+'world' # UP025 +6 6 | +7 7 | print(u"Hello") # UP025 +8 8 | -UP025.py:6:7: UP025 [*] Remove unicode literals from strings +UP025.py:7:7: UP025 [*] Remove unicode literals from strings | -4 | u'world' -5 | -6 | print(u"Hello") +5 | u'world' # UP025 +6 | +7 | print(u"Hello") # UP025 | ^^^^^^^^ UP025 -7 | -8 | print(u'world') +8 | +9 | print(u'world') # UP025 | = help: Remove unicode prefix ℹ Safe fix -3 3 | -4 4 | u'world' -5 5 | -6 |-print(u"Hello") - 6 |+print("Hello") -7 7 | -8 8 | print(u'world') -9 9 | +4 4 | +5 5 | u'world' # UP025 +6 6 | +7 |-print(u"Hello") # UP025 + 7 |+print("Hello") # UP025 +8 8 | +9 9 | print(u'world') # UP025 +10 10 | -UP025.py:8:7: UP025 [*] Remove unicode literals from strings +UP025.py:9:7: UP025 [*] Remove unicode literals from strings | - 6 | print(u"Hello") - 7 | - 8 | print(u'world') + 7 | print(u"Hello") # UP025 + 8 | + 9 | print(u'world') # UP025 | ^^^^^^^^ UP025 - 9 | -10 | import foo +10 | +11 | import foo | = help: Remove unicode prefix ℹ Safe fix -5 5 | -6 6 | print(u"Hello") -7 7 | -8 |-print(u'world') - 8 |+print('world') -9 9 | -10 10 | import foo -11 11 | +6 6 | +7 7 | print(u"Hello") # UP025 +8 8 | +9 |-print(u'world') # UP025 + 9 |+print('world') # UP025 +10 10 | +11 11 | import foo +12 12 | -UP025.py:12:5: UP025 [*] Remove unicode literals from strings +UP025.py:13:5: UP025 [*] Remove unicode literals from strings | -10 | import foo -11 | -12 | foo(u"Hello", U"world", a=u"Hello", b=u"world") +11 | import foo +12 | +13 | foo(u"Hello", U"world", a=u"Hello", b=u"world") # UP025 | ^^^^^^^^ UP025 -13 | -14 | # These should stay quoted they way they are +14 | +15 | # Retain quotes when fixing. | = help: Remove unicode prefix ℹ Safe fix -9 9 | -10 10 | import foo -11 11 | -12 |-foo(u"Hello", U"world", a=u"Hello", b=u"world") - 12 |+foo("Hello", U"world", a=u"Hello", b=u"world") -13 13 | -14 14 | # These should stay quoted they way they are -15 15 | +10 10 | +11 11 | import foo +12 12 | +13 |-foo(u"Hello", U"world", a=u"Hello", b=u"world") # UP025 + 13 |+foo("Hello", U"world", a=u"Hello", b=u"world") # UP025 +14 14 | +15 15 | # Retain quotes when fixing. +16 16 | x = u'hello' # UP025 -UP025.py:12:15: UP025 [*] Remove unicode literals from strings +UP025.py:13:15: UP025 [*] Remove unicode literals from strings | -10 | import foo -11 | -12 | foo(u"Hello", U"world", a=u"Hello", b=u"world") +11 | import foo +12 | +13 | foo(u"Hello", U"world", a=u"Hello", b=u"world") # UP025 | ^^^^^^^^ UP025 -13 | -14 | # These should stay quoted they way they are +14 | +15 | # Retain quotes when fixing. | = help: Remove unicode prefix ℹ Safe fix -9 9 | -10 10 | import foo -11 11 | -12 |-foo(u"Hello", U"world", a=u"Hello", b=u"world") - 12 |+foo(u"Hello", "world", a=u"Hello", b=u"world") -13 13 | -14 14 | # These should stay quoted they way they are -15 15 | +10 10 | +11 11 | import foo +12 12 | +13 |-foo(u"Hello", U"world", a=u"Hello", b=u"world") # UP025 + 13 |+foo(u"Hello", "world", a=u"Hello", b=u"world") # UP025 +14 14 | +15 15 | # Retain quotes when fixing. +16 16 | x = u'hello' # UP025 -UP025.py:12:27: UP025 [*] Remove unicode literals from strings +UP025.py:13:27: UP025 [*] Remove unicode literals from strings | -10 | import foo -11 | -12 | foo(u"Hello", U"world", a=u"Hello", b=u"world") +11 | import foo +12 | +13 | foo(u"Hello", U"world", a=u"Hello", b=u"world") # UP025 | ^^^^^^^^ UP025 -13 | -14 | # These should stay quoted they way they are +14 | +15 | # Retain quotes when fixing. | = help: Remove unicode prefix ℹ Safe fix -9 9 | -10 10 | import foo -11 11 | -12 |-foo(u"Hello", U"world", a=u"Hello", b=u"world") - 12 |+foo(u"Hello", U"world", a="Hello", b=u"world") -13 13 | -14 14 | # These should stay quoted they way they are -15 15 | +10 10 | +11 11 | import foo +12 12 | +13 |-foo(u"Hello", U"world", a=u"Hello", b=u"world") # UP025 + 13 |+foo(u"Hello", U"world", a="Hello", b=u"world") # UP025 +14 14 | +15 15 | # Retain quotes when fixing. +16 16 | x = u'hello' # UP025 -UP025.py:12:39: UP025 [*] Remove unicode literals from strings +UP025.py:13:39: UP025 [*] Remove unicode literals from strings | -10 | import foo -11 | -12 | foo(u"Hello", U"world", a=u"Hello", b=u"world") +11 | import foo +12 | +13 | foo(u"Hello", U"world", a=u"Hello", b=u"world") # UP025 | ^^^^^^^^ UP025 -13 | -14 | # These should stay quoted they way they are +14 | +15 | # Retain quotes when fixing. | = help: Remove unicode prefix ℹ Safe fix -9 9 | -10 10 | import foo -11 11 | -12 |-foo(u"Hello", U"world", a=u"Hello", b=u"world") - 12 |+foo(u"Hello", U"world", a=u"Hello", b="world") -13 13 | -14 14 | # These should stay quoted they way they are -15 15 | +10 10 | +11 11 | import foo +12 12 | +13 |-foo(u"Hello", U"world", a=u"Hello", b=u"world") # UP025 + 13 |+foo(u"Hello", U"world", a=u"Hello", b="world") # UP025 +14 14 | +15 15 | # Retain quotes when fixing. +16 16 | x = u'hello' # UP025 UP025.py:16:5: UP025 [*] Remove unicode literals from strings | -14 | # These should stay quoted they way they are -15 | -16 | x = u'hello' +15 | # Retain quotes when fixing. +16 | x = u'hello' # UP025 | ^^^^^^^^ UP025 -17 | x = u"""hello""" -18 | x = u'''hello''' +17 | x = u"""hello""" # UP025 +18 | x = u'''hello''' # UP025 | = help: Remove unicode prefix ℹ Safe fix -13 13 | -14 14 | # These should stay quoted they way they are -15 15 | -16 |-x = u'hello' - 16 |+x = 'hello' -17 17 | x = u"""hello""" -18 18 | x = u'''hello''' -19 19 | x = u'Hello "World"' +13 13 | foo(u"Hello", U"world", a=u"Hello", b=u"world") # UP025 +14 14 | +15 15 | # Retain quotes when fixing. +16 |-x = u'hello' # UP025 + 16 |+x = 'hello' # UP025 +17 17 | x = u"""hello""" # UP025 +18 18 | x = u'''hello''' # UP025 +19 19 | x = u'Hello "World"' # UP025 UP025.py:17:5: UP025 [*] Remove unicode literals from strings | -16 | x = u'hello' -17 | x = u"""hello""" +15 | # Retain quotes when fixing. +16 | x = u'hello' # UP025 +17 | x = u"""hello""" # UP025 | ^^^^^^^^^^^^ UP025 -18 | x = u'''hello''' -19 | x = u'Hello "World"' +18 | x = u'''hello''' # UP025 +19 | x = u'Hello "World"' # UP025 | = help: Remove unicode prefix ℹ Safe fix -14 14 | # These should stay quoted they way they are -15 15 | -16 16 | x = u'hello' -17 |-x = u"""hello""" - 17 |+x = """hello""" -18 18 | x = u'''hello''' -19 19 | x = u'Hello "World"' +14 14 | +15 15 | # Retain quotes when fixing. +16 16 | x = u'hello' # UP025 +17 |-x = u"""hello""" # UP025 + 17 |+x = """hello""" # UP025 +18 18 | x = u'''hello''' # UP025 +19 19 | x = u'Hello "World"' # UP025 20 20 | UP025.py:18:5: UP025 [*] Remove unicode literals from strings | -16 | x = u'hello' -17 | x = u"""hello""" -18 | x = u'''hello''' +16 | x = u'hello' # UP025 +17 | x = u"""hello""" # UP025 +18 | x = u'''hello''' # UP025 | ^^^^^^^^^^^^ UP025 -19 | x = u'Hello "World"' +19 | x = u'Hello "World"' # UP025 | = help: Remove unicode prefix ℹ Safe fix -15 15 | -16 16 | x = u'hello' -17 17 | x = u"""hello""" -18 |-x = u'''hello''' - 18 |+x = '''hello''' -19 19 | x = u'Hello "World"' +15 15 | # Retain quotes when fixing. +16 16 | x = u'hello' # UP025 +17 17 | x = u"""hello""" # UP025 +18 |-x = u'''hello''' # UP025 + 18 |+x = '''hello''' # UP025 +19 19 | x = u'Hello "World"' # UP025 20 20 | -21 21 | # These should not change +21 21 | u = "Hello" # OK UP025.py:19:5: UP025 [*] Remove unicode literals from strings | -17 | x = u"""hello""" -18 | x = u'''hello''' -19 | x = u'Hello "World"' +17 | x = u"""hello""" # UP025 +18 | x = u'''hello''' # UP025 +19 | x = u'Hello "World"' # UP025 | ^^^^^^^^^^^^^^^^ UP025 20 | -21 | # These should not change +21 | u = "Hello" # OK | = help: Remove unicode prefix ℹ Safe fix -16 16 | x = u'hello' -17 17 | x = u"""hello""" -18 18 | x = u'''hello''' -19 |-x = u'Hello "World"' - 19 |+x = 'Hello "World"' +16 16 | x = u'hello' # UP025 +17 17 | x = u"""hello""" # UP025 +18 18 | x = u'''hello''' # UP025 +19 |-x = u'Hello "World"' # UP025 + 19 |+x = 'Hello "World"' # UP025 20 20 | -21 21 | # These should not change -22 22 | u = "Hello" +21 21 | u = "Hello" # OK +22 22 | u = u # OK -UP025.py:29:7: UP025 [*] Remove unicode literals from strings +UP025.py:27:7: UP025 [*] Remove unicode literals from strings | -27 | return"Hello" -28 | -29 | f"foo"u"bar" +25 | return"Hello" # OK +26 | +27 | f"foo"u"bar" # OK | ^^^^^^ UP025 -30 | f"foo" u"bar" +28 | f"foo" u"bar" # OK | = help: Remove unicode prefix ℹ Safe fix -26 26 | def hello(): -27 27 | return"Hello" -28 28 | -29 |-f"foo"u"bar" - 29 |+f"foo""bar" -30 30 | f"foo" u"bar" +24 24 | def hello(): +25 25 | return"Hello" # OK +26 26 | +27 |-f"foo"u"bar" # OK + 27 |+f"foo""bar" # OK +28 28 | f"foo" u"bar" # OK -UP025.py:30:8: UP025 [*] Remove unicode literals from strings +UP025.py:28:8: UP025 [*] Remove unicode literals from strings | -29 | f"foo"u"bar" -30 | f"foo" u"bar" +27 | f"foo"u"bar" # OK +28 | f"foo" u"bar" # OK | ^^^^^^ UP025 | = help: Remove unicode prefix ℹ Safe fix -27 27 | return"Hello" -28 28 | -29 29 | f"foo"u"bar" -30 |-f"foo" u"bar" - 30 |+f"foo" "bar" +25 25 | return"Hello" # OK +26 26 | +27 27 | f"foo"u"bar" # OK +28 |-f"foo" u"bar" # OK + 28 |+f"foo" "bar" # OK diff --git a/crates/ruff_python_semantic/src/model.rs b/crates/ruff_python_semantic/src/model.rs index fd20a4714cda1d..65dd5e6ae0bcdc 100644 --- a/crates/ruff_python_semantic/src/model.rs +++ b/crates/ruff_python_semantic/src/model.rs @@ -1715,6 +1715,16 @@ bitflags! { /// ``` const FUTURE_ANNOTATIONS = 1 << 15; + /// The model has traversed past the module docstring. + /// + /// For example, the model could be visiting `x` in: + /// ```python + /// """Module docstring.""" + /// + /// x: int = 1 + /// ``` + const MODULE_DOCSTRING = 1 << 16; + /// The model is in a type parameter definition. /// /// For example, the model could be visiting `Record` in: @@ -1723,11 +1733,10 @@ bitflags! { /// /// Record = TypeVar("Record") /// - const TYPE_PARAM_DEFINITION = 1 << 16; + const TYPE_PARAM_DEFINITION = 1 << 17; /// The context is in any type annotation. - const ANNOTATION = Self::TYPING_ONLY_ANNOTATION.bits() | Self::RUNTIME_EVALUATED_ANNOTATION.bits() | Self::RUNTIME_REQUIRED_ANNOTATION.bits(); - + const ANNOTATION = Self::TYPING_ONLY_ANNOTATION.bits() | Self::RUNTIME_EVALUATED_ANNOTATION.bits() | Self::RUNTIME_REQUIRED_ANNOTATION.bits(); /// The context is in any string type definition. const STRING_TYPE_DEFINITION = Self::SIMPLE_STRING_TYPE_DEFINITION.bits()