@@ -521,7 +521,11 @@ functionBody throws XPathException
521
521
:
522
522
( LCURLY RCURLY ) => l:LCURLY^ RCURLY!
523
523
{ #functionBody= #(#l, #(#[PARENTHESIZED, "Parenthesized"], null)); }
524
- | LCURLY^ expr RCURLY!
524
+ | LCURLY^
525
+ { lexer.inFunctionBody = true; }
526
+ expr
527
+ { lexer.inFunctionBody = false; }
528
+ RCURLY!
525
529
;
526
530
527
531
returnType throws XPathException:
@@ -1059,8 +1063,20 @@ unaryExpr throws XPathException
1059
1063
;
1060
1064
1061
1065
valueExpr throws XPathException
1066
+ { Boolean inFunctionBodyState = lexer.inFunctionBody; }
1062
1067
:
1063
- pathExpr (BANG^ pathExpr)*
1068
+ pathExpr (
1069
+ BANG^
1070
+ {
1071
+ // simple map operator might add new document context
1072
+ lexer.inFunctionBody = false;
1073
+ }
1074
+ pathExpr
1075
+ {
1076
+ // reset state
1077
+ lexer.inFunctionBody = inFunctionBodyState;
1078
+ }
1079
+ )*
1064
1080
|
1065
1081
extensionExpr
1066
1082
;
@@ -1111,15 +1127,33 @@ pathExpr throws XPathException
1111
1127
relativePathExpr
1112
1128
|
1113
1129
( SLASH relativePathExpr )
1114
- => SLASH relPath:relativePathExpr
1115
- { #pathExpr= #(#[ABSOLUTE_SLASH, "AbsoluteSlash"], #relPath); }
1130
+ => s1:SLASH relPath:relativePathExpr
1131
+ {
1132
+ if (lexer.inFunctionBody) {
1133
+ throw new XPathException(#s1.getLine(), #s1.getColumn(), ErrorCodes.XPDY0002,
1134
+ "Leading ' / ' selects nothing, ContextItem is absent in function body");
1135
+ }
1136
+ #pathExpr= #(#[ABSOLUTE_SLASH, "AbsoluteSlash"], #relPath);
1137
+ }
1116
1138
// lone slash
1117
1139
|
1118
- SLASH
1119
- { #pathExpr= #[ABSOLUTE_SLASH, "AbsoluteSlash"]; }
1140
+ s2:SLASH
1141
+ {
1142
+ if (lexer.inFunctionBody) {
1143
+ throw new XPathException(#s2.getLine(), #s2.getColumn(), ErrorCodes.XPDY0002,
1144
+ "Leading ' / ' selects nothing, ContextItem is absent in function body");
1145
+ }
1146
+ #pathExpr= #[ABSOLUTE_SLASH, "AbsoluteSlash"];
1147
+ }
1120
1148
|
1121
- DSLASH relPath2:relativePathExpr
1122
- { #pathExpr= #(#[ABSOLUTE_DSLASH, "AbsoluteSlashSlash"], #relPath2); }
1149
+ ds:DSLASH relPath2:relativePathExpr
1150
+ {
1151
+ if (lexer.inFunctionBody) {
1152
+ throw new XPathException(#ds.getLine(), #ds.getColumn(), ErrorCodes.XPDY0002,
1153
+ "Leading ' // ' selects nothing, ContextItem is absent in function body");
1154
+ }
1155
+ #pathExpr= #(#[ABSOLUTE_DSLASH, "AbsoluteSlashSlash"], #relPath2);
1156
+ }
1123
1157
;
1124
1158
1125
1159
relativePathExpr throws XPathException
@@ -2188,6 +2222,7 @@ options {
2188
2222
protected boolean inStringConstructor = false ;
2189
2223
protected boolean inElementContent= false ;
2190
2224
protected boolean inAttributeContent= false ;
2225
+ protected boolean inFunctionBody= false ;
2191
2226
protected char attrDelimChar = ' "' ;
2192
2227
protected boolean inComment= false ;
2193
2228
protected boolean inPragma = false ;
0 commit comments