Skip to content

Commit 35c4731

Browse files
committed
Improved error handling and reporting
1 parent 5dc1a90 commit 35c4731

24 files changed

Lines changed: 154 additions & 13 deletions

File tree

CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/CompileErrors.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ public static CompileError noOperatorInType(TypeID type, OperatorType operator)
5454
return new CompileError(CompileExceptionCode.NO_SUCH_MEMBER, "No operator " + operator + " in type " + type);
5555
}
5656

57+
public static CompileError notAStaticMethod(TypeID type, String name) {
58+
return new CompileError(CompileExceptionCode.MEMBER_NOT_STATIC, "No static method " + name + " in type " + type);
59+
}
60+
61+
public static CompileError notAnInstanceMethod(TypeID type, String name) {
62+
return new CompileError(CompileExceptionCode.MEMBER_IS_STATIC, "No instance method " + name + " in type " + type);
63+
}
64+
5765
public static CompileError noThisInScope() {
5866
return new CompileError(CompileExceptionCode.USING_THIS_OUTSIDE_TYPE, "Not in an instance method; cannot use this");
5967
}

CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/CompilingExpression.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
public interface CompilingExpression {
1515
CompilingExpression[] NONE = new CompilingExpression[0];
1616

17+
CodePosition getPosition();
18+
1719
/**
1820
* Compiles this expression. The return type is inferred from the expression.
1921
*

CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/ExpressionBuilder.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.openzen.zenscript.codemodel.compilation;
22

3+
import org.openzen.zencode.shared.CodePosition;
34
import org.openzen.zencode.shared.CompileError;
45
import org.openzen.zenscript.codemodel.CompareType;
56
import org.openzen.zenscript.codemodel.FunctionHeader;
@@ -63,6 +64,8 @@ public interface ExpressionBuilder {
6364

6465
Expression invalid(CompileError error, TypeID type);
6566

67+
Expression invalidAt(CompileError error, CodePosition position);
68+
6669
Expression is(Expression value, TypeID type);
6770

6871
Expression lambda(LambdaClosure closure, FunctionHeader header, Statement body);

CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/MatchedCallArguments.java

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,23 +77,41 @@ private static <T extends AnyMethod> MatchedCallArguments<T> ambiguousCall(Map<C
7777
private final T method;
7878
private final CallArguments arguments;
7979
private final CompileError error;
80+
private final CodePosition position;
8081

8182
private MatchedCallArguments(T method, CallArguments arguments) {
8283
this.method = method;
8384
this.arguments = arguments;
8485
this.error = null;
86+
this.position = null;
87+
}
88+
89+
private MatchedCallArguments(T method, CallArguments arguments, CompileError error) {
90+
this.method = method;
91+
this.arguments = arguments;
92+
this.error = error;
93+
this.position = null;
8594
}
8695

8796
private MatchedCallArguments(CompileError error) {
8897
this.method = null;
8998
this.arguments = null;
9099
this.error = error;
100+
this.position = null;
91101
}
92102

93103
private MatchedCallArguments(CompileError error, CallArguments arguments) {
94104
this.method = null;
95105
this.arguments = arguments;
96106
this.error = error;
107+
this.position = null;
108+
}
109+
110+
private MatchedCallArguments(CompileError error, CallArguments arguments, CodePosition position) {
111+
this.method = null;
112+
this.arguments = arguments;
113+
this.error = error;
114+
this.position = position;
97115
}
98116

99117
public boolean requiresWidenedInstance(TypeID instanceType) {
@@ -106,7 +124,11 @@ public TypeID getWidenedInstanceType() {
106124

107125
public Expression eval(ExpressionBuilder builder, CallEvaluator<T> evaluator) {
108126
if (this.error != null) {
109-
return builder.invalid(error);
127+
if (position != null) {
128+
return builder.invalidAt(error, position);
129+
} else {
130+
return builder.invalid(error);
131+
}
110132
} else {
111133
return evaluator.eval(builder, method, arguments);
112134
}
@@ -148,7 +170,12 @@ private static <T extends AnyMethod> MatchedCallArguments<T> match(
148170
CastedExpression.Level.INVALID,
149171
expansionTypeArguments,
150172
typeArguments,
151-
Expression.NONE));
173+
Expression.NONE),
174+
CompileErrors.invalidNumberOfArguments(
175+
arguments.length,
176+
arguments.length < method.getHeader().minParameters
177+
? method.getHeader().minParameters
178+
: method.getHeader().maxParameters));
152179
}
153180

154181
// Type inference
@@ -256,7 +283,7 @@ private static <T extends AnyMethod> MatchedCallArguments<T> matchNormal(
256283
return CastedExpression.invalid(position, CompileErrors.missingParameter(header.getParameter(false, i).name));
257284
}
258285
TypeID originalType = method.getHeader().getParameterType(false, i);
259-
return argument.cast(CastedEval.implicit(compiler, position, header.getParameterType(false, i), originalType));
286+
return argument.cast(CastedEval.implicit(compiler, argument.getPosition(), header.getParameterType(false, i), originalType));
260287
})
261288
.toArray(CastedExpression[]::new);
262289

@@ -272,7 +299,8 @@ private static <T extends AnyMethod> MatchedCallArguments<T> matchNormal(
272299
.orElseThrow(() -> new IllegalStateException("Should never happen"));
273300

274301
return new MatchedCallArguments<>(firstInvalid.error,
275-
new CallArguments(CastedExpression.Level.INVALID, expansionTypeArguments, typeArguments, Expression.NONE));
302+
new CallArguments(CastedExpression.Level.INVALID, expansionTypeArguments, typeArguments, Expression.NONE),
303+
firstInvalid.value.position);
276304
}
277305

278306
return new MatchedCallArguments<>(

CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/expression/AbstractCompilingExpression.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ public AbstractCompilingExpression(ExpressionCompiler compiler, CodePosition pos
1818
this.position = position;
1919
}
2020

21+
@Override
22+
public CodePosition getPosition() {
23+
return position;
24+
}
25+
2126
@Override
2227
public CastedExpression cast(CastedEval cast) {
2328
return cast.of(eval());

CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/expression/InstanceMemberCompilingExpression.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ public Optional<CompilingCallable> call() {
7474
.findOperator(OperatorType.CALL)
7575
.map(method -> method.bind(compiler, field.get(compiler.at(position), instance), name.arguments)));
7676
}
77+
if (resolvedType.findStaticMethod(name.name).isPresent()) {
78+
return Optional.of(new InvalidCompilingExpression(compiler, position, CompileErrors.notAnInstanceMethod(instance.type, name.name)));
79+
}
7780

7881
return Optional.of(result.orElseGet(() -> new InvalidCompilingExpression(compiler, position, CompileErrors.noMemberInType(instance.type, name.name))));
7982
}

CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/expression/PackageCompilingExpression.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ public PackageCompilingExpression(ExpressionCompiler compiler, CodePosition posi
2222
this.pkg = pkg;
2323
}
2424

25+
@Override
26+
public CodePosition getPosition() {
27+
return position;
28+
}
29+
2530
@Override
2631
public Expression eval() {
2732
return compiler.at(position).invalid(CompileErrors.cannotUsePackageAsValue());

CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/expression/StaticMemberCompilingExpression.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ public Optional<CompilingCallable> call() {
6464
if (staticMethod.isPresent())
6565
return staticMethod;
6666

67+
if (resolvedType.findMethod(name.name).isPresent()) {
68+
return Optional.of(new InvalidCompilingExpression(compiler, position, CompileErrors.notAStaticMethod(type, name.name)));
69+
}
70+
6771
return resolvedType.getContextMember(name.name).flatMap(member -> member.compile(compiler).call());
6872
}
6973

CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/expression/TypeCompilingExpression.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ public TypeCompilingExpression(ExpressionCompiler compiler, CodePosition positio
2222
this.type = type;
2323
}
2424

25+
@Override
26+
public CodePosition getPosition() {
27+
return position;
28+
}
29+
2530
@Override
2631
public Expression eval() {
2732
return compiler.at(position).invalid(CompileErrors.cannotUseTypeAsValue());

CodeModel/src/main/java/org/openzen/zenscript/codemodel/compilation/impl/compiler/ExpressionCompilerImpl.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,11 @@ public Expression invalid(CompileError error, TypeID type) {
317317
return new InvalidExpression(position, type, error);
318318
}
319319

320+
@Override
321+
public Expression invalidAt(CompileError error, CodePosition position) {
322+
return new InvalidExpression(position, new InvalidTypeID(position, error), error);
323+
}
324+
320325
@Override
321326
public Expression is(Expression value, TypeID type) {
322327
return new IsExpression(position, value, type);

0 commit comments

Comments
 (0)