@@ -2073,23 +2073,18 @@ private Test nodeTest(final NodeType type, final boolean all) throws QueryExcept
2073
2073
int p = pos ;
2074
2074
if (consume ('*' )) {
2075
2075
p = pos ;
2076
- if (consume (':' )) {
2077
- if (!consume ('*' )) {
2078
- // name test: *:name
2079
- return new NameTest (new QNm (ncName (QNAME_X )), NamePart .LOCAL , type , sc .elemNS );
2080
- }
2076
+ if (consume (':' ) && !consume ('*' )) {
2077
+ // name test: *:name
2078
+ return new NameTest (new QNm (ncName (QNAME_X )), NamePart .LOCAL , type , sc .elemNS );
2081
2079
}
2082
2080
// name test: *
2083
2081
pos = p ;
2084
2082
return KindTest .get (type );
2085
2083
}
2086
-
2087
2084
if (consume (EQNAME )) {
2085
+ // name test: Q{uri}*
2088
2086
final byte [] uri = bracedURILiteral ();
2089
- if (consume ('*' )) {
2090
- // name test: Q{uri}*
2091
- return new NameTest (new QNm (COLON , uri ), NamePart .URI , type , sc .elemNS );
2092
- }
2087
+ if (consume ('*' )) return new NameTest (new QNm (COLON , uri ), NamePart .URI , type , sc .elemNS );
2093
2088
}
2094
2089
pos = p ;
2095
2090
@@ -2098,23 +2093,23 @@ private Test nodeTest(final NodeType type, final boolean all) throws QueryExcept
2098
2093
if (name != null ) {
2099
2094
p = pos ;
2100
2095
if (all && wsConsumeWs (PAREN1 )) {
2101
- // kind test
2102
2096
final NodeType nt = NodeType .find (name );
2103
2097
if (nt != null ) {
2098
+ // kind test
2104
2099
final Test test = kindTest (nt );
2105
2100
return test == null ? KindTest .get (nt ) : test ;
2106
2101
}
2107
2102
} else {
2108
2103
pos = p ;
2104
+ NamePart part = NamePart .FULL ;
2109
2105
if (!name .hasPrefix () && consume (COLWC )) {
2110
2106
// name test: prefix:*
2111
2107
name = new QNm (concat (name .string (), COLON ));
2112
- qnames .add (name , type == NodeType .ELEMENT , ii );
2113
- return new NameTest (name , NamePart .URI , type , sc .elemNS );
2108
+ part = NamePart .URI ;
2114
2109
}
2115
2110
// name test: prefix:name, name, Q{uri}name
2116
2111
qnames .add (name , type == NodeType .ELEMENT , ii );
2117
- return new NameTest (name , NamePart . FULL , type , sc .elemNS );
2112
+ return new NameTest (name , part , type , sc .elemNS );
2118
2113
}
2119
2114
}
2120
2115
pos = p ;
@@ -2309,10 +2304,10 @@ private Expr functionItem() throws QueryException {
2309
2304
body = enclosedExpr ();
2310
2305
} else if (curr ('{' )) {
2311
2306
final InputInfo ii = info ();
2312
- final QNm qnm = new QNm ("arg" );
2313
- final Var var = new Var (qnm , SeqType .ITEM_O , true , qc , sc , ii );
2307
+ final QNm name = new QNm ("arg" );
2308
+ final Var var = new Var (name , SeqType .ITEM_O , true , qc , sc , ii );
2314
2309
params = new Var [] { localVars .add (var ) };
2315
- body = new CachedMap (ii , localVars .resolve (qnm , ii ), enclosedExpr ());
2310
+ body = new CachedMap (ii , localVars .resolve (name , ii ), enclosedExpr ());
2316
2311
}
2317
2312
final VarScope vs = localVars .popContext ();
2318
2313
if (body != null ) return new Closure (info (), type , params , body , anns , global , vs );
@@ -3090,57 +3085,48 @@ private SeqType sequenceType() throws QueryException {
3090
3085
* @throws QueryException query exception
3091
3086
*/
3092
3087
private SeqType itemType () throws QueryException {
3093
- skipWs ();
3094
-
3095
3088
// parenthesized item type
3096
- if (consume (PAREN1 )) {
3097
- final SeqType type = itemType ();
3089
+ if (wsConsume (PAREN1 )) {
3090
+ final SeqType st = itemType ();
3098
3091
wsCheck (PAREN2 );
3099
- return type ;
3092
+ return st ;
3100
3093
}
3101
3094
3102
- // parse optional annotation and type name
3095
+ // parse annotations and type name
3103
3096
final AnnList anns = annotations (false ).check (false , false );
3104
3097
final QNm name = eQName (null , TYPEINVALID );
3105
- skipWs ();
3106
- // check if name is followed by parentheses
3107
- final boolean func = curr ('(' );
3108
3098
3109
- // item type
3099
+ // parse type
3100
+ SeqType st = null ;
3110
3101
Type type = null ;
3111
- if (func ) {
3112
- consume (PAREN1 );
3113
- // item type
3114
- if (name .eq (AtomType .ITEM .qname ())) type = AtomType .ITEM ;
3115
- // node types
3116
- if (type == null ) type = NodeType .find (name );
3117
- // function types
3118
- if (type == null ) {
3119
- type = FuncType .find (name );
3120
- if (type != null ) return functionTest (anns , type ).seqType ();
3102
+ if (wsConsume (PAREN1 )) {
3103
+ // function type
3104
+ type = FuncType .find (name );
3105
+ if (type != null ) return functionTest (anns , type ).seqType ();
3106
+ // node type
3107
+ type = NodeType .find (name );
3108
+ if (type != null ) {
3109
+ // extended node type
3110
+ if (!wsConsume (PAREN2 )) st = SeqType .get (type , Occ .EXACTLY_ONE , kindTest ((NodeType ) type ));
3111
+ } else if (name .eq (AtomType .ITEM .qname ())) {
3112
+ // item type
3113
+ type = AtomType .ITEM ;
3114
+ wsCheck (PAREN2 );
3121
3115
}
3122
3116
// no type found
3123
3117
if (type == null ) throw error (WHICHTYPE_X , FuncType .similar (name ));
3124
3118
} else {
3125
3119
// attach default element namespace
3126
3120
if (!name .hasURI ()) name .uri (sc .elemNS );
3127
- // atomic types
3121
+ // atomic type
3128
3122
type = AtomType .find (name , false );
3129
3123
// no type found
3130
3124
if (type == null ) throw error (TYPEUNKNOWN_X , AtomType .similar (name ));
3131
3125
}
3132
-
3133
3126
// annotations are not allowed for remaining types
3134
3127
if (!anns .isEmpty ()) throw error (NOANN );
3135
3128
3136
- // atomic value, or closing parenthesis
3137
- if (!func || wsConsume (PAREN2 )) return type .seqType ();
3138
-
3139
- // raise error if type different to node is not finalized by a parenthesis
3140
- if (!(type instanceof NodeType )) wsCheck (PAREN2 );
3141
-
3142
- // return type with an optional kind test for node types
3143
- return SeqType .get (type , Occ .EXACTLY_ONE , kindTest ((NodeType ) type ));
3129
+ return st != null ? st : type .seqType ();
3144
3130
}
3145
3131
3146
3132
/**
@@ -3152,7 +3138,7 @@ private SeqType itemType() throws QueryException {
3152
3138
*/
3153
3139
private Type functionTest (final AnnList anns , final Type type ) throws QueryException {
3154
3140
// wildcard
3155
- if (wsConsume (ASTERISK )) {
3141
+ if (wsConsume (WILDCARD )) {
3156
3142
wsCheck (PAREN2 );
3157
3143
return type ;
3158
3144
}
@@ -3194,12 +3180,12 @@ private Test kindTest(final NodeType type) throws QueryException {
3194
3180
final Test tp ;
3195
3181
switch (type ) {
3196
3182
case DOCUMENT_NODE : tp = documentTest (); break ;
3197
- case ELEMENT : tp = elemAttrTest ( type ); break ;
3183
+ case ELEMENT :
3198
3184
case ATTRIBUTE : tp = elemAttrTest (type ); break ;
3199
- case PROCESSING_INSTRUCTION : tp = piTest (); break ;
3185
+ case PROCESSING_INSTRUCTION : tp = piTest (); break ;
3200
3186
case SCHEMA_ELEMENT :
3201
3187
case SCHEMA_ATTRIBUTE : tp = schemaTest (); break ;
3202
- default : tp = null ; break ;
3188
+ default : tp = null ; break ;
3203
3189
}
3204
3190
wsCheck (PAREN2 );
3205
3191
return tp ;
@@ -3238,37 +3224,20 @@ private Test schemaTest() throws QueryException {
3238
3224
* @throws QueryException query exception
3239
3225
*/
3240
3226
private Test elemAttrTest (final NodeType type ) throws QueryException {
3241
- final Test test = nodeTest (type , true );
3242
- if (test != null ) {
3243
- typeName (type );
3244
- return test ;
3245
- }
3246
- final QNm name = eQName (type == NodeType .ELEMENT ? sc .elemNS : null , null );
3247
- if (name != null ) {
3248
- typeName (type );
3249
- return Test .get (type , name , sc .elemNS );
3250
- }
3251
- return null ;
3252
- }
3253
-
3254
- /**
3255
- * Parses the "TypeName" rule.
3256
- * @param type node type
3257
- * @throws QueryException query exception
3258
- */
3259
- private void typeName (final NodeType type ) throws QueryException {
3260
- if (wsConsumeWs (COMMA )) {
3261
- final QNm tn = eQName (sc .elemNS , QNAME_X );
3262
- Type ann = ListType .find (tn );
3263
- if (ann == null ) ann = AtomType .find (tn , true );
3264
- if (ann == null ) throw error (TYPEUNDEF_X , AtomType .similar (tn ));
3227
+ final Test test = nodeTest (type , false );
3228
+ if (test != null && wsConsumeWs (COMMA )) {
3229
+ final QNm name = eQName (sc .elemNS , QNAME_X );
3230
+ Type ann = ListType .find (name );
3231
+ if (ann == null ) ann = AtomType .find (name , true );
3232
+ if (ann == null ) throw error (TYPEUNDEF_X , AtomType .similar (name ));
3265
3233
// parse (and ignore) optional question mark
3266
3234
if (type == NodeType .ELEMENT ) wsConsume (QUESTION );
3267
3235
if (!ann .oneOf (AtomType .ANY_TYPE , AtomType .UNTYPED ) && (type == NodeType .ELEMENT ||
3268
3236
!ann .oneOf (AtomType .ANY_SIMPLE_TYPE , AtomType .ANY_ATOMIC_TYPE , AtomType .UNTYPED_ATOMIC ))) {
3269
3237
throw error (STATIC_X , ann );
3270
3238
}
3271
3239
}
3240
+ return test ;
3272
3241
}
3273
3242
3274
3243
/**
0 commit comments