1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
module
imports
static-semantics/actions/functions
static-semantics/entities/annotations
static-semantics/types/built-ins
static-semantics/ui/actions
static-semantics/ui/attributes
static-semantics/webdsl-actions
static-semantics/webdsl-types
static-semantics/webdsl-ui
static-semantics/webdsl
rules // template calls
templateElementOk(s, _, s_pha, TemplateCall2TemplateElement(tc)) :-
templateCallOk(s, s_pha, tc).
: scope * scope * TemplateCall
ajaxTemplateCallOk(s, s_pha, tc) :- templateCallOk_internal(s, s_pha, tc, TRUE()).
: scope * scope * TemplateCall
templateCallOk(s, s_pha, tc) :- templateCallOk_internal(s, s_pha, tc, FALSE()).
// BOOL denotes if template must be ajax enabled
: scope * scope * TemplateCall * BOOL
templateCallOk_internal(, s_pha, TemplateCall(TemplateCallId(t), TCallArgs(targs), TCallPropAssigns(propAssigns), TemplateBody(body)), ajax) :-
templatePropAssignmentsOk(s, propAssigns),
templateElementsOk(s, s_pha, body),
templateCallMatchesSig(s, t, targs, ajax).
// BOOL denotes if template must be ajax enabled
: scope * string * list(TemplateArgExp) * BOOL
templateCallMatchesSig(, , , ajax) :- { }
argTypes == typesOfTemplateArgExps(s, targs),
inputTemplateCallOk(s, t, targs, argTypes),
nameCompatibleSigs == resolveTemplate_internal(s, t, ajax),
mostSpecificSigs == mostSpecificSigs(argTypes, typeCompatibleSigs(nameCompatibleSigs, argTypes)),
mostSpecificSigs == [(t', TEMPLATE(_, _, _)) | _] | error $[Cannot resolve template [t] with compatible argument types] @t,
singleSignature(mostSpecificSigs, "template", t) | error $[Cannot resolve template [t] with compatible argument types] @t,
@t.ref := t'.
typesOfTemplateArgExps maps typeOfTemplateArgExp(*, list(*)) = list(*)
: scope * TemplateArgExp -> TYPE
typeOfTemplateArgExp(s, Exp(exp)) = typeOfExp(s, exp).
typeOfTemplateArgExp(s, TemplateElementsArgument(exp)) = TEMPLATEELEMENTS().
typeOfTemplateArgExp(s, ExpEntityDerive(_, _)) = UNTYPED() :- // TO-DO
try { false } | warning $[Derive expressions not implemented yet].
rules // pre-defined template calls
// elements
templateCallOk(_, _, TemplateCall(TemplateCallId("elements"), TCallArgs(targs), TCallPropAssigns(propAssigns), TemplateBody(body))) :-
targs == [] | error $[Cannot pass arguments to passed template elements],
body == [] | error $[Cannot pass template elements to passed template elements].
// validation
templateCallOk(s, _, ValidationErrors(_)).
templateCallOk(s, _, ValidationErrorsEmpty()).
// navigatebutton
templateCallOk(s, s_pha, tc@TemplateCall(TemplateCallId("navigatebutton"), TCallArgs([Exp(ThisCall2Exp(ThisCall("url", _))) | _]), _, _)) :-
templateCallOk_internal(s, s_pha, tc, FALSE()).
templateCallOk(, s_pha, tc@TemplateCall(TemplateCallId(t@"navigatebutton"), TCallArgs([Exp(ThisCall2Exp(ThisCall(p, args))) | [Exp(e)]]), _, _)) :-
typeCompatible(typeOfExp(s, e), string(s)) | error $[Cannot resolve template [t] with compatible argument types] @tc,
pageCallOk_internal(s, p, args).
rules // navigate calls
templateElementOk(, _, s_pha, NavigateCall(pc, props, elems)) :-
pageCallOk(s, pc),
templatePropAssignmentsOk(s, props),
templateElementsOk(s, s_pha, elems).
: scope * PageCall
pageCallOk(s, PageCall(p, args)) :-
pageCallOk_internal(s, p, args).
: scope * string * list(Exp)
pageCallOk_internal(, , ) :- { }
pageType(s, p) == PAGE(_, ts) | error $[There is no page with signature [p]] @p, // correct error message for tests
argTypes == typesOfExps(s, args),
typesCompatible(argTypes, ts) == TRUE() | error $[Given argument types not compatible with page definition. Got [argTypes] but expected [ts]] @args.
pageCallOk_internal(_, "root", []). // root page is always accessible from all locations
rules // property assignments
: scope * list(PropertyAssignment)
templatePropAssignmentsOk(s, pas) :- templatePropAssignmentsOkNoDuplicates(s, pas, []).
: scope * list(PropertyAssignment) * list(string)
templatePropAssignmentsOkNoDuplicates(_, [], _).
templatePropAssignmentsOkNoDuplicates(, [pa | pas], ) :- {}
x == templatePropAssignmentOk(s, pa),
noDuplicatesString(x, xs) | error $[Properties are defined multiple times: [x]] @x, // correct error message for tests
templatePropAssignmentsOkNoDuplicates(s, pas, [x | xs]).
: scope * PropertyAssignment -> string // return name of property for duplicate check
templatePropAssignmentOk(s, _) = "_IGNORE" :- // TO-DO
try { false } | warning $[This template property assignment is not implemented yet].
templatePropAssignmentOk(, PropertyAssignment(x, )) = x :-
typeCompatible(typeOfExp(s, e), string(s)) | error $[Property [x] requires a String value] @e.
templatePropAssignmentOk(s, PropertySubmit(x, a)) = x :-
actionCallOrInlineOrExpOk(s, a).
templatePropAssignmentOk(s, AttributeSelection2PropertyAssignment(AttributeIgnoreDefault(c@"class"))) = "_IGNORE".
templatePropAssignmentOk(s, AttributeSelection2PropertyAssignment(AttributeIgnoreDefault(c@"style"))) = "_IGNORE".
templatePropAssignmentOk(s, AttributeSelection2PropertyAssignment(AttributeIgnoreDefault(_))) = "_IGNORE" :-
false | error $[Only "class" and "style" are implicitly combined with defaults].
templatePropAssignmentOk(s, CommonAttribute2PropertyAssignment(ca)) = "_IGNORE" :-
commonAttributeOk(s, ca).
templatePropAssignmentOk(s, AttributeSelection2PropertyAssignment(AttributeSelection())) = "_IGNORE" :- { }
resolveAttributeCollection(s, a) == [(_, a') | _] | error $[Attribute collection [a] is not defined],
@a.ref := a'.
rules // mutability check for input templates
: scope * string * list(TemplateArgExp) * list(TYPE)
inputTemplateCallOk(s, _, _, _). // all other template calls are ok
inputTemplateCallOk(s, "input", [Exp(e) | _], [t | _]) :- isMutableExp(s, e, t).
: scope * Exp * TYPE
isMutableExp(_, , t) :- false | error $[Cannot verify mutability of expression [e]] @e.
isMutableExp(s, Var(x), t) :- isMutableOrRef(s, x, t).
isMutableExp(s, Cast(_, sort), t) :- typeOfSort(s, sort) == REF(_).
isMutableExp(s, FieldAccess(FAVar(var), x), t) :- {}
varType == variableType(s, var),
isMutableProperty(varType, x).
|