diff --git a/blueprintcompiler/language/common.py b/blueprintcompiler/language/common.py index 12dbc52..03cb428 100644 --- a/blueprintcompiler/language/common.py +++ b/blueprintcompiler/language/common.py @@ -24,7 +24,7 @@ from ..errors import CompileError, MultipleErrors from ..completions_utils import * from .. import decompiler as decompile from ..decompiler import DecompileCtx, decompiler -from ..gir import StringType, BoolType, IntType, FloatType, GirType +from ..gir import StringType, BoolType, IntType, FloatType, GirType, Enumeration from ..lsp_utils import Completion, CompletionItemKind, SemanticToken, SemanticTokenType from ..parse_tree import * from ..parser_utils import * diff --git a/blueprintcompiler/language/gtk_a11y.py b/blueprintcompiler/language/gtk_a11y.py index a0e44e0..51a362c 100644 --- a/blueprintcompiler/language/gtk_a11y.py +++ b/blueprintcompiler/language/gtk_a11y.py @@ -94,11 +94,12 @@ def get_types(gir): } def _get_docs(gir, name): - return ( + if gir_type := ( gir.get_type("AccessibleProperty", "Gtk").members.get(name) or gir.get_type("AccessibleRelation", "Gtk").members.get(name) or gir.get_type("AccessibleState", "Gtk").members.get(name) - ).doc + ): + return gir_type.doc class A11yProperty(BaseTypedAttribute): diff --git a/blueprintcompiler/language/values.py b/blueprintcompiler/language/values.py index ce5c406..b17c5bb 100644 --- a/blueprintcompiler/language/values.py +++ b/blueprintcompiler/language/values.py @@ -112,10 +112,10 @@ class Flag(AstNode): @docs() def docs(self): type = self.parent.parent.value_type + if not isinstance(type, Enumeration): + return if member := type.members.get(self.tokens["value"]): return member.doc - else: - return type.doc @validate() def validate_for_type(self): diff --git a/tests/test_samples.py b/tests/test_samples.py index 4c4b17c..908cc27 100644 --- a/tests/test_samples.py +++ b/tests/test_samples.py @@ -24,12 +24,21 @@ import traceback import unittest from blueprintcompiler import tokenizer, parser, decompiler +from blueprintcompiler.completions import complete from blueprintcompiler.errors import PrintableError, MultipleErrors, CompileError from blueprintcompiler.tokenizer import Token, TokenType, tokenize from blueprintcompiler import utils class TestSamples(unittest.TestCase): + def assert_docs_dont_crash(self, text, ast): + for i in range(len(text)): + ast.get_docs(i) + + def assert_completions_dont_crash(self, text, ast, tokens): + for i in range(len(text)): + list(complete(ast, tokens, i)) + def assert_sample(self, name): try: with open((Path(__file__).parent / f"samples/{name}.blp").resolve()) as f: @@ -52,6 +61,9 @@ class TestSamples(unittest.TestCase): diff = difflib.unified_diff(expected.splitlines(), actual.splitlines()) print("\n".join(diff)) raise AssertionError() + + self.assert_docs_dont_crash(blueprint, ast) + self.assert_completions_dont_crash(blueprint, ast, tokens) except PrintableError as e: # pragma: no cover e.pretty_print(name + ".blp", blueprint) raise AssertionError() @@ -67,6 +79,9 @@ class TestSamples(unittest.TestCase): tokens = tokenizer.tokenize(blueprint) ast, errors, warnings = parser.parse(tokens) + self.assert_docs_dont_crash(blueprint, ast) + self.assert_completions_dont_crash(blueprint, ast, tokens) + if errors: raise errors if len(ast.errors):