Package booton.translator

Source Code of booton.translator.ScriptWriter

/*
* Copyright (C) 2013 Nameless Production Committee
*
* Licensed under the MIT License (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*          http://opensource.org/licenses/mit-license.php
*/
package booton.translator;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import jdk.internal.org.objectweb.asm.Type;
import kiss.I;
import booton.BootonConfiguration;

/**
* @version 2013/11/26 11:29:00
*/
class ScriptWriter {

    /** The optimization flag. */
    private final BootonConfiguration config = I.make(BootonConfiguration.class);

    /** The actual buffer. */
    private final StringBuilder buffer = new StringBuilder();

    private int mark = 0;

    /** The current depth of indentation for debug. */
    private int depth = 0;

    /**
     * <p>
     * Append debug infomation.
     * </p>
     *
     * @param owner
     * @param methodName
     * @param description
     */
    public void debug(Class owner, String methodName, String description) {
        if (!config.compression) {
            buffer.append("// ");
            buffer.append(owner.getName()).append("#").append(methodName).append("(");

            Type type = Type.getMethodType(description);
            Type[] args = type.getArgumentTypes();

            for (int i = 0; i < args.length; i++) {
                buffer.append(args[i].getClassName());

                if (i < args.length - 1) {
                    buffer.append(", ");
                }
            }
            buffer.append(")");
            line();
        }
    }

    /**
     * <p>
     * Write comment.
     * </p>
     *
     * @param comment
     */
    public ScriptWriter comment(Object comment) {
        if (!config.compression) {
            buffer.append("// ");
            write(comment);
            line();
        }

        return this;
    }

    /**
     * <p>
     * Formt line for debug.
     * </p>
     *
     * @return A chainable API.
     */
    public ScriptWriter line() {
        if (!config.compression) {
            // write line separator
            buffer.append("\r\n");

            // write indent
            for (int i = 0; i < depth; i++) {
                buffer.append('\t');
            }
        }
        return this;
    }

    /**
     * <p>
     * Format code for degug.
     * </p>
     *
     * @return A chainable API.
     */
    private ScriptWriter startIndent() {
        depth++;
        return line();
    }

    /**
     * <p>
     * Format code for degug.
     * </p>
     *
     * @return A chainable API.
     */
    private ScriptWriter endIndent() {
        depth--;
        return line();
    }

    /**
     * Helper method to write script source.
     *
     * @param fragments
     * @return
     */
    public ScriptWriter append(Object... fragments) {
        for (Object fragment : fragments) {
            write(fragment);
        }

        // API definition
        return this;
    }

    /**
     * Helper method to write script source.
     *
     * @param position
     * @param fragment
     * @return
     */
    public ScriptWriter insertAt(int position, Object fragment) {
        buffer.insert(position, fragment);

        // API definition
        return this;
    }

    /**
     * <p>
     * Helper method to write script code with white space.
     * </p>
     */
    public ScriptWriter write(Object... fragments) {
        for (int i = 0; i < fragments.length; i++) {
            write(fragments[i], false);

            if (!config.compression && i + 1 != fragments.length) {
                write(" ");
            }
        }
        // API definition
        return this;
    }

    /**
     * Helper method to write String literal.
     *
     * @param fragments
     * @return
     */
    public ScriptWriter string(Object literal) {
        return append('"', literal, '"');
    }

    /**
     * <p>
     * Helper method to write separator ",".
     * </p>
     */
    public ScriptWriter separator() {
        return append(",").line();
    }

    /**
     * <p>
     * Optimize source code.
     * </p>
     * <ol>
     * <li>Remove tail whitespaces.</li>
     * <li>Remove tail separator comma.</li>
     * <li>Remove tail "return;" expression.</li>
     * </ol>
     */
    public void optimize() {
        remove(",");
        remove(";");
        remove(" ");
        remove("return");
    }

    /**
     * <p>
     * Remove tailing characters if it is matched.
     * </p>
     *
     * @param c A character to remove.
     * @return A last position.
     */
    private int remove(String chracters) {
        int last = removeWhitespaces();
        int length = chracters.length() - 1;

        if (last < length) {
            return last;
        }

        if (buffer.substring(last - length).equals(chracters)) {
            buffer.delete(last - length, last + 1);
            last -= length;
        }
        return last;
    }

    /**
     * <p>
     * Remove tailing whitespaces.
     * </p>
     *
     * @return A last position.
     */
    private int removeWhitespaces() {
        int last = buffer.length() - 1;

        if (last < 0) {
            return 0;
        }

        while (Character.isWhitespace(buffer.charAt(last))) {
            buffer.deleteCharAt(last--);
        }
        return last;
    }

    /**
     * <p>
     * Remove tailing whitespaces and separator.
     * </p>
     *
     * @return A last position.
     */
    private int removeSeparator() {
        int last = removeWhitespaces();

        if (buffer.charAt(last) == ',') {
            buffer.deleteCharAt(last);
            last = removeWhitespaces();
        }
        return last;
    }

    /**
     * Helper method to write script source.
     *
     * @param fragment
     * @return
     */
    private ScriptWriter write(Object fragment) {
        return write(fragment, true);
    }

    /**
     * Helper method to write script source.
     *
     * @param fragment
     * @return
     */
    private ScriptWriter write(Object fragment, boolean line) {
        if (fragment instanceof Map) {
            write("{");
            Iterator<Entry> iterator = ((Map) fragment).entrySet().iterator();

            if (iterator.hasNext()) {
                Entry entry = iterator.next();
                write(entry.getKey(), ":", entry.getValue());

                while (iterator.hasNext()) {
                    separator();

                    entry = iterator.next();
                    write(entry.getKey(), ":", entry.getValue());
                }
            }
            write("}");
        } else if (fragment instanceof List) {
            write("[");

            Iterator<Entry> iterator = ((List) fragment).iterator();

            if (iterator.hasNext()) {
                write(iterator.next());

                while (iterator.hasNext()) {
                    write(",", iterator.next());
                }
            }
            write("]");
        } else {

            String value = fragment.toString();
            if (value == null) {
                System.out.println(buffer);
                System.out.println(fragment);
            }
            int length = value.length();

            if (length != 0) {
                switch (value.charAt(0)) {
                case '}':
                case ']':
                    do {
                        remove(",");
                    } while (buffer.charAt(buffer.length() - 1) == ',');
                    break;
                }
            }

            // brace makes indentation
            if (length != 0 && value.charAt(0) == '}') {
                int last = buffer.length() - 1;
                int lastNonSpace = last;

                while (Character.isWhitespace(buffer.charAt(lastNonSpace))) {
                    lastNonSpace--;
                }

                if (last == lastNonSpace) {
                    endIndent();
                } else if (buffer.charAt(lastNonSpace) == '{') {
                    buffer.delete(lastNonSpace + 1, last + 1);
                    depth--;
                } else {
                    buffer.deleteCharAt(last);
                    depth--;
                }
            }

            // write actual code
            buffer.append(value);

            // brace makes indentation
            if (length != 0) {
                char last = value.charAt(length - 1);

                switch (last) {
                case '{':
                    startIndent();
                    break;

                case ';':
                    if (line) line();
                    break;
                }
            }
        }

        // API definition
        return this;
    }

    /**
     * Remove semicolon at the end.
     */
    void literalize() {
        int index = buffer.length() - 1;

        if (index != -1 && buffer.charAt(index) == ';') {
            buffer.deleteCharAt(index);
        }
    }

    /**
     * Clear data.
     */
    ScriptWriter clear() {
        buffer.delete(0, buffer.length());

        // API definition
        return this;
    }

    /**
     * <p>
     * Mark the current position.
     * </p>
     *
     * @return
     */
    ScriptWriter mark() {
        mark = buffer.length();

        // API definition
        return this;
    }

    String toFragment() {
        return buffer.substring(mark);
    }

    /**
     * <p>
     * Calcurate size of this code.
     * </p>
     *
     * @return
     */
    public int length() {
        return buffer.length();
    }

    /**
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return buffer.toString();
    }
}
TOP

Related Classes of booton.translator.ScriptWriter

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.