예제 #1
0
  public Construct eval(ParseTree c, final Environment env) throws CancelCommandException {
    final Construct m = c.getData();
    CurrentEnv = env;
    // TODO: Reevaluate if this line is needed. The script doesn't know the label inherently, the
    // environment does, and setting it this way taints the environment.
    CurrentEnv.getEnv(GlobalEnv.class).SetLabel(this.label);
    if (m.getCType() == ConstructType.FUNCTION) {
      env.getEnv(GlobalEnv.class).SetScript(this);
      if (m.val().matches("^_[^_].*")) {
        // Not really a function, so we can't put it in Function.
        Procedure p = getProc(m.val());
        if (p == null) {
          throw new ConfigRuntimeException(
              "Unknown procedure \"" + m.val() + "\"",
              ExceptionType.InvalidProcedureException,
              m.getTarget());
        }
        Environment newEnv = env;
        try {
          newEnv = env.clone();
        } catch (Exception e) {
        }
        ProfilePoint pp =
            env.getEnv(GlobalEnv.class).GetProfiler().start(m.val() + " execution", LogLevel.INFO);
        Construct ret = p.cexecute(c.getChildren(), newEnv, m.getTarget());
        pp.stop();
        return ret;
      }
      final Function f;
      try {
        f = (Function) FunctionList.getFunction(m);
      } catch (ConfigCompileException e) {
        // Turn it into a config runtime exception. This shouldn't ever happen though.
        throw new ConfigRuntimeException("Unable to find function " + m.val(), m.getTarget());
      }
      // We have special handling for loop and other control flow functions
      if (f instanceof assign) {
        if (c.getChildAt(0).getData() instanceof CFunction) {
          CFunction test = (CFunction) c.getChildAt(0).getData();
          if (test.val().equals("array_get")) {
            env.getEnv(GlobalEnv.class).SetFlag("array_get_alt_mode", true);
            Construct arrayAndIndex = eval(c.getChildAt(0), env);
            env.getEnv(GlobalEnv.class).ClearFlag("array_get_alt_mode");
            return ((assign) f)
                .array_assign(m.getTarget(), env, arrayAndIndex, eval(c.getChildAt(1), env));
          }
        }
      }

      if (f.useSpecialExec()) {
        ProfilePoint p = null;
        if (f.shouldProfile()
            && env.getEnv(GlobalEnv.class).GetProfiler() != null
            && env.getEnv(GlobalEnv.class).GetProfiler().isLoggable(f.profileAt())) {
          p =
              env.getEnv(GlobalEnv.class)
                  .GetProfiler()
                  .start(f.profileMessageS(c.getChildren()), f.profileAt());
        }
        Construct ret =
            f.execs(m.getTarget(), env, this, c.getChildren().toArray(new ParseTree[] {}));
        if (p != null) {
          p.stop();
        }
        return ret;
      }

      ArrayList<Construct> args = new ArrayList<Construct>();
      for (ParseTree c2 : c.getChildren()) {
        args.add(eval(c2, env));
      }
      if (f.isRestricted()) {
        boolean perm = Static.hasCHPermission(f.getName(), env);
        if (!perm) {
          throw new ConfigRuntimeException(
              "You do not have permission to use the " + f.getName() + " function.",
              ExceptionType.InsufficientPermissionException,
              m.getTarget());
        }
      }
      Object[] a = args.toArray();
      Construct[] ca = new Construct[a.length];
      for (int i = 0; i < a.length; i++) {
        ca[i] = (Construct) a[i];
        // CArray, CBoolean, CDouble, CInt, CNull, CString, CVoid, CEntry, CLabel (only to sconcat).
        if (!(ca[i] instanceof CArray
                || ca[i] instanceof CBoolean
                || ca[i] instanceof CDouble
                || ca[i] instanceof CInt
                || ca[i] instanceof CNull
                || ca[i] instanceof CString
                || ca[i] instanceof CVoid
                || ca[i] instanceof IVariable
                || ca[i] instanceof CEntry
                || ca[i] instanceof CLabel)
            && (!f.getName().equals("__autoconcat__") && (ca[i] instanceof CLabel))) {
          throw new ConfigRuntimeException(
              "Invalid Construct ("
                  + ca[i].getClass()
                  + ") being passed as an argument to a function ("
                  + f.getName()
                  + ")",
              null,
              m.getTarget());
        }
        if (env.getEnv(GlobalEnv.class).GetFlag("array_get_alt_mode") == Boolean.TRUE && i == 0) {
          continue;
        }
        while (f.preResolveVariables() && ca[i] instanceof IVariable) {
          IVariable cur = (IVariable) ca[i];
          ca[i] =
              env.getEnv(GlobalEnv.class).GetVarList().get(cur.getName(), cur.getTarget()).ival();
        }
      }

      {
        // It takes a moment to generate the toString of some things, so lets not do it
        // if we actually aren't going to profile
        ProfilePoint p = null;
        if (f.shouldProfile()
            && env.getEnv(GlobalEnv.class).GetProfiler() != null
            && env.getEnv(GlobalEnv.class).GetProfiler().isLoggable(f.profileAt())) {
          p = env.getEnv(GlobalEnv.class).GetProfiler().start(f.profileMessage(ca), f.profileAt());
        }
        Construct ret = f.exec(m.getTarget(), env, ca);
        if (p != null) {
          p.stop();
        }
        return ret;
      }

    } else if (m.getCType() == ConstructType.VARIABLE) {
      return new CString(m.val(), m.getTarget());
    } else {
      return m;
    }
  }
예제 #2
0
  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++) {
          ExceptionType t = (ExceptionType) thrownList.get(i);
          if (i != 0) {
            thrown.append("<br />\n");
          }
          thrown
              .append("[[CommandHelper/Exceptions#")
              .append(t.toString())
              .append("|")
              .append(t.toString())
              .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())).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<? extends Documentation> c : seeAlso) {
          if (Function.class.isAssignableFrom(c)) {
            Function f2 = (Function) c.newInstance();
            if (!first) {
              seeAlsoText += ", ";
            }
            first = false;
            seeAlsoText +=
                "[[CommandHelper/"
                    + (staged ? "Staged/" : "")
                    + "API/"
                    + f2.getName()
                    + "|"
                    + f2.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");
    }
  }