Package jsx.ui

Source Code of jsx.ui.LocalId$Coder

/*
* Copyright (C) 2014 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 jsx.ui;

import static jdk.internal.org.objectweb.asm.Opcodes.*;

import java.util.HashMap;
import java.util.Map;

import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.ClassVisitor;
import jdk.internal.org.objectweb.asm.Label;
import jdk.internal.org.objectweb.asm.MethodVisitor;
import jdk.internal.org.objectweb.asm.Type;
import kiss.I;

import sun.reflect.ConstantPool;

import booton.css.StyleDeclaration;
import booton.translator.Translator;

/**
* @version 2014/09/13 9:44:24
*/
class LocalId {

    /** The class name. */
    private static final String CLASS = VirtualStructure.class.getName() + "$";

    /**
     * <p>
     * Generate local id.
     * </p>
     *
     * @return A generated local id.
     */
    static final int generate() {
        Error error = new Error();
        StackTraceElement[] elements = error.getStackTrace();

        for (int i = 0; i < elements.length; i++) {
            StackTraceElement e = elements[i];
            StackTraceElement n = elements[i + 1];

            if (e.getClassName().startsWith(CLASS) && !n.getClassName().startsWith(CLASS)) {
                return elements[i + 1].getLineNumber();
            }
        }

        // If this exception will be thrown, it is bug of this program. So we must rethrow the
        // wrapped error in here.
        throw new Error();
    }

    /**
     * <p>
     * Find line number of the current context.
     * </p>
     */
    static int findContextLineNumber() {
        Error error = new Error();
        StackTraceElement[] elements = error.getStackTrace();

        for (int i = 0; i < elements.length; i++) {
            StackTraceElement e = elements[i];
            StackTraceElement n = elements[i + 1];

            if (e.getClassName().startsWith(CLASS) && !n.getClassName().startsWith(CLASS)) {
                LineInfo info = LineInfo.of(n.getClassName());

                return info.lines.getOrDefault(n.getLineNumber(), 0);
            }
        }

        // If this exception will be thrown, it is bug of this program. So we must rethrow the
        // wrapped error in here.
        throw new Error();
    }

    /**
     * @version 2014/10/08 12:07:42
     */
    private static class LineInfo {

        /** The cache of {@link LineInfo}. */
        private static final Map<String, LineInfo> infos = new HashMap();

        /** The line mapping. */
        private final Map<Integer, Integer> lines = new HashMap();

        /**
         * @param className
         */
        private LineInfo(String className) {
            try {
                ClassLineSearch search = new ClassLineSearch(lines);
                ClassReader reader = new ClassReader(className);
                reader.accept(search, ClassReader.SKIP_FRAMES);
            } catch (Exception e) {
                throw I.quiet(e);
            }
        }

        /**
         * <p>
         * Find {@link LineInfo} by class name.
         * </p>
         *
         * @param className
         * @return
         */
        private static LineInfo of(String className) {
            LineInfo info = infos.get(className);

            if (info == null) {
                info = new LineInfo(className);
                infos.put(className, info);
            }
            return info;
        }
    }

    /**
     * @version 2014/10/08 11:28:33
     */
    private static class ClassLineSearch extends ClassVisitor {

        /** The line mapping. */
        private final Map<Integer, Integer> lines;

        /**
         *
         */
        private ClassLineSearch(Map<Integer, Integer> lines) {
            super(ASM5);

            this.lines = lines;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
            return new MethodLineSearch(lines);
        }
    }

    /**
     * @version 2014/10/08 11:31:02
     */
    private static class MethodLineSearch extends MethodVisitor {

        /** Reusable type. */
        private static final Type VirtualStructure = Type.getType(VirtualStructure.class);

        /** The line mapping. */
        private final Map<Integer, Integer> lines;

        /** The latest line number. */
        private int latestLineNumber;

        /** The latest {@link VirtualStructure} field access line number. */
        private int latestFieldAccessLineNumber;

        /**
         *
         */
        private MethodLineSearch(Map<Integer, Integer> lines) {
            super(ASM5);

            this.lines = lines;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void visitFieldInsn(int opcode, String owner, String name, String desc) {
            if (opcode == GETFIELD && owner.equals(VirtualStructure.getInternalName())) {
                this.latestFieldAccessLineNumber = latestLineNumber;
            }
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void visitLineNumber(int line, Label start) {
            this.latestLineNumber = line;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean interfaceOwner) {
            if (owner.startsWith(VirtualStructure.getInternalName().concat("$"))) {
                lines.put(latestLineNumber, latestFieldAccessLineNumber);
            }
        }
    }

    /**
     * @version 2014/09/13 9:36:39
     */
    @SuppressWarnings("unused")
    private static class Coder extends Translator<LocalId> {

        /**
         * <p>
         * Generate local id.
         * </p>
         *
         * @return A generated local id.
         */
        public String generate() {
            return "0";
        }

        /**
         * <p>
         * Find line number of the current context.
         * </p>
         */
        public String findContextLineNumber() {
            return "0";
        }
    }
}
TOP

Related Classes of jsx.ui.LocalId$Coder

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.