Skip to content

Commit

Permalink
Allow updating without % and define default annotations namespace.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ghislain Fourny committed Aug 2, 2024
1 parent 3eb58a9 commit 8d324c9
Show file tree
Hide file tree
Showing 10 changed files with 1,771 additions and 1,783 deletions.
48 changes: 26 additions & 22 deletions src/main/java/org/rumbledb/compiler/TranslationVisitor.java
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ public Node visitProlog(JsoniqParser.PrologContext ctx) {
return prolog;
}

public Name parseName(JsoniqParser.QnameContext ctx, boolean isFunction, boolean isType) {
public Name parseName(JsoniqParser.QnameContext ctx, boolean isFunction, boolean isType, boolean isAnnotation) {
String localName = null;
String prefix = null;
Name name = null;
Expand All @@ -445,6 +445,8 @@ public Name parseName(JsoniqParser.QnameContext ctx, boolean isFunction, boolean
name = Name.createVariableInDefaultFunctionNamespace(localName);
} else if (isType) {
name = Name.createVariableInDefaultTypeNamespace(localName);
} else if(isAnnotation) {
name = Name.createVariableInDefaultAnnotationsNamespace(localName);
} else {
name = Name.createVariableInNoNamespace(localName);
}
Expand All @@ -463,14 +465,14 @@ public Name parseName(JsoniqParser.QnameContext ctx, boolean isFunction, boolean
@Override
public Node visitFunctionDecl(JsoniqParser.FunctionDeclContext ctx) {
List<Annotation> annotations = processAnnotations(ctx.annotations());
Name name = parseName(ctx.qname(), true, false);
Name name = parseName(ctx.qname(), true, false, false);
LinkedHashMap<Name, SequenceType> fnParams = new LinkedHashMap<>();
SequenceType fnReturnType = null;
Name paramName;
SequenceType paramType;
if (ctx.paramList() != null) {
for (JsoniqParser.ParamContext param : ctx.paramList().param()) {
paramName = parseName(param.qname(), false, false);
paramName = parseName(param.qname(), false, false, false);
paramType = ITEM_STAR;
if (fnParams.containsKey(paramName)) {
throw new DuplicateParamNameException(
Expand Down Expand Up @@ -534,7 +536,7 @@ public Node visitTypeDecl(JsoniqParser.TypeDeclContext ctx) {
pe.initCause(e);
throw pe;
}
Name name = parseName(ctx.qname(), false, true);
Name name = parseName(ctx.qname(), false, true, false);
String schemaLanguage = null;
if (ctx.schema != null) {
schemaLanguage = ctx.schema.getText();
Expand Down Expand Up @@ -1135,7 +1137,7 @@ public Node visitArrowExpr(JsoniqParser.ArrowExprContext ctx) {
children.add(mainExpression);
children.addAll(getArgumentsFromArgumentListContext(ctx.arguments.get(i)));
if (functionCallContext.qname() != null) {
Name name = parseName(functionCallContext.qname(), true, false);
Name name = parseName(functionCallContext.qname(), true, false, false);
mainExpression = processFunctionCall(name, children, createMetadataFromContext(functionCallContext));
continue;
} else if (functionCallContext.varRef() != null) {
Expand Down Expand Up @@ -1521,7 +1523,7 @@ public Node visitParenthesizedExpr(JsoniqParser.ParenthesizedExprContext ctx) {

@Override
public Node visitVarRef(JsoniqParser.VarRefContext ctx) {
Name name = parseName(ctx.qname(), false, false);
Name name = parseName(ctx.qname(), false, false, false);
return new VariableReferenceExpression(name, createMetadataFromContext(ctx));
}

Expand Down Expand Up @@ -1592,7 +1594,7 @@ public ItemType processItemType(JsoniqParser.ItemTypeContext itemTypeContext) {
return BuiltinTypesCatalogue.anyFunctionItem;
}
}
Name name = parseName(itemTypeContext.qname(), false, true);
Name name = parseName(itemTypeContext.qname(), false, true, false);
if (!BuiltinTypesCatalogue.typeExists(name)) {
return new ItemTypeReference(name);
}
Expand Down Expand Up @@ -1625,7 +1627,7 @@ private Expression processFunctionCall(Name name, List<Expression> children, Exc

@Override
public Node visitFunctionCall(JsoniqParser.FunctionCallContext ctx) {
Name name = parseName(ctx.fn_name, true, false);
Name name = parseName(ctx.fn_name, true, false, false);
return processFunctionCall(
name,
getArgumentsFromArgumentListContext(ctx.argumentList()),
Expand Down Expand Up @@ -1669,7 +1671,7 @@ public Node visitFunctionItemExpr(JsoniqParser.FunctionItemExprContext ctx) {

@Override
public Node visitNamedFunctionRef(JsoniqParser.NamedFunctionRefContext ctx) {
Name name = parseName(ctx.fn_name, true, false);
Name name = parseName(ctx.fn_name, true, false, false);
int arity = 0;
try {
arity = Integer.parseInt(ctx.arity.getText());
Expand All @@ -1694,7 +1696,7 @@ public Node visitInlineFunctionExpr(JsoniqParser.InlineFunctionExprContext ctx)
SequenceType paramType;
if (ctx.paramList() != null) {
for (JsoniqParser.ParamContext param : ctx.paramList().param()) {
paramName = parseName(param.qname(), false, false);
paramName = parseName(param.qname(), false, false, false);
paramType = SequenceType.ITEM_STAR;
if (fnParams.containsKey(paramName)) {
throw new DuplicateParamNameException(
Expand Down Expand Up @@ -1876,7 +1878,7 @@ public Node visitTryCatchExpr(JsoniqParser.TryCatchExprContext ctx) {
for (JsoniqParser.CatchClauseContext catchCtx : ctx.catches) {
Expression catchExpression = (Expression) this.visitExpr(catchCtx.catch_expression);
for (JsoniqParser.QnameContext qnameCtx : catchCtx.errors) {
Name name = parseName(qnameCtx, false, false);
Name name = parseName(qnameCtx, false, false, false);
if (!catchExpressions.containsKey(name.getLocalName())) {
catchExpressions.put(name.getLocalName(), catchExpression);
}
Expand Down Expand Up @@ -2031,7 +2033,7 @@ public Node visitApplyStatement(JsoniqParser.ApplyStatementContext ctx) {

@Override
public Node visitAssignStatement(JsoniqParser.AssignStatementContext ctx) {
Name paramName = parseName(ctx.qname(), false, false);
Name paramName = parseName(ctx.qname(), false, false, false);
Expression exprSingle = (Expression) this.visitExprSingle(ctx.exprSingle());
return new AssignStatement(exprSingle, paramName, createMetadataFromContext(ctx));
}
Expand Down Expand Up @@ -2173,7 +2175,7 @@ public Node visitTryCatchStatement(JsoniqParser.TryCatchStatementContext ctx) {
for (JsoniqParser.CatchCaseStatementContext catchCtx : ctx.catches) {
BlockStatement catchBlockStatement = (BlockStatement) this.visitBlockStatement(catchCtx.catch_block);
for (JsoniqParser.QnameContext qnameCtx : catchCtx.errors) {
Name name = parseName(qnameCtx, false, false);
Name name = parseName(qnameCtx, false, false, false);
if (!catchBlockStatements.containsKey(name.getLocalName())) {
catchBlockStatements.put(name.getLocalName(), catchBlockStatement);
}
Expand Down Expand Up @@ -2383,20 +2385,22 @@ public ExceptionMetadata generateMetadata(Token token) {

private List<Annotation> processAnnotations(JsoniqParser.AnnotationsContext annotations) {
List<Annotation> parsedAnnotations = new ArrayList<>();
annotations.annotation().forEach(annotationContext -> {
for(JsoniqParser.AnnotationContext annotationContext : annotations.annotation())
{
// for backwards compatibility, the specification allows for updating without % sign
if(annotationContext.updating != null)
{
Name name = Name.createVariableInDefaultAnnotationsNamespace("updating");
parsedAnnotations.add(new Annotation(name, null));
continue;
}
JsoniqParser.QnameContext qnameContext = annotationContext.qname();
Name name = parseName(qnameContext, false, false);
Name name = parseName(qnameContext, false, false, true);
if (!annotationContext.Literal().isEmpty()) {
throw new OurBadException("Literals are currently not supported in annotations!");
}
parsedAnnotations.add(new Annotation(name, null));
// List<Expression> literals = new ArrayList<>();
// ExceptionMetadata metadata = createMetadataFromContext(annotationContext);
// annotationContext.Literal().forEach(literal -> {
// literals.add(getLiteralExpressionFromToken(literal.getText(), metadata));
// });
// parsedAnnotations.add(new Annotation(name, literals));
});
}

return parsedAnnotations;
}
Expand Down
16 changes: 14 additions & 2 deletions src/main/java/org/rumbledb/context/Name.java
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ public class Name implements Comparable<Name>, Serializable, KryoSerializable {
public static final String XS_NS = "http://www.w3.org/2001/XMLSchema";
public static final String JS_NS = "http://jsoniq.org/types";
public static final String LOCAL_NS = "http://www.w3.org/2005/xquery-local-functions";

public static final String AN_NS = "http://www.zorba-xquery.com/annotations";
public static final String AN_NS = "http://www.w3.org/2012/xquery";
public static final String DEFAULT_COLLATION_NS = "http://www.w3.org/2005/xpath-functions/collation/codepoint";

public static final Name CONTEXT_ITEM = createVariableInNoNamespace("$");
public static final Name CONTEXT_POSITION = createVariableInNoNamespace("$position");
public static final Name CONTEXT_COUNT = createVariableInNoNamespace("$count");
Expand Down Expand Up @@ -122,6 +122,18 @@ public static Name createVariableInDefaultFunctionNamespace(String localName) {
return new Name(JSONIQ_DEFAULT_FUNCTION_NS, "", localName);
}

/**
* Creates an expanded name that has the default annotations namespace. By default, in Rumble, unprefixed
* annotations live in this namespace. This namespace includes
* all builtin annotations.
*
* @param localName the name of the variable
* @return the expanded name
*/
public static Name createVariableInDefaultAnnotationsNamespace(String localName) {
return new Name(AN_NS, "", localName);
}

public static Name createVariableInDefaultXQueryTypeNamespace(String localName) {
return new Name(FN_NS, "", localName);
}
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/org/rumbledb/context/StaticContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public class StaticContext implements Serializable, KryoSerializable {
defaultBindings.put("xs", Name.XS_NS);
defaultBindings.put("jn", Name.JN_NS);
defaultBindings.put("js", Name.JS_NS);
defaultBindings.put("an", Name.AN_NS);
//defaultBindings.put("an", Name.AN_NS);
}

private RumbleRuntimeConfiguration configuration;
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/org/rumbledb/parser/Jsoniq.g4
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ typeSwitchStatement : Ktypeswitch '(' cond=expr ')' cases+=caseStatement

caseStatement : Kcase (var_ref=varRef Kas)? union+=sequenceType ('|' union+=sequenceType)* Kreturn ret=statement ;

annotation : '%' name=qname ('(' Literal (',' Literal)* ')')? ;
annotation : ('%' name=qname ('(' Literal (',' Literal)* ')')? | updating=Kupdating);

annotations : annotation* ;

Expand Down Expand Up @@ -443,6 +443,7 @@ keyWords : Kjsoniq
| Kreturning
| Kwhile
| Kjson
| Kupdating
;

///////////////////////// literals
Expand Down Expand Up @@ -578,6 +579,9 @@ Kwith : 'with';
Kposition : 'position';

Kjson : 'json';

Kupdating : 'updating';

///////////////////////// Scripting keywords
Kbreak : 'break' ;
Kloop : 'loop' ;
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/org/rumbledb/parser/Jsoniq.interp

Large diffs are not rendered by default.

54 changes: 28 additions & 26 deletions src/main/java/org/rumbledb/parser/Jsoniq.tokens
Original file line number Diff line number Diff line change
Expand Up @@ -124,24 +124,25 @@ Kvalue=123
Kwith=124
Kposition=125
Kjson=126
Kbreak=127
Kloop=128
Kcontinue=129
Kexit=130
Kreturning=131
Kwhile=132
STRING=133
ArgumentPlaceholder=134
NullLiteral=135
Literal=136
NumericLiteral=137
IntegerLiteral=138
DecimalLiteral=139
DoubleLiteral=140
WS=141
NCName=142
XQComment=143
ContentChar=144
Kupdating=127
Kbreak=128
Kloop=129
Kcontinue=130
Kexit=131
Kreturning=132
Kwhile=133
STRING=134
ArgumentPlaceholder=135
NullLiteral=136
Literal=137
NumericLiteral=138
IntegerLiteral=139
DecimalLiteral=140
DoubleLiteral=141
WS=142
NCName=143
XQComment=144
ContentChar=145
';'=1
'module'=2
'namespace'=3
Expand Down Expand Up @@ -268,11 +269,12 @@ ContentChar=144
'with'=124
'position'=125
'json'=126
'break'=127
'loop'=128
'continue'=129
'exit'=130
'returning'=131
'while'=132
'?'=134
'null'=135
'updating'=127
'break'=128
'loop'=129
'continue'=130
'exit'=131
'returning'=132
'while'=133
'?'=135
'null'=136
5 changes: 4 additions & 1 deletion src/main/java/org/rumbledb/parser/JsoniqLexer.interp

Large diffs are not rendered by default.

Loading

0 comments on commit 8d324c9

Please sign in to comment.