Skip to content

Commit fc9d669

Browse files
committed
Restore vararg type check in Procedure
1 parent d30e319 commit fc9d669

File tree

2 files changed

+33
-7
lines changed

2 files changed

+33
-7
lines changed

src/main/java/com/laytonsmith/core/Procedure.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,6 @@ public Mixed execute(List<Mixed> args, Environment oldEnv, Target t) {
220220
|| (!this.varIndex.isEmpty()
221221
&& this.varIndex.get(this.varIndex.size() - 1).getDefinedType().isVarargs())) {
222222
IVariable var;
223-
boolean isVarArg = false;
224223
if(varInd < this.varIndex.size() - 1
225224
|| !this.varIndex.get(this.varIndex.size() - 1).getDefinedType().isVarargs()) {
226225
var = this.varIndex.get(varInd);
@@ -232,21 +231,33 @@ public Mixed execute(List<Mixed> args, Environment oldEnv, Target t) {
232231
env.getEnv(GlobalEnv.class).GetVarList().set(new IVariable(CArray.TYPE,
233232
var.getVariableName(), vararg, c.getTarget()));
234233
}
235-
isVarArg = true;
236234
}
235+
236+
// Type check "void" value.
237237
if(c instanceof CVoid
238238
&& !(var.getDefinedType().equals(Auto.TYPE) || var.getDefinedType().equals(CVoid.TYPE))) {
239239
throw new CRECastException("Procedure \"" + name + "\" expects a value of type "
240240
+ var.getDefinedType().val() + " in argument " + (varInd + 1) + ", but"
241241
+ " a void value was found instead.", c.getTarget());
242-
} else if((!(c instanceof CVoid) && c instanceof CNull) || var.getDefinedType().equals(Auto.TYPE)
243-
|| InstanceofUtil.isInstanceof(c.typeof(), var.getDefinedType(), env)) {
244-
if(isVarArg) {
242+
}
243+
244+
// Type check vararg parameter.
245+
if(var.getDefinedType().isVarargs()) {
246+
if(InstanceofUtil.isInstanceof(c.typeof(), var.getDefinedType().getVarargsBaseType(), env)) {
245247
vararg.push(c, t);
248+
continue;
246249
} else {
247-
env.getEnv(GlobalEnv.class).GetVarList().set(new IVariable(var.getDefinedType(),
248-
var.getVariableName(), c, c.getTarget()));
250+
throw new CRECastException("Procedure \"" + name + "\" expects a value of type "
251+
+ var.getDefinedType().val() + " in argument " + (varInd + 1) + ", but"
252+
+ " a value of type " + c.typeof() + " was found instead.", c.getTarget());
249253
}
254+
}
255+
256+
// Type check non-vararg parameter.
257+
if(InstanceofUtil.isInstanceof(c.typeof(), var.getDefinedType(), env)) {
258+
env.getEnv(GlobalEnv.class).GetVarList().set(new IVariable(var.getDefinedType(),
259+
var.getVariableName(), c, c.getTarget()));
260+
continue;
250261
} else {
251262
throw new CRECastException("Procedure \"" + name + "\" expects a value of type "
252263
+ var.getDefinedType().val() + " in argument " + (varInd + 1) + ", but"

src/main/java/com/laytonsmith/core/constructs/CClassType.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,4 +680,19 @@ public boolean isVarargs() {
680680
return this.isVararg;
681681
}
682682

683+
/**
684+
* Returns the base type of this varargs type.
685+
* @return The base {@link CClassType} of this type (e.g. `string` for `string...`).
686+
* @throws IllegalStateException - If this is not a vararg type.
687+
*/
688+
public CClassType getVarargsBaseType() throws IllegalStateException {
689+
if(!this.isVararg) {
690+
throw new IllegalStateException("CClassType is not a vararg type.");
691+
}
692+
try {
693+
return CClassType.get(this.fqcn);
694+
} catch (ClassNotFoundException e) {
695+
throw new Error(e); // Existence of this vararg type implies that its base type exists.
696+
}
697+
}
683698
}

0 commit comments

Comments
 (0)