Skip to content

Commit 533e511

Browse files
nikarhFylmTM
authored andcommitted
Added primitive argument type checking (#44)
* Added primitive argument type checking
1 parent efdec80 commit 533e511

File tree

8 files changed

+396
-94
lines changed

8 files changed

+396
-94
lines changed

config/checkstyle/checkstyle.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@
129129
<module name="InterfaceIsType"/>
130130
<module name="VisibilityModifier">
131131
<property name="protectedAllowed" value="true"/>
132+
<property name="allowPublicFinalFields" value="true"/>
133+
<property name="allowPublicImmutableFields" value="true"/>
132134
</module>
133135

134136
<!-- Miscellaneous other checks. -->

language/cypher/src/main/java/com/neueda/jetbrains/plugin/graphdb/language/cypher/completion/metadata/atoms/CypherBuiltInFunctions.java

Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -14,90 +14,90 @@
1414
public final class CypherBuiltInFunctions {
1515

1616
private static final List<CypherBuiltInFunctionElement> FUNCTIONS_PREDICATE = Lists.newArrayList(
17-
element("all", "(variable IN list WHERE predicate)", BOOLEAN.single()),
18-
element("any", "(variable IN list WHERE predicate)", BOOLEAN.single()),
19-
element("none", "(variable in list WHERE predicate)", BOOLEAN.single()),
20-
element("single", "(variable in list WHERE predicate)", BOOLEAN.single()),
21-
element("exists", "(pattern)", BOOLEAN.single()),
22-
element("exists", "(property)", BOOLEAN.single())
17+
element("all", "(variable IN list WHERE predicate :: ANY)", BOOLEAN.single()),
18+
element("any", "(variable IN list WHERE predicate :: ANY)", BOOLEAN.single()),
19+
element("none", "(variable in list WHERE predicate :: ANY)", BOOLEAN.single()),
20+
element("single", "(variable in list WHERE predicate :: ANY)", BOOLEAN.single()),
21+
element("exists", "(pattern :: ANY)", BOOLEAN.single()),
22+
element("exists", "(property :: ANY)", BOOLEAN.single())
2323
);
2424
private static final List<CypherBuiltInFunctionElement> FUNCTIONS_SHORTEST_PATH = Lists.newArrayList(
25-
element("shortestPath", "(pattern)", PATH.single()),
26-
element("allShortestPaths", "(pattern)", PATH.array())
25+
element("shortestPath", "(pattern :: PATH)", PATH.single()),
26+
element("allShortestPaths", "(pattern :: PATH)", PATH.array())
2727
);
2828
private static final List<CypherBuiltInFunctionElement> FUNCTIONS_SCALAR = Lists.newArrayList(
29-
element("size", "(list)", INTEGER.single()),
30-
element("size", "(pattern)", INTEGER.single()),
31-
element("length", "(path)", INTEGER.single()),
32-
element("length", "(string)", INTEGER.single()),
33-
element("type", "(relationship)", STRING.single()),
34-
element("id", "(node)", INTEGER.single()),
35-
element("id", "(relationship)", INTEGER.single()),
36-
element("coalesce", "(expression...)", ANY.single()),
37-
element("head", "(expression)", ANY.single()),
38-
element("last", "(expression)", ANY.single()),
29+
element("size", "(list :: LIST OF ANY)", INTEGER.single()),
30+
element("size", "(pattern :: ANY)", INTEGER.single()),
31+
element("length", "(path :: ANY)", INTEGER.single()),
32+
element("length", "(string :: STRING)", INTEGER.single()),
33+
element("type", "(relationship :: RELATIONSHIP)", STRING.single()),
34+
element("id", "(node :: NODE)", INTEGER.single()),
35+
element("id", "(relationship :: RELATIONSHIP)", INTEGER.single()),
36+
element("coalesce", "(expression... :: ANY)", ANY.single()),
37+
element("head", "(expression :: LIST OF ANY)", ANY.single()),
38+
element("last", "(expression :: LIST OF ANY)", ANY.single()),
3939
element("timestamp", "()", INTEGER.single()),
40-
element("startNode", "(relationship)", NODE.single()),
41-
element("endNode", "(relationship", NODE.single()),
42-
element("properties", "(node)", MAP.single()),
43-
element("properties", "(relationship)", MAP.single()),
44-
element("toInt", "(expression)", INTEGER.single()),
45-
element("toFloat", "(expression)", FLOAT.single())
40+
element("startNode", "(relationship :: RELATIONSHIP)", NODE.single()),
41+
element("endNode", "(relationship :: RELATIONSHIP)", NODE.single()),
42+
element("properties", "(node :: NODE)", MAP.single()),
43+
element("properties", "(relationship :: RELATIONSHIP)", MAP.single()),
44+
element("toInt", "(expression :: STRING)", INTEGER.single()),
45+
element("toFloat", "(expression :: STRING)", FLOAT.single())
4646
);
4747
private static final List<CypherBuiltInFunctionElement> FUNCTIONS_LIST = Lists.newArrayList(
48-
element("nodes", "(path)", NODE.array()),
49-
element("relationships", "(path)", RELATIONSHIP.array()),
50-
element("labels", "(node)", STRING.array()),
51-
element("keys", "(node)", STRING.array()),
52-
element("keys", "(relationship)", STRING.array()),
53-
element("extract", "(variable IN list | expression)", ANY.array()),
54-
element("filter", "(variable IN list WHERE predicate)", ANY.array()),
55-
element("tail", "(expression)", ANY.array()),
56-
element("range", "(start, end, step = 1)", INTEGER.array()),
57-
element("reduce", "(accumulator = initial, variable IN list | expression)", ANY.single())
48+
element("nodes", "(path :: PATH)", NODE.array()),
49+
element("relationships", "(path :: PATH)", RELATIONSHIP.array()),
50+
element("labels", "(node :: NODE)", STRING.array()),
51+
element("keys", "(node :: NODE)", STRING.array()),
52+
element("keys", "(relationship :: RELATIONSHIP)", STRING.array()),
53+
element("extract", "(variable IN list | expression :: ANY)", ANY.array()),
54+
element("filter", "(variable IN list WHERE predicate :: ANY)", ANY.array()),
55+
element("tail", "(expression :: LIST OF ANY)", ANY.array()),
56+
element("range", "(start :: INTEGER, end :: INTEGER, step = 1 :: INTEGER)", INTEGER.array()),
57+
element("reduce", "(accumulator = initial :: ANY, variable IN list | expression :: ANY)", ANY.single())
5858
);
5959
private static final List<CypherBuiltInFunctionElement> FUNCTIONS_MATH_NUMERIC = Lists.newArrayList(
60-
element("abs", "(expression)", INTEGER.single()),
61-
element("ceil", "(expression)", INTEGER.single()),
62-
element("floor", "(expression)", INTEGER.single()),
63-
element("round", "(expression)", INTEGER.single()),
64-
element("sign", "(expression)", INTEGER.single()),
60+
element("abs", "(expression :: NUMBER)", INTEGER.single()),
61+
element("ceil", "(expression :: NUMBER)", INTEGER.single()),
62+
element("floor", "(expression :: NUMBER)", INTEGER.single()),
63+
element("round", "(expression :: NUMBER)", INTEGER.single()),
64+
element("sign", "(expression :: NUMBER)", INTEGER.single()),
6565
element("rand", "()", FLOAT.single())
6666
);
6767
private static final List<CypherBuiltInFunctionElement> FUNCTIONS_MATH_LOGARITHMIC = Lists.newArrayList(
68-
element("log", "(expression)", FLOAT.single()),
69-
element("log10", "(expression)", FLOAT.single()),
70-
element("exp", "(expression)", FLOAT.single()),
68+
element("log", "(expression :: NUMBER)", FLOAT.single()),
69+
element("log10", "(expression :: NUMBER)", FLOAT.single()),
70+
element("exp", "(expression :: NUMBER)", FLOAT.single()),
7171
element("e", "()", FLOAT.single()),
72-
element("sqrt", "(expression)", FLOAT.single())
72+
element("sqrt", "(expression :: NUMBER)", FLOAT.single())
7373
);
7474
private static final List<CypherBuiltInFunctionElement> FUNCTIONS_MATH_TRIGONOMETRIC = Lists.newArrayList(
75-
element("sin", "(expression)", FLOAT.single()),
76-
element("cos", "(expression)", FLOAT.single()),
77-
element("tan", "(expression)", FLOAT.single()),
78-
element("cot", "(expression)", FLOAT.single()),
79-
element("asin", "(expression)", FLOAT.single()),
80-
element("acos", "(expression)", FLOAT.single()),
81-
element("atan", "(expression)", FLOAT.single()),
82-
element("atan2", "(expression, expression)", FLOAT.single()),
75+
element("sin", "(expression :: NUMBER)", FLOAT.single()),
76+
element("cos", "(expression :: NUMBER)", FLOAT.single()),
77+
element("tan", "(expression :: NUMBER)", FLOAT.single()),
78+
element("cot", "(expression :: NUMBER)", FLOAT.single()),
79+
element("asin", "(expression :: NUMBER)", FLOAT.single()),
80+
element("acos", "(expression :: NUMBER)", FLOAT.single()),
81+
element("atan", "(expression :: NUMBER)", FLOAT.single()),
82+
element("atan2", "(expression :: NUMBER, expression :: NUMBER)", FLOAT.single()),
8383
element("pi", "()", FLOAT.single()),
84-
element("degrees", "(expression)", FLOAT.single()),
85-
element("radians", "(expression)", FLOAT.single()),
86-
element("haversin", "(expression)", FLOAT.single())
84+
element("degrees", "(expression :: NUMBER)", FLOAT.single()),
85+
element("radians", "(expression :: NUMBER)", FLOAT.single()),
86+
element("haversin", "(expression :: NUMBER)", FLOAT.single())
8787
);
8888
private static final List<CypherBuiltInFunctionElement> FUNCTIONS_STRING = Lists.newArrayList(
89-
element("replace", "(original, search, replace)", STRING.single()),
90-
element("substring", "(original, start, length = length(original))", STRING.single()),
91-
element("left", "(original, length)", STRING.single()),
92-
element("right", "(original, length)", STRING.single()),
93-
element("ltrim", "(original)", STRING.single()),
94-
element("rtrim", "(original)", STRING.single()),
95-
element("trim", "(original)", STRING.single()),
96-
element("lower", "(original)", STRING.single()),
97-
element("upper", "(original)", STRING.single()),
98-
element("split", "(original, splitPattern)", STRING.array()),
99-
element("reverse", "(original)", STRING.single()),
100-
element("toString", "(expression)", STRING.single())
89+
element("replace", "(original :: STRING, search :: STRING, replace :: STRING)", STRING.single()),
90+
element("substring", "(original :: STRING, start :: INTEGER, length = length(original) :: INTEGER)", STRING.single()),
91+
element("left", "(original :: STRING, length :: INTEGER)", STRING.single()),
92+
element("right", "(original :: STRING, length :: INTEGER)", STRING.single()),
93+
element("ltrim", "(original :: STRING)", STRING.single()),
94+
element("rtrim", "(original :: STRING)", STRING.single()),
95+
element("trim", "(original :: STRING)", STRING.single()),
96+
element("lower", "(original :: STRING)", STRING.single()),
97+
element("upper", "(original :: STRING)", STRING.single()),
98+
element("split", "(original :: STRING, splitPattern :: STRING)", STRING.array()),
99+
element("reverse", "(original :: STRING)", STRING.single()),
100+
element("toString", "(expression :: STRING)", STRING.single())
101101
);
102102

103103
public static final List<CypherBuiltInFunctionElement> FUNCTIONS = new ArrayList<CypherBuiltInFunctionElement>() {{

language/cypher/src/main/java/com/neueda/jetbrains/plugin/graphdb/language/cypher/completion/metadata/elements/InvokableInformation.java

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,36 @@
33
import com.intellij.openapi.util.text.StringUtil;
44
import com.intellij.util.Range;
55

6+
import java.util.List;
67
import java.util.Objects;
78
import java.util.regex.Matcher;
9+
import java.util.stream.Stream;
10+
11+
import static java.util.Collections.emptyList;
12+
import static java.util.stream.Collectors.toList;
813

914
public final class InvokableInformation {
1015

16+
public static class Argument {
17+
public final String name;
18+
public final String type;
19+
public final boolean optional;
20+
public final boolean varArgs;
21+
22+
Argument(String definition) {
23+
String[] s = definition.trim().split("::");
24+
name = s[0].split("=")[0].split("\\.\\.\\.")[0].trim();
25+
type = s.length > 1 ? s[1].trim() : "ANY";
26+
optional = s[0].contains("=");
27+
varArgs = s[0].contains("...");
28+
}
29+
}
30+
1131
private final String name;
1232
private final String signature;
1333
private final String returnType;
1434
private final boolean hasParameters;
35+
private final List<Argument> arguments;
1536
private final Range<Integer> arity;
1637

1738
public InvokableInformation(String fullSignature, String name) {
@@ -28,6 +49,8 @@ public InvokableInformation(String fullSignature, String name) {
2849

2950
this.name = name;
3051
this.hasParameters = !this.signature.startsWith("()");
52+
53+
this.arguments = parseArguments();
3154
this.arity = calculateArity();
3255
}
3356

@@ -36,6 +59,8 @@ public InvokableInformation(String name, String signature, String returnType) {
3659
this.signature = signature;
3760
this.returnType = returnType;
3861
this.hasParameters = !Objects.equals(signature, "()");
62+
63+
this.arguments = parseArguments();
3964
this.arity = calculateArity();
4065
}
4166

@@ -55,25 +80,37 @@ public boolean hasParameters() {
5580
return hasParameters;
5681
}
5782

83+
public List<Argument> getArguments() {
84+
return arguments;
85+
}
86+
5887
public Range<Integer> getArity() {
5988
return arity;
6089
}
6190

62-
private Range<Integer> calculateArity() {
91+
private List<Argument> parseArguments() {
6392
if (!hasParameters) {
93+
return emptyList();
94+
}
95+
96+
return Stream.of(signature.substring(1, signature.length() - 1).split(","))
97+
.map(Argument::new)
98+
.collect(toList());
99+
}
100+
101+
private Range<Integer> calculateArity() {
102+
if (arguments.isEmpty()) {
64103
return new Range<>(0, 0);
65104
}
66105

67106
int from = 0;
68107
int to = 0;
69-
String[] args = signature.substring(1, signature.length() - 1).split(",");
70-
for (String arg : args) {
71-
String p = arg.trim();
72-
if (p.endsWith("...")) {
108+
for (Argument arg : arguments) {
109+
if (arg.varArgs) {
73110
from++;
74111
to = Integer.MAX_VALUE;
75112
break;
76-
} else if (p.contains("=")) {
113+
} else if (arg.optional) {
77114
to++;
78115
} else {
79116
from++;
@@ -83,4 +120,5 @@ private Range<Integer> calculateArity() {
83120

84121
return new Range<>(from, to);
85122
}
123+
86124
}

0 commit comments

Comments
 (0)