From 595990186c7ceb7398a515b1441c828f95fdf098 Mon Sep 17 00:00:00 2001 From: Pieter12345 Date: Fri, 13 Jan 2023 04:09:47 +0100 Subject: [PATCH] Fix self statement semicolon rewrite Fix semicolons not getting added to self statements where placement was intended. --- .../core/MethodScriptCompiler.java | 43 +++++++++++++------ 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/laytonsmith/core/MethodScriptCompiler.java b/src/main/java/com/laytonsmith/core/MethodScriptCompiler.java index a9fec423d..d1ae38766 100644 --- a/src/main/java/com/laytonsmith/core/MethodScriptCompiler.java +++ b/src/main/java/com/laytonsmith/core/MethodScriptCompiler.java @@ -1912,7 +1912,8 @@ public static ParseTree compile(TokenStream stream, Environment environment, Stack> procs = new Stack<>(); procs.add(new ArrayList<>()); processKeywords(tree, environment, compilerErrors); - addSelfStatements(tree, environment, envs, compilerErrors); + addSelfStatements(rootNode, environment, envs, compilerErrors); // Pass rootNode since this might rewrite 'tree'. + tree = rootNode.getChildAt(0); rewriteAutoconcats(tree, environment, envs, compilerErrors, true); processLateKeywords(tree, environment, compilerErrors); checkLinearComponents(tree, environment, compilerErrors); @@ -2075,10 +2076,19 @@ private static void moveNodeModifiersOffSyntheticNodes(ParseTree node) { } } - private static void addSelfStatements(ParseTree root, Environment env, + /** + * Adds semicolon AST nodes after self statements within children of the given AST node (following + * {@link Function#isSelfStatement(Target, Environment, List, Set)}). + * When the self statement is not yet within an {@link __autoconcat__}, it is wrapped into one. + * @param ast - The abstract syntax tree. + * @param env - The environment. + * @param envs - The set of expected environment classes at runtime. + * @param compilerErrors - A set to put compile errors in. + */ + private static void addSelfStatements(ParseTree ast, Environment env, Set> envs, Set compilerErrors) { - for(int i = 0; i < root.numberOfChildren(); i++) { - ParseTree node = root.getChildAt(i); + for(int i = 0; i < ast.numberOfChildren(); i++) { + ParseTree node = ast.getChildAt(i); boolean isSelfStatement; try { isSelfStatement = node.getData() instanceof CFunction cf @@ -2090,16 +2100,21 @@ private static void addSelfStatements(ParseTree root, Environment env, return; } if(isSelfStatement) { - int offset = i + 1; - if(!(root.getData() instanceof CFunction cf && cf.val().equals(Compiler.__autoconcat__.NAME))) { - // We need to create an autoconcat node first, and put this and the semicolon in that - ParseTree newNode = new ParseTree(new CFunction(Compiler.__autoconcat__.NAME, Target.UNKNOWN), root.getFileOptions(), true); - newNode.addChild(root); - root = newNode; - offset = 1; - } - root.getChildren().add(offset, new ParseTree(new CSemicolon(Target.UNKNOWN), - node.getFileOptions(), true)); + if(ast.getData() instanceof CFunction cf && cf.val().equals(Compiler.__autoconcat__.NAME)) { + + // Add semicolon to existing autoconcat. + ast.getChildren().add(i + 1, new ParseTree( + new CSemicolon(Target.UNKNOWN), node.getFileOptions(), true)); + i++; // Skip added semicolon. + } else { + + // Replace node with an autoconcat that contains the node and a semicolon. + ParseTree newNode = new ParseTree(new CFunction( + Compiler.__autoconcat__.NAME, Target.UNKNOWN), ast.getFileOptions(), true); + newNode.addChild(node); + newNode.addChild(new ParseTree(new CSemicolon(Target.UNKNOWN), node.getFileOptions(), true)); + ast.getChildren().set(i, newNode); + } } addSelfStatements(node, env, envs, compilerErrors); }