Skip to content

Commit

Permalink
Further validate type format before rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
PseudoKnight committed Mar 29, 2024
1 parent bed9686 commit c21762f
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1951,7 +1951,6 @@ private static void checkLinearComponents(ParseTree tree, Environment env,
new CompilerWarning("Use of bare (unquoted) string: "
+ m.getData().val(), m.getTarget(),
FileOptions.SuppressWarning.UseBareStrings));
return; // for now, only one warning per file
}
}
}
Expand Down
49 changes: 35 additions & 14 deletions src/main/java/com/laytonsmith/core/functions/Compiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -464,11 +464,34 @@ public static ParseTree rewrite(List<ParseTree> list, boolean returnSConcat,
}

// Look for typed assignments
for(int k = 0; k < list.size(); k++) {
if(list.get(k).getData().equals(CVoid.VOID) || list.get(k).getData().isInstanceOf(CClassType.TYPE)
|| (list.get(k).getData().getClass().equals(CBareString.class))
|| (list.get(k).getData() instanceof CFunction
&& list.get(k).getData().val().equals(concat.NAME))) {
typedAssignmentLoop: for(int k = 0; k < list.size(); k++) {
ParseTree typeNode = list.get(k);
if(typeNode.getData().equals(CVoid.VOID) || typeNode.getData().isInstanceOf(CClassType.TYPE)
|| (typeNode.getData().getClass().equals(CBareString.class))
|| (typeNode.getData() instanceof CFunction
&& typeNode.getData().val().equals(concat.NAME))) {

// If concat, ensure only CClassType or CBareString are being concatenated.
// This can be nested once: concat(concat(ms, lang), string)
if(typeNode.getData() instanceof CFunction) {
for(ParseTree concatChild : typeNode.getChildren()) {
if(concatChild.getData() instanceof CFunction) {
if(!concatChild.getData().val().equals(concat.NAME)) {
continue typedAssignmentLoop;
}
for(ParseTree innerConcatChild : concatChild.getChildren()) {
if(!innerConcatChild.getData().isInstanceOf(CClassType.TYPE)
&& !innerConcatChild.getData().getClass().equals(CBareString.class)) {
continue typedAssignmentLoop;
}
}
} else if(!concatChild.getData().isInstanceOf(CClassType.TYPE)
&& !concatChild.getData().getClass().equals(CBareString.class)) {
continue typedAssignmentLoop;
}
}
}

if(k == list.size() - 1) {
// This is not a typed assignment
break;
Expand All @@ -483,11 +506,11 @@ public static ParseTree rewrite(List<ParseTree> list, boolean returnSConcat,
case "proc":
// Typed assign/closure
if(list.get(k + 1).getData().val().equals(assign.NAME)
&& list.get(k).getData().equals(CVoid.VOID)) {
&& typeNode.getData().equals(CVoid.VOID)) {
throw new ConfigCompileException("Variables may not be of type void",
list.get(k + 1).getTarget());
}
ParseTree typeNode = list.remove(k);
typeNode = list.remove(k);

// Convert bare string or concat() to type reference as it is used like that in syntax.
ParseTree typeRefNode = __type_ref__.createFromBareStringOrConcats(typeNode);
Expand All @@ -500,12 +523,11 @@ public static ParseTree rewrite(List<ParseTree> list, boolean returnSConcat,
list.get(k).setChildren(children);
break;
default:
throw new ConfigCompileException("Unexpected ClassType \"" + list.get(k).getData().val() + "\"", list.get(k).getTarget());
throw new ConfigCompileException("Unexpected ClassType \"" + typeNode.getData().val() + "\"", typeNode.getTarget());
}
} else if(list.get(k + 1).getData() instanceof IVariable) {
// Not an assignment, a random variable declaration though.
ParseTree node = new ParseTree(new CFunction(assign.NAME, list.get(k + 1).getTarget()), list.get(k).getFileOptions());
ParseTree typeNode = list.get(k);
ParseTree node = new ParseTree(new CFunction(assign.NAME, list.get(k + 1).getTarget()), typeNode.getFileOptions());

// Convert bare string or concat() to type reference as it is used like that in syntax.
ParseTree typeRefNode = __type_ref__.createFromBareStringOrConcats(typeNode);
Expand All @@ -515,12 +537,11 @@ public static ParseTree rewrite(List<ParseTree> list, boolean returnSConcat,

node.addChild(typeNode);
node.addChild(list.get(k + 1));
node.addChild(new ParseTree(CNull.UNDEFINED, list.get(k).getFileOptions()));
node.addChild(new ParseTree(CNull.UNDEFINED, typeNode.getFileOptions()));
list.set(k, node);
list.remove(k + 1);
} else if(list.get(k + 1).getData() instanceof CLabel) {
ParseTree node = new ParseTree(new CFunction(assign.NAME, list.get(k + 1).getTarget()), list.get(k).getFileOptions());
ParseTree typeNode = list.get(k);
ParseTree node = new ParseTree(new CFunction(assign.NAME, list.get(k + 1).getTarget()), typeNode.getFileOptions());

// Convert bare string or concat() to type reference as it is used like that in syntax.
ParseTree typeRefNode = __type_ref__.createFromBareStringOrConcats(typeNode);
Expand All @@ -534,7 +555,7 @@ public static ParseTree rewrite(List<ParseTree> list, boolean returnSConcat,
labelNode.addChild(new ParseTree(CNull.UNDEFINED, typeNode.getFileOptions()));
list.set(k, labelNode);
list.remove(k + 1);
} else if(list.get(k).getData().getClass().equals(CBareString.class)) {
} else if(typeNode.getData().getClass().equals(CBareString.class)) {
continue; // Bare string was not used as a type.
} else {
throw new ConfigCompileException("Unexpected data after ClassType", list.get(k + 1).getTarget());
Expand Down

0 comments on commit c21762f

Please sign in to comment.