use of com.laytonsmith.core.taskmanager.TaskManager in project CommandHelper by EngineHub.
the class CommandHelperInterpreterListener method execute.
public void execute(String script, final MCPlayer p) throws ConfigCompileException, ConfigCompileGroupException {
TokenStream stream = MethodScriptCompiler.lex(script, new File("Interpreter"), true);
ParseTree tree = MethodScriptCompiler.compile(stream);
interpreterMode.remove(p.getName());
GlobalEnv gEnv = new GlobalEnv(plugin.executionQueue, plugin.profiler, plugin.persistenceNetwork, CommandHelperFileLocations.getDefault().getConfigDirectory(), plugin.profiles, new TaskManager());
gEnv.SetDynamicScriptingMode(true);
CommandHelperEnvironment cEnv = new CommandHelperEnvironment();
cEnv.SetPlayer(p);
Environment env = Environment.createEnvironment(gEnv, cEnv);
try {
MethodScriptCompiler.registerAutoIncludes(env, null);
MethodScriptCompiler.execute(tree, env, new MethodScriptComplete() {
@Override
public void done(String output) {
output = output.trim();
if (output.isEmpty()) {
Static.SendMessage(p, ":");
} else {
if (output.startsWith("/")) {
// Run the command
Static.SendMessage(p, ":" + MCChatColor.YELLOW + output);
p.chat(output);
} else {
// output the results
Static.SendMessage(p, ":" + MCChatColor.GREEN + output);
}
}
interpreterMode.add(p.getName());
}
}, null);
} catch (CancelCommandException e) {
interpreterMode.add(p.getName());
} catch (ConfigRuntimeException e) {
ConfigRuntimeException.HandleUncaughtException(e, env);
Static.SendMessage(p, MCChatColor.RED + e.toString());
interpreterMode.add(p.getName());
} catch (Exception e) {
Static.SendMessage(p, MCChatColor.RED + e.toString());
Logger.getLogger(CommandHelperInterpreterListener.class.getName()).log(Level.SEVERE, null, e);
interpreterMode.add(p.getName());
}
}
use of com.laytonsmith.core.taskmanager.TaskManager in project CommandHelper by EngineHub.
the class AliasCore method alias.
/**
* This is the workhorse function. It takes a given command, then converts it into the actual command(s). If the
* command maps to a defined alias, it will run the specified alias. It will search through the global list of
* aliases, as well as the aliases defined for that specific player. This function doesn't handle the /alias command
* however.
*
* @param command
* @return
*/
public boolean alias(String command, final MCCommandSender player) {
if (scripts == null) {
throw ConfigRuntimeException.CreateUncatchableException("Cannot run alias commands, no config file is loaded", Target.UNKNOWN);
}
boolean match = false;
try {
// actually add the player to the array.
if (player != null && player instanceof MCPlayer && echoCommand.contains(((MCPlayer) player).getName())) {
// we are running one of the expanded commands, so exit with false
return false;
}
for (Script s : scripts) {
try {
if (s.match(command)) {
this.addPlayerReference(player);
if (Prefs.ConsoleLogCommands() && s.doLog()) {
StringBuilder b = new StringBuilder("CH: Running original command ");
if (player instanceof MCPlayer) {
b.append("on player ").append(((MCPlayer) player).getName());
} else {
b.append("from a MCCommandSender");
}
b.append(" ----> ").append(command);
Static.getLogger().log(Level.INFO, b.toString());
}
GlobalEnv gEnv = new GlobalEnv(parent.executionQueue, parent.profiler, parent.persistenceNetwork, MethodScriptFileLocations.getDefault().getConfigDirectory(), parent.profiles, new TaskManager());
CommandHelperEnvironment cEnv = new CommandHelperEnvironment();
cEnv.SetCommandSender(player);
Environment env = Environment.createEnvironment(gEnv, cEnv);
try {
env.getEnv(CommandHelperEnvironment.class).SetCommand(command);
ProfilePoint alias = env.getEnv(GlobalEnv.class).GetProfiler().start("Global Alias - \"" + command + "\"", LogLevel.ERROR);
try {
s.run(s.getVariables(command), env, new MethodScriptComplete() {
@Override
public void done(String output) {
try {
if (output != null) {
if (!output.trim().isEmpty() && output.trim().startsWith("/")) {
if (Prefs.DebugMode()) {
if (player instanceof MCPlayer) {
Static.getLogger().log(Level.INFO, "[CommandHelper]: Executing command on " + ((MCPlayer) player).getName() + ": " + output.trim());
} else {
Static.getLogger().log(Level.INFO, "[CommandHelper]: Executing command from console equivalent: " + output.trim());
}
}
if (player instanceof MCPlayer) {
((MCPlayer) player).chat(output.trim());
} else {
Static.getServer().dispatchCommand(player, output.trim().substring(1));
}
}
}
} catch (Throwable e) {
StreamUtils.GetSystemErr().println(e.getMessage());
player.sendMessage(MCChatColor.RED + e.getMessage());
} finally {
Static.getAliasCore().removePlayerReference(player);
}
}
});
} finally {
alias.stop();
}
} catch (ConfigRuntimeException ex) {
ex.setEnv(env);
ConfigRuntimeException.HandleUncaughtException(ex, env);
} catch (Throwable e) {
// This is not a simple user script error, this is a deeper problem, so we always handle this.
StreamUtils.GetSystemErr().println("An unexpected exception occured: " + e.getClass().getSimpleName());
player.sendMessage("An unexpected exception occured: " + MCChatColor.RED + e.getClass().getSimpleName());
e.printStackTrace();
} finally {
Static.getAliasCore().removePlayerReference(player);
}
match = true;
break;
}
} catch (Exception e) {
StreamUtils.GetSystemErr().println("An unexpected exception occured inside the command " + s.toString());
e.printStackTrace();
}
}
} catch (Throwable e) {
// Not only did an error happen, an error happened in our error handler
throw new InternalException(TermColors.RED + "An unexpected error occured in the CommandHelper plugin. " + "Further, this is likely an error with the error handler, so it may be caused by your script, " + "however, there is no more information at this point. Check your script, but also report this " + "as a bug in CommandHelper. Also, it's possible that some commands will no longer work. As a temporary " + "workaround, restart the server, and avoid doing whatever it is you did to make this happen.\nThe error is as follows: " + e.toString() + "\n" + TermColors.reset() + "Stack Trace:\n" + StringUtils.Join(Arrays.asList(e.getStackTrace()), "\n"));
}
return match;
}
use of com.laytonsmith.core.taskmanager.TaskManager in project CommandHelper by EngineHub.
the class Manager method start.
@SuppressWarnings("ResultOfObjectAllocationIgnored")
public static void start() throws IOException, DataSourceException, URISyntaxException, Profiles.InvalidProfileException {
Implementation.useAbstractEnumThread(false);
Implementation.forceServerType(Implementation.Type.BUKKIT);
ConnectionMixinFactory.ConnectionMixinOptions options = new ConnectionMixinFactory.ConnectionMixinOptions();
options.setWorkingDirectory(chDirectory);
persistenceNetwork = new PersistenceNetwork(CommandHelperFileLocations.getDefault().getPersistenceConfig(), CommandHelperFileLocations.getDefault().getDefaultPersistenceDBFile().toURI(), options);
Installer.Install(chDirectory);
CHLog.initialize(chDirectory);
profiler = new Profiler(CommandHelperFileLocations.getDefault().getProfilerConfigFile());
gEnv = new GlobalEnv(new MethodScriptExecutionQueue("Manager", "default"), profiler, persistenceNetwork, chDirectory, new Profiles(MethodScriptFileLocations.getDefault().getProfilesFile()), new TaskManager());
cls();
pl("\n" + Static.Logo() + "\n\n" + Static.DataManagerLogo());
pl("Starting the Data Manager...");
try {
Environment env = Environment.createEnvironment(gEnv, new CommandHelperEnvironment());
MethodScriptCompiler.execute(MethodScriptCompiler.compile(MethodScriptCompiler.lex("player()", null, true)), env, null, null);
} catch (ConfigCompileException | ConfigCompileGroupException ex) {
}
pl(GREEN + "Welcome to the CommandHelper " + CYAN + "Data Manager!");
pl(BLINKON + RED + "Warning!" + BLINKOFF + YELLOW + " Be sure your server is not running before using this tool to make changes to your database!");
pl("------------------------");
boolean finished = false;
do {
pl(YELLOW + "What function would you like to run? Type \"help\" for a full list of options.");
String input = prompt();
pl();
if (input.toLowerCase().startsWith("help")) {
help(input.replaceFirst("help ?", "").toLowerCase().split(" "));
} else if (input.equalsIgnoreCase("refactor")) {
refactor();
} else if (input.toLowerCase().startsWith("print")) {
print(input.replaceFirst("print ?", "").toLowerCase().split(" "));
} else if (input.equalsIgnoreCase("cleardb")) {
cleardb();
} else if (input.equalsIgnoreCase("edit")) {
edit();
} else if (input.equalsIgnoreCase("merge")) {
merge();
} else if (input.equalsIgnoreCase("interpreter")) {
new Interpreter(null, System.getProperty("user.dir"));
} else if (input.equalsIgnoreCase("hidden-keys")) {
hiddenKeys();
} else if (input.equalsIgnoreCase("exit")) {
pl("Thanks for using the " + CYAN + BOLD + "Data Manager!" + reset());
finished = true;
} else {
pl("I'm sorry, that's not a valid command. Here's the help:");
help(new String[] {});
}
} while (finished == false);
StreamUtils.GetSystemOut().println(TermColors.reset());
}
use of com.laytonsmith.core.taskmanager.TaskManager in project CommandHelper by EngineHub.
the class AliasCore method reload.
/**
* Loads the global alias file in from the file system. If a player is running the command, send a reference to
* them, and they will see compile errors, otherwise, null.
*
* @param player
* @param settings The argument list for the settings.
* @param firstLoad Indicates that CH is loading
*/
public final void reload(MCPlayer player, String[] settings, boolean firstLoad) {
ReloadOptions options;
try {
options = new ReloadOptions(settings);
} catch (Exception ex) {
if (player != null) {
player.sendMessage(ex.getMessage());
} else {
StreamUtils.GetSystemOut().println(ex.getMessage());
}
return;
}
try {
if (Prefs.AllowDynamicShell()) {
CHLog.GetLogger().Log(CHLog.Tags.GENERAL, LogLevel.WARNING, "allow-dynamic-shell is set to true in " + CommandHelperFileLocations.getDefault().getProfilerConfigFile().getName() + " you should set this to false, except during development.", Target.UNKNOWN);
}
if (parent.profiler == null || options.reloadProfiler()) {
parent.profiler = new Profiler(MethodScriptFileLocations.getDefault().getProfilerConfigFile());
}
ProfilePoint extensionPreReload = parent.profiler.start("Extension PreReloadAliases call", LogLevel.VERBOSE);
try {
// Allow new-style extensions know we are about to reload aliases.
ExtensionManager.PreReloadAliases(options);
} finally {
extensionPreReload.stop();
}
ProfilePoint shutdownHooks = parent.profiler.start("Shutdown hooks call", LogLevel.VERBOSE);
try {
StaticLayer.GetConvertor().runShutdownHooks();
} finally {
shutdownHooks.stop();
}
if (!firstLoad && options.reloadExtensions()) {
ProfilePoint extensionManagerShutdown = parent.profiler.start("Extension manager shutdown", LogLevel.VERBOSE);
try {
ExtensionManager.Shutdown();
} finally {
extensionManagerShutdown.stop();
}
}
CHLog.initialize(MethodScriptFileLocations.getDefault().getConfigDirectory());
// Clear out the data source cache
DataSourceFactory.DisconnectAll();
// PacketJumper.startup(); we're not using this yet
if (options.reloadExtensions()) {
ProfilePoint extensionManagerStartup = parent.profiler.start("Extension manager startup", LogLevel.VERBOSE);
try {
ExtensionManager.Startup();
} finally {
extensionManagerStartup.stop();
}
}
CHLog.GetLogger().Log(CHLog.Tags.GENERAL, LogLevel.VERBOSE, "Scripts reloading...", Target.UNKNOWN);
if (parent.persistenceNetwork == null || options.reloadPersistenceConfig()) {
ProfilePoint persistenceConfigReload = parent.profiler.start("Reloading persistence configuration", LogLevel.VERBOSE);
try {
MemoryDataSource.ClearDatabases();
ConnectionMixinFactory.ConnectionMixinOptions mixinOptions = new ConnectionMixinFactory.ConnectionMixinOptions();
mixinOptions.setWorkingDirectory(MethodScriptFileLocations.getDefault().getConfigDirectory());
parent.persistenceNetwork = new PersistenceNetwork(MethodScriptFileLocations.getDefault().getPersistenceConfig(), new URI("sqlite:/" + MethodScriptFileLocations.getDefault().getDefaultPersistenceDBFile().getCanonicalFile().toURI().getRawSchemeSpecificPart().replace('\\', '/')), mixinOptions);
} finally {
persistenceConfigReload.stop();
}
}
try {
parent.profiles = new Profiles(MethodScriptFileLocations.getDefault().getProfilesFile());
} catch (IOException | Profiles.InvalidProfileException ex) {
CHLog.GetLogger().e(CHLog.Tags.GENERAL, ex.getMessage(), Target.UNKNOWN);
return;
}
GlobalEnv gEnv = new GlobalEnv(parent.executionQueue, parent.profiler, parent.persistenceNetwork, MethodScriptFileLocations.getDefault().getConfigDirectory(), parent.profiles, new TaskManager());
gEnv.SetLabel(Static.GLOBAL_PERMISSION);
if (options.reloadExecutionQueue()) {
ProfilePoint stoppingExecutionQueue = parent.profiler.start("Stopping execution queues", LogLevel.VERBOSE);
try {
parent.executionQueue.stopAllNow();
} finally {
stoppingExecutionQueue.stop();
}
}
CommandHelperEnvironment cEnv = new CommandHelperEnvironment();
Environment env = Environment.createEnvironment(gEnv, cEnv);
if (options.reloadGlobals()) {
ProfilePoint clearingGlobals = parent.profiler.start("Clearing globals", LogLevel.VERBOSE);
try {
Globals.clear();
} finally {
clearingGlobals.stop();
}
}
if (options.reloadTimeouts()) {
ProfilePoint clearingTimeouts = parent.profiler.start("Clearing timeouts/intervals", LogLevel.VERBOSE);
try {
Scheduling.ClearScheduledRunners();
} finally {
clearingTimeouts.stop();
}
}
if (!aliasConfig.exists()) {
aliasConfig.getParentFile().mkdirs();
aliasConfig.createNewFile();
try {
String samp_aliases = getStringResource(AliasCore.class.getResourceAsStream("/samp_aliases.txt"));
// Because the sample config may have been written an a machine that isn't this type, replace all
// line endings
samp_aliases = samp_aliases.replaceAll("\n|\r\n", System.getProperty("line.separator"));
file_put_contents(aliasConfig, samp_aliases, "o");
} catch (Exception e) {
logger.log(Level.WARNING, "CommandHelper: Could not write sample config file");
}
}
if (!mainFile.exists()) {
mainFile.getParentFile().mkdirs();
mainFile.createNewFile();
try {
String samp_main = getStringResource(AliasCore.class.getResourceAsStream("/samp_main.txt"));
samp_main = samp_main.replaceAll("\n|\r\n", System.getProperty("line.separator"));
file_put_contents(mainFile, samp_main, "o");
} catch (Exception e) {
logger.log(Level.WARNING, "CommandHelper: Could not write sample main file");
}
}
if (!Prefs.isInitialized()) {
Prefs.init(prefFile);
}
if (options.reloadScripts()) {
ProfilePoint unregisteringEvents = parent.profiler.start("Unregistering events", LogLevel.VERBOSE);
try {
EventUtils.UnregisterAll();
} finally {
unregisteringEvents.stop();
}
ProfilePoint runningExtensionHooks = parent.profiler.start("Running event hooks", LogLevel.VERBOSE);
try {
ExtensionManager.RunHooks();
} finally {
runningExtensionHooks.stop();
}
// Clear the include cache, so it re-pulls files
IncludeCache.clearCache();
// Close all channel messager channels registered by CH.
Static.getServer().getMessenger().closeAllChannels();
scripts = new ArrayList<Script>();
LocalPackage localPackages = new LocalPackage();
// Run the main file once
String main = file_get_contents(mainFile.getAbsolutePath());
localPackages.appendMS(main, mainFile);
// get the file again
String alias_config = file_get_contents(aliasConfig.getAbsolutePath());
localPackages.appendMSA(alias_config, aliasConfig);
File auto_include = new File(env.getEnv(GlobalEnv.class).GetRootFolder(), "auto_include.ms");
if (auto_include.exists()) {
localPackages.addAutoInclude(auto_include);
}
// Now that we've included the default files, search the local_packages directory
GetAuxAliases(auxAliases, localPackages);
autoIncludes = localPackages.getAutoIncludes();
ProfilePoint compilerMS = parent.profiler.start("Compilation of MS files in Local Packages", LogLevel.VERBOSE);
try {
env.getEnv(CommandHelperEnvironment.class).SetCommandSender(Static.getServer().getConsole());
MethodScriptCompiler.registerAutoIncludes(env, null);
localPackages.compileMS(player, env);
} finally {
env.getEnv(CommandHelperEnvironment.class).SetCommandSender(null);
compilerMS.stop();
}
ProfilePoint compilerMSA = parent.profiler.start("Compilation of MSA files in Local Packages", LogLevel.VERBOSE);
try {
localPackages.compileMSA(scripts, player);
} finally {
compilerMSA.stop();
}
}
} catch (IOException ex) {
logger.log(Level.SEVERE, "[CommandHelper]: Path to config file is not correct/accessable. Please" + " check the location and try loading the plugin again.");
} catch (Throwable t) {
t.printStackTrace();
}
ProfilePoint postReloadAliases = parent.profiler.start("Extension manager post reload aliases", LogLevel.VERBOSE);
try {
ExtensionManager.PostReloadAliases();
} finally {
postReloadAliases.stop();
}
}
use of com.laytonsmith.core.taskmanager.TaskManager in project CommandHelper by EngineHub.
the class MethodScriptCompiler method optimize.
/**
* Recurses down into the tree, attempting to optimize where possible. A few things have strong coupling, for
* information on these items, see the documentation included in the source.
*
* @param tree
* @return
*/
private static void optimize(ParseTree tree, Stack<List<Procedure>> procs, Set<ConfigCompileException> compilerErrors) {
if (tree.isOptimized()) {
// Don't need to re-run this
return;
}
// }
if (!(tree.getData() instanceof CFunction)) {
// There's no way to optimize something that's not a function
return;
}
// If it is a proc definition, we need to go ahead and see if we can add it to the const proc stack
if (tree.getData().val().equals("proc")) {
procs.push(new ArrayList<Procedure>());
}
CFunction cFunction = (CFunction) tree.getData();
Function func;
try {
func = (Function) FunctionList.getFunction(cFunction);
} catch (ConfigCompileException e) {
func = null;
}
if (func != null) {
if (func.getClass().getAnnotation(nolinking.class) != null) {
// It's an unlinking function, so we need to stop at this point
return;
}
}
if (cFunction instanceof CIdentifier) {
// Add the child to the identifier
ParseTree c = ((CIdentifier) cFunction).contained();
tree.addChild(c);
c.getData().setWasIdentifier(true);
}
List<ParseTree> children = tree.getChildren();
if (func instanceof Optimizable && ((Optimizable) func).optimizationOptions().contains(OptimizationOption.PRIORITY_OPTIMIZATION)) {
// would cause an error, even though the user did in fact provide code in that section.
try {
((Optimizable) func).optimizeDynamic(tree.getTarget(), children, tree.getFileOptions());
} catch (ConfigCompileException ex) {
// If an error occurs, we will skip the rest of this element
compilerErrors.add(ex);
return;
} catch (ConfigRuntimeException ex) {
compilerErrors.add(new ConfigCompileException(ex));
return;
}
}
for (int i = 0; i < children.size(); i++) {
ParseTree t = children.get(i);
if (t.getData() instanceof CFunction) {
if (t.getData().val().startsWith("_") || (func != null && func.useSpecialExec())) {
continue;
}
Function f;
try {
f = (Function) FunctionList.getFunction(t.getData());
} catch (ConfigCompileException ex) {
compilerErrors.add(ex);
return;
}
Set<OptimizationOption> options = NO_OPTIMIZATIONS;
if (f instanceof Optimizable) {
options = ((Optimizable) f).optimizationOptions();
}
if (options.contains(OptimizationOption.TERMINAL)) {
if (children.size() > i + 1) {
// First, a compiler warning
CHLog.GetLogger().Log(CHLog.Tags.COMPILER, LogLevel.WARNING, "Unreachable code. Consider removing this code.", children.get(i + 1).getTarget());
// Now, truncate the children
for (int j = children.size() - 1; j > i; j--) {
children.remove(j);
}
break;
}
}
}
}
boolean fullyStatic = true;
boolean hasIVars = false;
for (ParseTree node : children) {
if (node.getData() instanceof CFunction) {
optimize(node, procs, compilerErrors);
}
if (node.getData().isDynamic() && !(node.getData() instanceof IVariable)) {
fullyStatic = false;
}
if (node.getData() instanceof IVariable) {
hasIVars = true;
}
}
// In all cases, at this point, we are either unable to optimize, or we will
// optimize, so set our optimized variable at this point.
tree.setOptimized(true);
if (func == null) {
// It's a proc call. Let's see if we can optimize it
Procedure p = null;
loop: for (List<Procedure> proc : procs) {
for (Procedure pp : proc) {
if (pp.getName().equals(cFunction.val())) {
p = pp;
break loop;
}
}
}
if (p != null) {
try {
Construct c = DataHandling.proc.optimizeProcedure(p.getTarget(), p, children);
if (c != null) {
tree.setData(c);
tree.removeChildren();
return;
}
// else Nope, couldn't optimize.
} catch (ConfigRuntimeException ex) {
// Cool. Caught a runtime error at compile time :D
compilerErrors.add(new ConfigCompileException(ex));
}
}
// so we can't for sure say, but we do know we can't optimize this
return;
}
if (tree.getData().val().equals("proc")) {
// Check for too few arguments
if (children.size() < 2) {
compilerErrors.add(new ConfigCompileException("Incorrect number of arguments passed to proc", tree.getData().getTarget()));
return;
}
// We just went out of scope, so we need to pop the layer of Procedures that
// are internal to us
procs.pop();
// Let's see.
try {
ParseTree root = new ParseTree(new CFunction(__autoconcat__, Target.UNKNOWN), tree.getFileOptions());
Script fakeScript = Script.GenerateScript(root, "*");
Environment env = null;
try {
if (Implementation.GetServerType().equals(Implementation.Type.BUKKIT)) {
CommandHelperPlugin plugin = CommandHelperPlugin.self;
GlobalEnv gEnv = new GlobalEnv(plugin.executionQueue, plugin.profiler, plugin.persistenceNetwork, MethodScriptFileLocations.getDefault().getConfigDirectory(), plugin.profiles, new TaskManager());
env = Environment.createEnvironment(gEnv, new CommandHelperEnvironment());
} else {
env = Static.GenerateStandaloneEnvironment(false);
}
} catch (IOException | DataSourceException | URISyntaxException | Profiles.InvalidProfileException e) {
//
}
Procedure myProc = DataHandling.proc.getProcedure(tree.getTarget(), env, fakeScript, children.toArray(new ParseTree[children.size()]));
// Yep. So, we can move on with our lives now, and if it's used later, it could possibly be static.
procs.peek().add(myProc);
} catch (ConfigRuntimeException e) {
// Well, they have an error in there somewhere
compilerErrors.add(new ConfigCompileException(e));
} catch (NullPointerException e) {
// Nope, can't optimize.
return;
}
}
// the compiler trick functions know how to deal with it specially, even if everything isn't
// static, so do this first.
String oldFunctionName = func.getName();
Set<OptimizationOption> options = NO_OPTIMIZATIONS;
if (func instanceof Optimizable) {
options = ((Optimizable) func).optimizationOptions();
}
if (options.contains(OptimizationOption.OPTIMIZE_DYNAMIC)) {
try {
ParseTree tempNode;
try {
tempNode = ((Optimizable) func).optimizeDynamic(tree.getData().getTarget(), tree.getChildren(), tree.getFileOptions());
} catch (ConfigRuntimeException e) {
// Turn it into a compile exception, then rethrow
throw new ConfigCompileException(e);
}
if (tempNode == Optimizable.PULL_ME_UP) {
if (tree.hasChildren()) {
tempNode = tree.getChildAt(0);
} else {
tempNode = null;
}
}
if (tempNode == Optimizable.REMOVE_ME) {
tree.setData(new CFunction("p", Target.UNKNOWN));
tree.removeChildren();
} else if (tempNode != null) {
tree.setData(tempNode.getData());
tree.setOptimized(tempNode.isOptimized());
tree.setChildren(tempNode.getChildren());
tree.getData().setWasIdentifier(tempNode.getData().wasIdentifier());
optimize(tree, procs, compilerErrors);
tree.setOptimized(true);
// array, so if they have reversed this, make note of that now
if (tempNode.hasBeenMadeStatic()) {
fullyStatic = true;
}
}
// else it wasn't an optimization, but a compile check
} catch (ConfigCompileException ex) {
compilerErrors.add(ex);
}
}
if (!fullyStatic) {
return;
}
// specially from here forward
if (func.preResolveVariables() && hasIVars) {
// Well, this function isn't equipped to deal with IVariables.
return;
}
// don't want to run this now
if (tree.getData().getValue().equals(oldFunctionName) && (options.contains(OptimizationOption.OPTIMIZE_CONSTANT) || options.contains(OptimizationOption.CONSTANT_OFFLINE))) {
Construct[] constructs = new Construct[tree.getChildren().size()];
for (int i = 0; i < tree.getChildren().size(); i++) {
constructs[i] = tree.getChildAt(i).getData();
}
try {
try {
Construct result;
if (options.contains(OptimizationOption.CONSTANT_OFFLINE)) {
List<Integer> numArgsList = Arrays.asList(func.numArgs());
if (!numArgsList.contains(Integer.MAX_VALUE) && !numArgsList.contains(tree.getChildren().size())) {
compilerErrors.add(new ConfigCompileException("Incorrect number of arguments passed to " + tree.getData().val(), tree.getData().getTarget()));
result = null;
} else {
result = func.exec(tree.getData().getTarget(), null, constructs);
}
} else {
result = ((Optimizable) func).optimize(tree.getData().getTarget(), constructs);
}
// If the result is null, it was just a check, it can't optimize further.
if (result != null) {
result.setWasIdentifier(tree.getData().wasIdentifier());
tree.setData(result);
tree.removeChildren();
}
} catch (ConfigRuntimeException e) {
// Turn this into a ConfigCompileException, then rethrow
throw new ConfigCompileException(e);
}
} catch (ConfigCompileException ex) {
compilerErrors.add(ex);
}
}
// It doesn't know how to optimize. Oh well.
}
Aggregations