Package ch.njol.skript.expressions

Source Code of ch.njol.skript.expressions.ExprParse

/*
*   This file is part of Skript.
*
*  Skript is free software: you can redistribute it and/or modify
*  it under the terms of the GNU General Public License as published by
*  the Free Software Foundation, either version 3 of the License, or
*  (at your option) any later version.
*
*  Skript is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU General Public License for more details.
*
*  You should have received a copy of the GNU General Public License
*  along with Skript.  If not, see <http://www.gnu.org/licenses/>.
*
*
* Copyright 2011, 2012 Peter Güttinger
*
*/

package ch.njol.skript.expressions;

import java.lang.reflect.Array;

import org.bukkit.event.Event;
import org.eclipse.jdt.annotation.Nullable;

import ch.njol.skript.Skript;
import ch.njol.skript.classes.ClassInfo;
import ch.njol.skript.classes.Parser;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Examples;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.Literal;
import ch.njol.skript.lang.ParseContext;
import ch.njol.skript.lang.SkriptParser;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.VariableString;
import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.skript.localization.Language;
import ch.njol.skript.log.ErrorQuality;
import ch.njol.skript.log.LogEntry;
import ch.njol.skript.log.ParseLogHandler;
import ch.njol.skript.log.SkriptLogger;
import ch.njol.util.Kleenean;
import ch.njol.util.NonNullPair;

/**
* @author Peter Güttinger
*/
@Name("Parse")
@Description({"Parses text as a given type, or as a given pattern.",
    "This expression can be used in two different ways: One which parses the entire text as a single instance of a type, e.g. as a number, " +
        "and one that parses the text according to a pattern.",
    "If the given text could not be parsed, this expression will return nothing and the <a href='#ExprParseError'>parse error</a> will be set if some information is available.",
    "Some notes about parsing with a pattern:",
    "- The pattern must be a <a href='../patterns/'>Skript pattern</a>, " +
        "e.g. percent signs are used to define where to parse which types, e.g. put a %number% or %items% in the pattern if you expect a number or some items there.",
    "- You <i>have to</i> save the expression's value in a list variable, e.g. <code>set {parsed::*} to message parsed as \"...\"</code>.",
    "- The list variable will contain the parsed values from all %types% in the pattern in order. If a type was plural, e.g. %items%, the variable's value at the respective index will be a list variable," +
        " e.g. the values will be stored in {parsed::1::*}, not {parsed::1}."})
@Examples({"set {var} to line 1 parsed as number",
    "on chat:",
    "  set {var::*} to message parsed as \"buying %items% for %money%\"",
    "  if parse error is set:",
    "    message \"%parse error%\"",
    "  else if {var::*} is set:",
    "    cancel event",
    "    remove {var::2} from the player's balance",
    "    give {var::1::*} to the player"})
@Since("2.0")
public class ExprParse extends SimpleExpression<Object> {
  static {
    Skript.registerExpression(ExprParse.class, Object.class, ExpressionType.COMBINED,
        "%string% parsed as (%-*classinfo%|\"<.*>\")");
  }
 
  @Nullable
  static String lastError = null;
 
  @SuppressWarnings("null")
  private Expression<String> text;
 
  @Nullable
  private String pattern;
  @Nullable
  private boolean[] plurals;
 
  @Nullable
  private ClassInfo<?> c;
 
  @SuppressWarnings({"unchecked", "null"})
  @Override
  public boolean init(final Expression<?>[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) {
    text = (Expression<String>) exprs[0];
    if (exprs[1] == null) {
      String pattern = "" + parseResult.regexes.get(0).group();
      if (!VariableString.isQuotedCorrectly(pattern, false)) {
        Skript.error("Invalid amount and/or placement of double quotes in '" + pattern + "'", ErrorQuality.SEMANTIC_ERROR);
        return false;
      }
      // escape '¦'
      final StringBuilder b = new StringBuilder(pattern.length());
      for (int i = 0; i < pattern.length(); i++) {
        final char c = pattern.charAt(i);
        if (c == '\\') {
          b.append(c);
          b.append(pattern.charAt(i + 1));
          i++;
        } else if (c == '¦') {
          b.append("\\¦");
        } else {
          b.append(c);
        }
      }
      pattern = "" + b.toString();
      final NonNullPair<String, boolean[]> p = SkriptParser.validatePattern(pattern);
      if (p == null)
        return false;
      this.pattern = p.getFirst();
      plurals = p.getSecond();
    } else {
      c = ((Literal<ClassInfo<?>>) exprs[1]).getSingle();
      final Parser<?> p = c.getParser();
      if (p == null || !p.canParse(ParseContext.COMMAND)) { // TODO special parse context?
        Skript.error("Text cannot be parsed as " + c.getName().withIndefiniteArticle(), ErrorQuality.SEMANTIC_ERROR);
        return false;
      }
    }
    return true;
  }
 
  @SuppressWarnings("null")
  @Override
  @Nullable
  protected Object[] get(final Event e) {
    final String t = text.getSingle(e);
    if (t == null)
      return null;
    final ParseLogHandler h = SkriptLogger.startParseLogHandler();
    try {
      if (c != null) {
        final Parser<?> p = c.getParser();
        assert p != null; // checked in init()
        final Object o = p.parse(t, ParseContext.COMMAND);
        if (o != null) {
          final Object[] one = (Object[]) Array.newInstance(c.getC(), 1);
          one[0] = o;
          return one;
        }
      } else {
        assert pattern != null && plurals != null;
        final ParseResult r = SkriptParser.parse(t, pattern);
        if (r != null) {
          assert plurals.length == r.exprs.length;
          final Object[] os = new Object[r.exprs.length];
          for (int i = 0; i < os.length; i++)
            os[i] = plurals[i] ? r.exprs[i].getArray(null) : r.exprs[i].getSingle(null);
          return os;
        }
      }
      final LogEntry err = h.getError();
      lastError = err != null ? err.getMessage() : null;
      return null;
    } finally {
      h.clear();
      h.printLog();
    }
  }
 
  @Override
  public boolean isSingle() {
    return pattern == null;
  }
 
  @Override
  public Class<? extends Object> getReturnType() {
    return c != null ? c.getC() : Object[].class;
  }
 
  @Override
  public String toString(final @Nullable Event e, final boolean debug) {
    return text.toString(e, debug) + " parsed as " + (c != null ? c.toString(Language.F_INDEFINITE_ARTICLE) : pattern);
  }
 
}
TOP

Related Classes of ch.njol.skript.expressions.ExprParse

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.