Search in sources :

Example 1 with Optimizable

use of com.laytonsmith.core.Optimizable in project CommandHelper by EngineHub.

the class DocGen method examples.

public static String examples(String function, boolean staged) throws Exception {
    FunctionBase fb = FunctionList.getFunction(new CFunction(function, Target.UNKNOWN));
    if (fb instanceof Function) {
        Function f = (Function) fb;
        String restricted = (f instanceof Function && ((Function) f).isRestricted()) ? "<div style=\"background-color: red; font-weight: bold; text-align: center;\">Yes</div>" : "<div style=\"background-color: green; font-weight: bold; text-align: center;\">No</div>";
        String optimizationMessage = "None";
        if (f instanceof Optimizable) {
            Set<Optimizable.OptimizationOption> options = ((Optimizable) f).optimizationOptions();
            List<String> list = new ArrayList<String>();
            for (Optimizable.OptimizationOption option : options) {
                list.add("[[CommandHelper/" + (staged ? "Staged/" : "") + "Optimizer#" + option.name() + "|" + option.name() + "]]");
            }
            optimizationMessage = StringUtils.Join(list, "<br />");
        }
        DocInfo di = new DocInfo(f.docs());
        StringBuilder thrown = new StringBuilder();
        if (f instanceof Function && ((Function) f).thrown() != null) {
            List thrownList = Arrays.asList(((Function) f).thrown());
            for (int i = 0; i < thrownList.size(); i++) {
                String t = ((Class<? extends CREThrowable>) thrownList.get(i)).getAnnotation(typeof.class).value();
                if (i != 0) {
                    thrown.append("<br />\n");
                }
                thrown.append("[[CommandHelper/Exceptions#").append(t).append("|").append(t).append("]]");
            }
        }
        String tableUsages = di.originalArgs.replace("|", "<hr />");
        String[] usages = di.originalArgs.split("\\|");
        StringBuilder usageBuilder = new StringBuilder();
        for (String usage : usages) {
            usageBuilder.append("<pre>\n").append(f.getName()).append("(").append(usage.trim()).append(")\n</pre>");
        }
        StringBuilder exampleBuilder = new StringBuilder();
        if (f.examples() != null && f.examples().length > 0) {
            int count = 1;
            // If the output was automatically generated, change the color of the pre
            for (ExampleScript es : f.examples()) {
                exampleBuilder.append("====Example ").append(count).append("====\n").append(es.getDescription()).append("\n\n" + "Given the following code:\n");
                exampleBuilder.append(SimpleSyntaxHighlighter.Highlight(es.getScript(), true)).append("\n");
                String style = "";
                if (es.isAutomatic()) {
                    style = " style=\"background-color: #BDC7E9\"";
                    exampleBuilder.append("\n\nThe output would be:\n<pre");
                } else {
                    exampleBuilder.append("\n\nThe output might be:\n<pre");
                }
                exampleBuilder.append(style).append(">").append(es.getOutput()).append("</pre>\n");
                count++;
            }
        } else {
            exampleBuilder.append("Sorry, there are no examples for this function! :(");
        }
        Class[] seeAlso = f.seeAlso();
        String seeAlsoText = "";
        if (seeAlso != null && seeAlso.length > 0) {
            seeAlsoText += "===See Also===\n";
            boolean first = true;
            for (Class c : seeAlso) {
                if (!first) {
                    seeAlsoText += ", ";
                }
                first = false;
                if (Function.class.isAssignableFrom(c)) {
                    Function f2 = (Function) c.newInstance();
                    seeAlsoText += "<code>[[CommandHelper/" + (staged ? "Staged/" : "") + "API/" + f2.getName() + "|" + f2.getName() + "]]</code>";
                } else if (Template.class.isAssignableFrom(c)) {
                    Template t = (Template) c.newInstance();
                    seeAlsoText += "[[CommandHelper/" + (staged ? "Staged/" : "") + t.getName() + "|Learning Trail: " + t.getDisplayName() + "]]";
                } else {
                    throw new Error("Unsupported class found in @seealso annotation: " + c.getName());
                }
            }
        }
        Map<String, String> templateFields = new HashMap<>();
        templateFields.put("function_name", f.getName());
        templateFields.put("returns", di.ret);
        templateFields.put("tableUsages", tableUsages);
        templateFields.put("throws", thrown.toString());
        templateFields.put("since", f.since().toString());
        templateFields.put("restricted", restricted);
        templateFields.put("optimizationMessage", optimizationMessage);
        templateFields.put("description", di.extendedDesc == null ? di.desc : di.topDesc + "\n\n" + di.extendedDesc);
        templateFields.put("usages", usageBuilder.toString());
        templateFields.put("examples", exampleBuilder.toString());
        templateFields.put("staged", staged ? "Staged/" : "");
        templateFields.put("seeAlso", seeAlsoText);
        String template = StreamUtils.GetString(DocGenTemplates.class.getResourceAsStream("/templates/example_templates"));
        // Find all the %%templates%% in the template
        Matcher m = Pattern.compile("%%(.*?)%%").matcher(template);
        try {
            while (m.find()) {
                String name = m.group(1);
                String templateValue = templateFields.get(name);
                template = template.replaceAll("%%" + Pattern.quote(name) + "%%", templateValue.replace("$", "\\$").replaceAll("\\'", "\\\\'"));
            }
            return template;
        } catch (RuntimeException e) {
            throw new RuntimeException("Caught a runtime exception while generating template for " + function, e);
        }
    } else {
        throw new RuntimeException(function + " does not implement Function");
    }
}
Also used : FunctionBase(com.laytonsmith.core.functions.FunctionBase) HashMap(java.util.HashMap) Matcher(java.util.regex.Matcher) ArrayList(java.util.ArrayList) Template(com.laytonsmith.tools.docgen.templates.Template) CFunction(com.laytonsmith.core.constructs.CFunction) Function(com.laytonsmith.core.functions.Function) ArrayList(java.util.ArrayList) FunctionList(com.laytonsmith.core.functions.FunctionList) List(java.util.List) com.laytonsmith.annotations.typeof(com.laytonsmith.annotations.typeof) ExampleScript(com.laytonsmith.core.functions.ExampleScript) CFunction(com.laytonsmith.core.constructs.CFunction) Optimizable(com.laytonsmith.core.Optimizable)

Example 2 with Optimizable

use of com.laytonsmith.core.Optimizable in project CommandHelper by EngineHub.

the class StaticTest method TestBoilerplate.

/**
 * Tests the boilerplate functions in a Function. While all functions should conform to at least this, it is useful
 * to also use the more strict TestBoilerplate function.
 *
 * @param ff
 * @param name
 * @throws java.lang.Exception
 */
public static void TestBoilerplate(FunctionBase ff, String name) throws Exception {
    if (!(ff instanceof Function)) {
        return;
    }
    Function f = (Function) ff;
    // For the "quality test code coverage" number, set this to true
    boolean runQualityTestsOnly = false;
    MCServer fakeServer = StaticTest.GetFakeServer();
    MCPlayer fakePlayer = StaticTest.GetOnlinePlayer("Player01", fakeServer);
    // make sure that these functions don't throw an exception. Any other results
    // are fine
    f.isRestricted();
    f.runAsync();
    f.preResolveVariables();
    f.thrown();
    // name should match the given value
    if (!f.getName().equals(name)) {
        fail("Expected name of function to be " + name + ", but was given " + f.getName());
    }
    // requirement set.
    if (f.docs().length() <= 0) {
        fail("docs must return a non-empty string");
    }
    TestDocs(f);
    if (f.numArgs().length == 0) {
        fail("numArgs must return an Integer array with more than zero values");
    }
    // If we are interested in tests that are specific to the functions however, we shouldn't run this.
    if (!runQualityTestsOnly && f.getClass().getAnnotation(noboilerplate.class) == null) {
        TestExec(f, fakePlayer, "fake player");
        TestExec(f, null, "null command sender");
        TestExec(f, StaticTest.GetFakeConsoleCommandSender(), "fake console command sender");
    }
    // Same thing for optimize/canOptimize and optimizeDynamic/canOptimizeDynamic
    if (f instanceof Optimizable) {
        Set<Optimizable.OptimizationOption> options = ((Optimizable) f).optimizationOptions();
        if (options.contains(Optimizable.OptimizationOption.CONSTANT_OFFLINE) && options.contains(Optimizable.OptimizationOption.OPTIMIZE_CONSTANT)) {
            fail(f.getName() + " declares both CONSTANT_OFFLINE and OPTIMIZE_CONSTANT, which are mutually exclusive.");
        }
    }
    for (Method method : f.getClass().getDeclaredMethods()) {
        if (method.getName().equals("execs")) {
            if (!f.useSpecialExec()) {
                fail(f.getName() + " declares execs, but returns false for useSpecialExec.");
            }
        }
        if (f instanceof Optimizable) {
            Set<Optimizable.OptimizationOption> options = ((Optimizable) f).optimizationOptions();
            if (method.getName().equals("optimize")) {
                if (!options.contains(Optimizable.OptimizationOption.OPTIMIZE_CONSTANT)) {
                    fail(f.getName() + " declares optimize, but does not declare that it can OPTIMIZE_CONSTANT");
                }
            }
            if (method.getName().equals("optimizeDynamic")) {
                if (!options.contains(Optimizable.OptimizationOption.OPTIMIZE_DYNAMIC)) {
                    fail(f.getName() + " declares optimizeDynamic, but does not declare that it can OPTIMIZE_DYNAMIC");
                }
            }
        }
    }
// now the only function left to test is exec. This cannot be abstracted, unfortunately.
}
Also used : Function(com.laytonsmith.core.functions.Function) MCPlayer(com.laytonsmith.abstraction.MCPlayer) Optimizable(com.laytonsmith.core.Optimizable) MCServer(com.laytonsmith.abstraction.MCServer) Method(java.lang.reflect.Method)

Example 3 with Optimizable

use of com.laytonsmith.core.Optimizable in project CommandHelper by EngineHub.

the class SiteDeploy method generateFunctionDocs.

private void generateFunctionDocs(Function f, DocGen.DocInfo docs) {
    StringBuilder page = new StringBuilder();
    page.append("== ").append(f.getName()).append(" ==\n");
    page.append("<div>").append(docs.desc).append("</div>\n");
    page.append("=== Vital Info ===\n");
    page.append("{| style=\"width: 40%;\" cellspacing=\"1\" cellpadding=\"1\" border=\"1\" class=\"wikitable\"\n");
    page.append("|-\n" + "! scope=\"col\" width=\"20%\" | \n" + "! scope=\"col\" width=\"80%\" | \n" + "|-\n" + "! scope=\"row\" | Name\n" + "| ").append(f.getName()).append("\n" + "|-\n" + "! scope=\"row\" | Returns\n" + "| ").append(docs.ret).append("\n" + "|-\n" + "! scope=\"row\" | Usages\n" + "| ").append(docs.args).append("\n" + "|-\n" + "! scope=\"row\" | Throws\n" + "| ");
    List<String> exceptions = new ArrayList<>();
    for (Class<? extends CREThrowable> c : f.thrown()) {
        String t = c.getAnnotation(typeof.class).value();
        exceptions.add("[[../objects/" + t + "|" + t + "]]");
    }
    page.append(StringUtils.Join(exceptions, "<br>"));
    page.append("\n" + "|-\n" + "! scope=\"row\" | Since\n" + "| ").append(f.since()).append("\n" + "|-\n" + "! scope=\"row\" | Restricted\n");
    page.append("| <div style=\"background-color: ");
    page.append(f.isRestricted() ? "red" : "green");
    page.append("; font-weight: bold; text-align: center;\">").append(f.isRestricted() ? "Yes" : "No").append("</div>\n" + "|-\n" + "! scope=\"row\" | Optimizations\n" + "| ");
    String optimizationMessage = "None";
    if (f instanceof Optimizable) {
        Set<Optimizable.OptimizationOption> options = ((Optimizable) f).optimizationOptions();
        List<String> list = new ArrayList<>();
        for (Optimizable.OptimizationOption option : options) {
            list.add("[[../../Optimizer#" + option.name() + "|" + option.name() + "]]");
        }
        optimizationMessage = StringUtils.Join(list, " <br /> ");
    }
    page.append(optimizationMessage);
    page.append("\n|}");
    if (docs.extendedDesc != null) {
        page.append("<div>").append(docs.extendedDesc).append("</div>");
    }
    String[] usages = docs.originalArgs.split("\\|");
    StringBuilder usageBuilder = new StringBuilder();
    for (String usage : usages) {
        usageBuilder.append("<pre>\n").append(f.getName()).append("(").append(usage.trim()).append(")\n</pre>");
    }
    page.append("\n=== Usages ===\n");
    page.append(usageBuilder.toString());
    StringBuilder exampleBuilder = new StringBuilder();
    try {
        if (f.examples() != null && f.examples().length > 0) {
            int count = 1;
            // If the output was automatically generated, change the color of the pre
            for (ExampleScript es : f.examples()) {
                exampleBuilder.append("====Example ").append(count).append("====\n").append(HTMLUtils.escapeHTML(es.getDescription())).append("\n\n" + "Given the following code:\n");
                exampleBuilder.append(SimpleSyntaxHighlighter.Highlight(es.getScript(), true)).append("\n");
                String style = "";
                exampleBuilder.append("\n\nThe output ");
                if (es.isAutomatic()) {
                    style = " background-color: #BDC7E9;";
                    exampleBuilder.append("would");
                } else {
                    exampleBuilder.append("might");
                }
                exampleBuilder.append(" be:\n<pre class=\"pre\" style=\"border-top: 1px solid blue; border-bottom: 1px solid blue;").append(style).append("\"");
                exampleBuilder.append(">%%NOWIKI|").append(es.getOutput()).append("%%").append("</pre>\n");
                count++;
            }
        } else {
            exampleBuilder.append("Sorry, there are no examples for this function! :(\n");
        }
    } catch (ConfigCompileException | IOException | DataSourceException | URISyntaxException ex) {
        exampleBuilder.append("Error while compiling the examples for ").append(f.getName());
    }
    page.append("\n=== Examples ===\n");
    page.append(exampleBuilder.toString());
    Class<?>[] seeAlso = f.seeAlso();
    String seeAlsoText = "";
    if (seeAlso != null && seeAlso.length > 0) {
        seeAlsoText += "===See Also===\n";
        boolean first = true;
        for (Class<?> c : seeAlso) {
            if (!first) {
                seeAlsoText += ", ";
            }
            first = false;
            if (Function.class.isAssignableFrom(c)) {
                Function f2 = (Function) ReflectionUtils.newInstance(c);
                seeAlsoText += "<code>[[" + f2.getName() + "|" + f2.getName() + "]]</code>";
            } else if (Template.class.isAssignableFrom(c)) {
                Template t = (Template) ReflectionUtils.newInstance(c);
                seeAlsoText += "[[" + t.getName() + "|Learning Trail: " + t.getDisplayName() + "]]";
            } else {
                throw new Error("Unsupported class found in @seealso annotation: " + c.getName());
            }
        }
    }
    page.append(seeAlsoText);
    Class<?> container = f.getClass();
    while (container.getEnclosingClass() != null) {
        container = container.getEnclosingClass();
    }
    String bW = "<p id=\"edit_this_page\">" + EDIT_THIS_PAGE_PREAMBLE + String.format(githubBaseUrl, "java/" + container.getName().replace(".", "/")) + ".java" + EDIT_THIS_PAGE_POSTAMBLE + " (Note this page is automatically generated from the documentation in the source code.)</p>";
    page.append(bW);
    String description = "";
    writePage(f.getName(), page.toString(), "API/functions/" + f.getName(), Arrays.asList(new String[] { f.getName(), f.getName() + " api", f.getName() + " example", f.getName() + " description" }), description);
}
Also used : ArrayList(java.util.ArrayList) URISyntaxException(java.net.URISyntaxException) ConfigCompileException(com.laytonsmith.core.exceptions.ConfigCompileException) Template(com.laytonsmith.tools.docgen.templates.Template) Function(com.laytonsmith.core.functions.Function) com.laytonsmith.annotations.typeof(com.laytonsmith.annotations.typeof) ExampleScript(com.laytonsmith.core.functions.ExampleScript) Optimizable(com.laytonsmith.core.Optimizable) IOException(java.io.IOException) DataSourceException(com.laytonsmith.persistence.DataSourceException)

Aggregations

Optimizable (com.laytonsmith.core.Optimizable)3 Function (com.laytonsmith.core.functions.Function)3 com.laytonsmith.annotations.typeof (com.laytonsmith.annotations.typeof)2 ExampleScript (com.laytonsmith.core.functions.ExampleScript)2 Template (com.laytonsmith.tools.docgen.templates.Template)2 ArrayList (java.util.ArrayList)2 MCPlayer (com.laytonsmith.abstraction.MCPlayer)1 MCServer (com.laytonsmith.abstraction.MCServer)1 CFunction (com.laytonsmith.core.constructs.CFunction)1 ConfigCompileException (com.laytonsmith.core.exceptions.ConfigCompileException)1 FunctionBase (com.laytonsmith.core.functions.FunctionBase)1 FunctionList (com.laytonsmith.core.functions.FunctionList)1 DataSourceException (com.laytonsmith.persistence.DataSourceException)1 IOException (java.io.IOException)1 Method (java.lang.reflect.Method)1 URISyntaxException (java.net.URISyntaxException)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Matcher (java.util.regex.Matcher)1