com.codename1.tools.translator.ByteCodeField.java Source code

Java tutorial

Introduction

Here is the source code for com.codename1.tools.translator.ByteCodeField.java

Source

/*
 * Copyright (c) 2012, Codename One and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Codename One designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *  
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 * 
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 * 
 * Please contact Codename One through http://www.codenameone.com/ if you 
 * need additional information or have any questions.
 */

package com.codename1.tools.translator;

import java.util.ArrayList;
import java.util.List;
import org.objectweb.asm.Opcodes;

/**
 *
 * @author Shai Almog
 */
public class ByteCodeField {
    private final String clsName;
    private boolean staticField;
    private String fieldName;

    private List<String> dependentClasses = new ArrayList<String>();
    //private List<String> exportedClasses = new ArrayList<String>();

    private int arrayDimensions;
    private String type;
    private Class primitiveType;
    private boolean finalField;
    private Object value;
    private boolean privateField;

    public ByteCodeField(String clsName, int access, String name, String desc, String signature, Object value) {
        this.clsName = clsName;
        this.value = value;
        privateField = (access & Opcodes.ACC_PRIVATE) == Opcodes.ACC_PRIVATE;
        if (value != null && value instanceof String) {
            Parser.addToConstantPool((String) value);
        }
        staticField = (access & Opcodes.ACC_STATIC) == Opcodes.ACC_STATIC;
        finalField = (access & Opcodes.ACC_FINAL) == Opcodes.ACC_FINAL;
        fieldName = name.replace('$', '_');

        arrayDimensions = 0;
        while (desc.startsWith("[")) {
            desc = desc.substring(1);
            arrayDimensions++;
        }
        char currentType = desc.charAt(0);
        switch (currentType) {
        case 'L':
            // Object skip until ;
            int idx = desc.indexOf(';');
            String objectType = desc.substring(1, idx);
            objectType = objectType.replace('/', '_').replace('$', '_');
            if (!dependentClasses.contains(objectType)) {
                dependentClasses.add(objectType);
            }
            //if (!privateField && !exportedClasses.contains(objectType)) {
            //    exportedClasses.add(objectType);
            //}

            type = objectType;
            break;
        case 'I':
            primitiveType = Integer.TYPE;
            break;
        case 'J':
            primitiveType = Long.TYPE;
            break;
        case 'B':
            primitiveType = Byte.TYPE;
            break;
        case 'S':
            primitiveType = Short.TYPE;
            break;
        case 'F':
            primitiveType = Float.TYPE;
            break;
        case 'D':
            primitiveType = Double.TYPE;
            break;
        case 'Z':
            primitiveType = Boolean.TYPE;
            break;
        case 'C':
            primitiveType = Character.TYPE;
            break;
        }
    }

    public String getFieldName() {
        return fieldName;
    }

    public String getCDefinition() {
        if (type != null || arrayDimensions > 0) {
            return "JAVA_OBJECT";
        }
        return Util.getCType(primitiveType);
    }

    public List<String> getDependentClasses() {
        return dependentClasses;
    }

    //public List<String> getExportedClasses() {
    //    return exportedClasses;
    //}
    /**
     * @return the staticField
     */
    public boolean isStaticField() {
        return staticField;
    }

    @Override
    public boolean equals(Object o) {
        return fieldName.equals(((ByteCodeField) o).fieldName);
    }

    @Override
    public int hashCode() {
        return fieldName.hashCode();
    }

    /**
     * @return the clsName
     */
    public String getClsName() {
        return clsName;
    }

    public boolean isObjectType() {
        return arrayDimensions > 0 || primitiveType == null;
    }

    public boolean isFinal() {
        return finalField;
    }

    public boolean shouldRemoveFromHeapCollection() {
        if (finalField && isObjectType()) {
            // 2d arrays can be modified in runtime resulting in broken arrays
            if (arrayDimensions < 2) {
                // arrays of non-primitive types are mutable despite being marked as final
                if (type != null && arrayDimensions > 0) {
                    return false;
                }
                if (type == null
                        || type.startsWith("java_lang_") && !type.endsWith("Builder") && !type.endsWith("Buffer")) {
                    return true;
                }
            }
        }
        return false;
    }

    public Object getValue() {
        return value;
    }

    public String getType() {
        return type;
    }
}