Fix handling of null nodes in memoized properties

TN: T203-028
This commit is contained in:
Pierre-Marie de Rodat
2020-02-03 09:06:45 -05:00
parent 1d997331d9
commit 744220fa4f
6 changed files with 92 additions and 8 deletions

View File

@@ -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:

View File

@@ -0,0 +1,12 @@
grammar None_grammar {
main_rule <- Example(@Example)
}
class FooNode {
@export memoized fun prop (): Boolean = true
}
class Example : FooNode {
}

View 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;

View File

@@ -0,0 +1,3 @@
No exception...
main.adb: Done
Done

View 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')

View File

@@ -0,0 +1 @@
driver: python