001// Copyright 2011 The Apache Software Foundation 002// 003// Licensed under the Apache License, Version 2.0 (the "License"); 004// you may not use this file except in compliance with the License. 005// You may obtain a copy of the License at 006// 007// http://www.apache.org/licenses/LICENSE-2.0 008// 009// Unless required by applicable law or agreed to in writing, software 010// distributed under the License is distributed on an "AS IS" BASIS, 011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012// See the License for the specific language governing permissions and 013// limitations under the License. 014 015package org.apache.tapestry5.internal.plastic; 016 017import java.util.HashMap; 018import java.util.Map; 019 020import org.apache.tapestry5.internal.plastic.asm.Opcodes; 021 022/** 023 * Collects together information needed to write code that involves primitive types, including 024 * moving between wrapper types and primitive values, or extracting a primitive value from 025 * the {@link StaticContext}. 026 */ 027@SuppressWarnings("rawtypes") 028public enum PrimitiveType implements Opcodes 029{ 030 VOID("void", "V", void.class, Void.class, null, null, ILOAD, ISTORE, RETURN), 031 032 BOOLEAN("boolean", "Z", boolean.class, Boolean.class, "booleanValue", "getBoolean", ILOAD, ISTORE, IRETURN), 033 034 CHAR("char", "C", char.class, Character.class, "charValue", "getChar", ILOAD, ISTORE, IRETURN), 035 036 BYTE("byte", "B", byte.class, Byte.class, "byteValue", "getByte", ILOAD, ISTORE, IRETURN), 037 038 SHORT("short", "S", short.class, Short.class, "shortValue", "getShort", ILOAD, ISTORE, IRETURN), 039 040 INT("int", "I", int.class, Integer.class, "intValue", "getInt", ILOAD, ISTORE, IRETURN), 041 042 FLOAT("float", "F", float.class, Float.class, "floatValue", "getFloat", FLOAD, FSTORE, FRETURN), 043 044 LONG("long", "J", long.class, Long.class, "longValue", "getLong", LLOAD, LSTORE, LRETURN), 045 046 DOUBLE("double", "D", double.class, Double.class, "doubleValue", "getDouble", DLOAD, DSTORE, DRETURN); 047 048 /** 049 * @param name 050 * the Java source name for the type 051 * @param descriptor 052 * Java descriptor for the type ('Z', 'I', etc.) 053 * @param primitiveType 054 * TODO 055 * @param wrapperType 056 * wrapper type, e.g., java.lang.Integer 057 * @param toValueMethodName 058 * name of method of wrapper class to extract primitive value 059 * @param getFromStaticContextMethodName 060 * name of method of {@link StaticContext} used to extract primitive context value 061 * @param loadOpcode 062 * Correct opcode for loading an argument or local variable onto the stack (ILOAD, LLOAD, FLOAD or 063 * DLOAD) 064 * @param storeOpcode 065 * matching opcode for storing a value to a local variable (ISTORE, LSTORE, FSTORE or DSTORE) 066 * @param returnOpcode 067 * Correct opcode for returning the top value on the stack (IRETURN, LRETURN, FRETURN 068 * or DRETURN) 069 */ 070 private PrimitiveType(String name, String descriptor, Class primitiveType, Class wrapperType, 071 String toValueMethodName, String getFromStaticContextMethodName, int loadOpcode, int storeOpcode, 072 int returnOpcode) 073 { 074 this.name = name; 075 this.descriptor = descriptor; 076 this.primitiveType = primitiveType; 077 this.wrapperType = wrapperType; 078 this.wrapperInternalName = wrapperType == null ? null : PlasticInternalUtils.toInternalName(wrapperType 079 .getName()); 080 this.toValueMethodName = toValueMethodName; 081 this.getFromStaticContextMethodName = getFromStaticContextMethodName; 082 this.loadOpcode = loadOpcode; 083 this.storeOpcode = storeOpcode; 084 this.returnOpcode = returnOpcode; 085 086 this.valueOfMethodDescriptor = String.format("(%s)L%s;", descriptor, wrapperInternalName); 087 this.toValueMethodDescriptor = "()" + descriptor; 088 this.getFromStaticContextMethodDescriptor = "(I)" + descriptor; 089 } 090 091 public final String name, descriptor, wrapperInternalName, valueOfMethodDescriptor, toValueMethodName, 092 getFromStaticContextMethodName, toValueMethodDescriptor, getFromStaticContextMethodDescriptor; 093 094 public final Class primitiveType, wrapperType; 095 096 public final int loadOpcode, storeOpcode, returnOpcode; 097 098 private static final Map<String, PrimitiveType> BY_NAME = new HashMap<String, PrimitiveType>(); 099 private static final Map<String, PrimitiveType> BY_DESC = new HashMap<String, PrimitiveType>(); 100 private static final Map<Class, PrimitiveType> BY_PRIMITIVE_TYPE = new HashMap<Class, PrimitiveType>(); 101 102 static 103 { 104 for (PrimitiveType type : values()) 105 { 106 BY_NAME.put(type.name, type); 107 BY_DESC.put(type.descriptor, type); 108 BY_PRIMITIVE_TYPE.put(type.primitiveType, type); 109 } 110 } 111 112 public boolean isWide() 113 { 114 return this == LONG || this == DOUBLE; 115 } 116 117 /** 118 * Returns the primitive type matching the given type name or null for a non-primitive type (an array type, 119 * or an class name). 120 * 121 * @param name 122 * possible primitive name 123 * @return the type or null 124 */ 125 public static PrimitiveType getByName(String name) 126 { 127 return BY_NAME.get(name); 128 } 129 130 public static PrimitiveType getByPrimitiveType(Class primitiveType) 131 { 132 return BY_PRIMITIVE_TYPE.get(primitiveType); 133 } 134}