Skip to content

Commit d0a87c2

Browse files
authored
Merge pull request #5718 from line-o/port/fix/5685
Port/fix/5685
2 parents 8f6b5b5 + f76323f commit d0a87c2

File tree

3 files changed

+281
-253
lines changed

3 files changed

+281
-253
lines changed

exist-core/src/main/java/org/exist/xquery/FunctionSignature.java

Lines changed: 59 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.Arrays;
2525
import java.util.HashMap;
2626
import java.util.Map;
27+
2728
import org.exist.Namespaces;
2829
import org.exist.dom.QName;
2930
import org.exist.xquery.value.FunctionParameterSequenceType;
@@ -33,7 +34,7 @@
3334
/**
3435
* Describes the signature of a built-in or user-defined function, i.e.
3536
* its name, the type and cardinality of its arguments and its return type.
36-
*
37+
*
3738
* @author wolf
3839
* @author lcahlander
3940
* @version 1.3
@@ -43,25 +44,20 @@ public class FunctionSignature {
4344
/**
4445
* Default sequence type for function parameters.
4546
*/
46-
public final static SequenceType DEFAULT_TYPE = new SequenceType(Type.ITEM, Cardinality.ZERO_OR_MORE);
47+
public static final SequenceType DEFAULT_TYPE = new SequenceType(Type.ITEM, Cardinality.ZERO_OR_MORE);
4748

4849
/**
4950
* Empty array to specify if a function doesn't take any arguments.
5051
*/
51-
public final static SequenceType[] NO_ARGS = new SequenceType[0];
52+
public static final SequenceType[] NO_ARGS = new SequenceType[0];
5253

5354
private static final String DEPRECATION_REMOVAL_MESSAGE = "\nThis function could be removed in the next major release version.";
54-
55-
public static SequenceType[] singleArgument(final SequenceType arg) {
56-
return new SequenceType[] { arg };
57-
}
58-
59-
private Annotation[] annotations;
6055
private final QName name;
56+
private Annotation[] annotations;
6157
private SequenceType[] arguments;
6258
private SequenceType returnType;
63-
private boolean isVariadic = false;
64-
private String description = null;
59+
private boolean isVariadic;
60+
private String description;
6561
private String deprecated = null;
6662
private Map<String, String> metadata = null;
6763

@@ -89,17 +85,13 @@ public FunctionSignature(final QName name, final SequenceType[] arguments, final
8985
}
9086

9187
public FunctionSignature(final QName name, final String description, final SequenceType[] arguments, final SequenceType returnType) {
92-
this(name, description, arguments, returnType, false);
88+
this(name, description, arguments, returnType, false);
9389
}
9490

9591
public FunctionSignature(final QName name, final String description, final SequenceType[] arguments, final SequenceType returnType, final String deprecated) {
9692
this(name, description, arguments, returnType, false);
9793
setDeprecated(deprecated);
9894
}
99-
100-
// public FunctionSignature(final QName name, final String description, final SequenceType[] arguments, final SequenceType returnType, final FunctionSignature deprecatedBy) {
101-
// this(name, description, arguments, returnType, false, "Moved to the module: " + deprecatedBy.getName().getNamespaceURI() + ", you should now use '" + deprecatedBy.getName().getPrefix() + ":" + deprecatedBy.getName().getLocalPart() + "' instead!");
102-
// }
10395

10496
public FunctionSignature(final QName name, final String description, final SequenceType[] arguments, final SequenceType returnType, final boolean variadic, final String deprecated) {
10597
this(name, description, arguments, returnType, variadic);
@@ -108,13 +100,13 @@ public FunctionSignature(final QName name, final String description, final Seque
108100

109101
/**
110102
* Create a new function signature.
111-
*
112-
* @param name the QName of the function.
103+
*
104+
* @param name the QName of the function.
113105
* @param description documentation string describing the function
114-
* @param arguments the sequence types of all expected arguments
115-
* @param returnType the sequence type returned by the function
116-
* @param variadic set to true if the function may expect additional parameters
117-
*/
106+
* @param arguments the sequence types of all expected arguments
107+
* @param returnType the sequence type returned by the function
108+
* @param variadic set to true if the function may expect additional parameters
109+
*/
118110
public FunctionSignature(final QName name, final String description, final SequenceType[] arguments, final SequenceType returnType, final boolean variadic) {
119111
this.name = name;
120112
this.arguments = arguments;
@@ -126,22 +118,26 @@ public FunctionSignature(final QName name, final String description, final Seque
126118
public Annotation[] getAnnotations() {
127119
return annotations;
128120
}
129-
121+
122+
public void setAnnotations(final Annotation[] annotations) {
123+
this.annotations = annotations;
124+
}
125+
130126
public QName getName() {
131127
return name;
132128
}
133129

134130
public int getArgumentCount() {
135-
if(isVariadic) {
131+
if (isVariadic) {
136132
return -1;
137133
}
138134
return arguments != null ? arguments.length : 0;
139135
}
140-
136+
141137
public FunctionId getFunctionId() {
142138
return new FunctionId(name, getArgumentCount());
143139
}
144-
140+
145141
public SequenceType getReturnType() {
146142
return returnType;
147143
}
@@ -157,29 +153,23 @@ public SequenceType[] getArgumentTypes() {
157153
public void setArgumentTypes(final SequenceType[] types) {
158154
this.arguments = types;
159155
}
160-
161-
public void setAnnotations(final Annotation[] annotations) {
162-
this.annotations = annotations;
163-
}
164-
156+
165157
public String getDescription() {
166-
return description;
158+
return description;
167159
}
168160

169161
public void setDescription(final String description) {
170162
this.description = description;
171163
}
172164

173-
public void addMetadata(final String key, String value) {
174-
if(metadata == null) {
165+
public void addMetadata(final String key, final String value) {
166+
if (metadata == null) {
175167
metadata = new HashMap<>(5);
176168
}
177169
final String old = metadata.get(key);
178-
if (old != null) {
179-
// if the key exists, simply append the new value
180-
value = old + ", " + value;
181-
}
182-
metadata.put(key, value);
170+
// if the key exists, append the new value
171+
final String newValue = old == null ? value : old + ", " + value;
172+
metadata.put(key, newValue);
183173
}
184174

185175
public String getMetadata(final String key) {
@@ -208,17 +198,17 @@ public String getDeprecated() {
208198
return null;
209199
}
210200
}
211-
201+
212202
public final void setDeprecated(final String message) {
213203
deprecated = message;
214204
}
215205

216206
public boolean isPrivate() {
217207
final Annotation[] annotations = getAnnotations();
218-
if(annotations != null) {
219-
for(final Annotation annot : annotations) {
208+
if (annotations != null) {
209+
for (final Annotation annot : annotations) {
220210
final QName qn = annot.getName();
221-
if(qn.getNamespaceURI().equals(Namespaces.XPATH_FUNCTIONS_NS) && "private".equals(qn.getLocalPart())) {
211+
if (qn.getNamespaceURI().equals(Namespaces.XPATH_FUNCTIONS_NS) && "private".equals(qn.getLocalPart())) {
222212
return true;
223213
}
224214
}
@@ -231,50 +221,53 @@ public String toString() {
231221
final StringBuilder buf = new StringBuilder();
232222
buf.append(name.getStringValue());
233223
buf.append('(');
234-
if(arguments != null) {
235-
final char var = 'a';
236-
for(int i = 0; i < arguments.length; i++) {
237-
if(i > 0) {
224+
if (arguments != null) {
225+
final char ANON_VAR = 'a';
226+
for (int i = 0; i < arguments.length; i++) {
227+
if (i > 0) {
238228
buf.append(", ");
239229
}
240230
buf.append('$');
241-
if(arguments[i] instanceof FunctionParameterSequenceType) {
242-
buf.append(((FunctionParameterSequenceType)arguments[i]).getAttributeName());
231+
if (arguments[i] instanceof FunctionParameterSequenceType) {
232+
buf.append(((FunctionParameterSequenceType) arguments[i]).getAttributeName());
243233
} else {
244-
buf.append((char)(var + i));
234+
buf.append((char) (ANON_VAR + i));
245235
}
246236
buf.append(" as ");
247237
buf.append(arguments[i].toString());
248238
}
249-
250-
if(isVariadic) {
239+
240+
if (isVariadic) {
251241
buf.append(", ...");
252242
}
253243
}
254-
buf.append(") ");
244+
buf.append(") as ");
255245
buf.append(returnType.toString());
256-
246+
257247
return buf.toString();
258248
}
259249

260250
@Override
261251
public boolean equals(final Object obj) {
262-
if(obj == null || !(obj instanceof FunctionSignature other)) {
252+
if (!(obj instanceof FunctionSignature other)) {
263253
return false;
264254
}
265-
266-
if(name == null) {
267-
if(other.name != null) {
268-
return false;
269-
}
270-
return getArgumentCount() == other.getArgumentCount();
255+
// quick comparison by object identity
256+
if (this == other) {
257+
return true;
271258
}
272-
273-
if(name.equals(other.name)) {
274-
return getArgumentCount() == other.getArgumentCount();
259+
260+
// anonymous functions cannot be compared by name and argument count
261+
if (
262+
name == null || other.name == null ||
263+
name.getLocalPart().equals("") ||
264+
other.name.getLocalPart().equals("")
265+
) {
266+
return false;
275267
}
276-
277-
return false;
268+
269+
// compare by QName and arity
270+
return (name.equals(other.name) && getArgumentCount() == other.getArgumentCount());
278271
}
279272

280273
/**

0 commit comments

Comments
 (0)