mirror of
https://github.com/AdaCore/langkit.git
synced 2026-02-12 12:28:12 -08:00
Fix handling of null nodes in memoized properties
TN: T203-028
This commit is contained in:
@@ -143,7 +143,7 @@ begin
|
||||
## If this property uses env, we want to make sure lexical env caches are up
|
||||
## to date.
|
||||
% if property.uses_envs:
|
||||
if Node /= null then
|
||||
if Self /= null then
|
||||
Reset_Caches (Self.Unit);
|
||||
|
||||
## And if it is also public, we need to ensure that lexical
|
||||
@@ -155,6 +155,10 @@ begin
|
||||
% endif
|
||||
|
||||
% if memoized:
|
||||
if Self = null then
|
||||
raise Property_Error with "property called on null node";
|
||||
end if;
|
||||
|
||||
## If memoization is enabled for this property, look for an already
|
||||
## computed result for this property. See the declaration of
|
||||
## Analysis_Context_Type.In_Populate_Lexical_Env for the rationale about
|
||||
@@ -295,16 +299,18 @@ exception
|
||||
% endif
|
||||
|
||||
% if memoized:
|
||||
% if not property.memoize_in_populate:
|
||||
if not Self.Unit.Context.In_Populate_Lexical_Env then
|
||||
% endif
|
||||
if Self /= null then
|
||||
% if not property.memoize_in_populate:
|
||||
if not Self.Unit.Context.In_Populate_Lexical_Env then
|
||||
% endif
|
||||
|
||||
Add_Memoized_Value
|
||||
(Self.Unit, Mmz_Handle, (Kind => Mmz_Property_Error));
|
||||
Add_Memoized_Value
|
||||
(Self.Unit, Mmz_Handle, (Kind => Mmz_Property_Error));
|
||||
|
||||
% if not property.memoize_in_populate:
|
||||
% if not property.memoize_in_populate:
|
||||
end if;
|
||||
% endif
|
||||
end if;
|
||||
% endif
|
||||
% endif
|
||||
|
||||
% if has_logging:
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
grammar None_grammar {
|
||||
main_rule <- Example(@Example)
|
||||
|
||||
}
|
||||
|
||||
class FooNode {
|
||||
|
||||
@export memoized fun prop (): Boolean = true
|
||||
}
|
||||
|
||||
class Example : FooNode {
|
||||
}
|
||||
33
testsuite/tests/properties/mmz_on_null/main.adb
Normal file
33
testsuite/tests/properties/mmz_on_null/main.adb
Normal file
@@ -0,0 +1,33 @@
|
||||
with Ada.Exceptions; use Ada.Exceptions;
|
||||
with Ada.Text_IO; use Ada.Text_IO;
|
||||
|
||||
with Langkit_Support.Diagnostics; use Langkit_Support.Diagnostics;
|
||||
|
||||
with Libfoolang.Analysis; use Libfoolang.Analysis;
|
||||
with Libfoolang.Common; use Libfoolang.Common;
|
||||
|
||||
procedure Main is
|
||||
Ctx : constant Analysis_Context := Create_Context;
|
||||
Unit : constant Analysis_Unit :=
|
||||
Get_From_Buffer (Ctx, "foo.txt", Buffer => "example");
|
||||
begin
|
||||
if Has_Diagnostics (Unit) then
|
||||
for D of Diagnostics (Unit) loop
|
||||
Put_Line (To_Pretty_String (D));
|
||||
end loop;
|
||||
raise Program_Error;
|
||||
end if;
|
||||
|
||||
declare
|
||||
Dummy : Boolean;
|
||||
begin
|
||||
Dummy := Unit.Root.P_Prop;
|
||||
Put_Line ("No exception...");
|
||||
exception
|
||||
when Exc : Property_Error =>
|
||||
Put_Line ("Got an exception!");
|
||||
Put_Line (Exception_Name (Exc) & ": " & Exception_Message (Exc));
|
||||
end;
|
||||
|
||||
Put_Line ("main.adb: Done");
|
||||
end Main;
|
||||
3
testsuite/tests/properties/mmz_on_null/test.out
Normal file
3
testsuite/tests/properties/mmz_on_null/test.out
Normal file
@@ -0,0 +1,3 @@
|
||||
No exception...
|
||||
main.adb: Done
|
||||
Done
|
||||
29
testsuite/tests/properties/mmz_on_null/test.py
Normal file
29
testsuite/tests/properties/mmz_on_null/test.py
Normal file
@@ -0,0 +1,29 @@
|
||||
"""
|
||||
Test that calling a memoized property on a null node triggers the expected
|
||||
error.
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
from langkit.dsl import ASTNode
|
||||
from langkit.expressions import langkit_property
|
||||
from langkit.parsers import Grammar
|
||||
|
||||
from utils import build_and_run
|
||||
|
||||
|
||||
class FooNode(ASTNode):
|
||||
|
||||
@langkit_property(public=True, memoized=True)
|
||||
def prop():
|
||||
return True
|
||||
|
||||
|
||||
class Example(FooNode):
|
||||
pass
|
||||
|
||||
|
||||
g = Grammar('main_rule')
|
||||
g.add_rules(main_rule=Example('example'))
|
||||
build_and_run(g, ada_main='main.adb')
|
||||
print('Done')
|
||||
1
testsuite/tests/properties/mmz_on_null/test.yaml
Normal file
1
testsuite/tests/properties/mmz_on_null/test.yaml
Normal file
@@ -0,0 +1 @@
|
||||
driver: python
|
||||
Reference in New Issue
Block a user