001    /*
002     * ClassHelper.java created on 25.10.2005
003     *
004     */
005    package org.codehaus.groovy.ast;
006    
007    import groovy.lang.Closure;
008    import groovy.lang.GString;
009    import groovy.lang.Range;
010    import groovy.lang.Reference;
011    import groovy.lang.Script;
012    
013    import java.math.BigDecimal;
014    import java.math.BigInteger;
015    import java.util.List;
016    import java.util.Map;
017    import java.util.regex.Pattern;
018    
019    import org.objectweb.asm.Opcodes;
020    
021    /**
022     * @author Jochen Theodorou
023     */
024    public class ClassHelper {
025        
026    
027        private static String[] names = new String[] {
028            boolean.class.getName(),    char.class.getName(), 
029            byte.class.getName(),       short.class.getName(),
030            int.class.getName(),        long.class.getName(),
031            double.class.getName(),     float.class.getName(),
032            Object.class.getName(),     Void.TYPE.getName(),
033            Closure.class.getName(),    GString.class.getName(),
034            List.class.getName(),       Map.class.getName(),
035            Range.class.getName(),      Pattern.class.getName(),
036            Script.class.getName(),     String.class.getName(),
037            Boolean.class.getName(),    Character.class.getName(),
038            Byte.class.getName(),       Short.class.getName(),
039            Integer.class.getName(),    Long.class.getName(),
040            Double.class.getName(),     Float.class.getName(),
041            BigDecimal.class.getName(), BigInteger.class.getName(),
042            Void.class.getName()
043        };
044        
045        private static Class[] classes = new Class[] {
046            Object.class, Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE,
047            Integer.TYPE, Long.TYPE, Double.TYPE, Float.TYPE, Void.TYPE,
048            Closure.class, GString.class, List.class, Map.class, Range.class,
049            Pattern.class, Script.class, String.class,  Boolean.class, 
050            Character.class, Byte.class, Short.class, Integer.class, Long.class,
051            Double.class, Float.class, BigDecimal.class, BigInteger.class, Void.class
052        };
053        
054        public static final ClassNode 
055            DYNAMIC_TYPE = new ClassNode(Object.class),  OBJECT_TYPE = DYNAMIC_TYPE,
056            VOID_TYPE = new ClassNode(Void.TYPE),        CLOSURE_TYPE = new ClassNode(Closure.class),
057            GSTRING_TYPE = new ClassNode(GString.class), LIST_TYPE = new ClassNode(List.class),
058            MAP_TYPE = new ClassNode(Map.class),         RANGE_TYPE = new ClassNode(Range.class),
059            PATTERN_TYPE = new ClassNode(Pattern.class), STRING_TYPE = new ClassNode(String.class),
060            SCRIPT_TYPE = new ClassNode(Script.class),
061            
062            boolean_TYPE = new ClassNode(boolean.class),     char_TYPE = new ClassNode(char.class),
063            byte_TYPE = new ClassNode(byte.class),           int_TYPE = new ClassNode(int.class),
064            long_TYPE = new ClassNode(long.class),           short_TYPE = new ClassNode(short.class),
065            double_TYPE = new ClassNode(double.class),       float_TYPE = new ClassNode(float.class),
066            Byte_TYPE = new ClassNode(Byte.class),           Short_TYPE = new ClassNode(Short.class),
067            Integer_TYPE = new ClassNode(Integer.class),     Long_TYPE = new ClassNode(Long.class),
068            Character_TYPE = new ClassNode(Character.class), Float_TYPE = new ClassNode(Float.class),
069            Double_TYPE = new ClassNode(Double.class),       Boolean_TYPE = new ClassNode(Boolean.class),
070            BigInteger_TYPE =  new ClassNode(java.math.BigInteger.class),
071            BigDecimal_TYPE = new ClassNode(java.math.BigDecimal.class),
072            void_WRAPPER_TYPE = new ClassNode(Void.class);
073        
074        private static ClassNode[] types = new ClassNode[] {
075            OBJECT_TYPE,
076            boolean_TYPE, char_TYPE, byte_TYPE, short_TYPE,
077            int_TYPE, long_TYPE, double_TYPE, float_TYPE,
078            VOID_TYPE, CLOSURE_TYPE, GSTRING_TYPE,
079            LIST_TYPE, MAP_TYPE, RANGE_TYPE, PATTERN_TYPE,
080            SCRIPT_TYPE, STRING_TYPE, Boolean_TYPE, Character_TYPE,
081            Byte_TYPE, Short_TYPE, Integer_TYPE, Long_TYPE,
082            Double_TYPE, Float_TYPE, BigDecimal_TYPE, BigInteger_TYPE, void_WRAPPER_TYPE
083        };
084    
085        
086        private static ClassNode[] numbers = new ClassNode[] {
087            char_TYPE, byte_TYPE, short_TYPE, int_TYPE, long_TYPE, 
088            double_TYPE, float_TYPE, Short_TYPE, Byte_TYPE, Character_TYPE,
089            Integer_TYPE, Float_TYPE, Long_TYPE, Double_TYPE, BigInteger_TYPE,
090            BigDecimal_TYPE
091        };
092    
093        protected static final ClassNode[] EMPTY_TYPE_ARRAY = {};
094        
095        public static final String OBJECT = "java.lang.Object";    
096        
097        public static ClassNode make(Class c) {
098            for (int i=0; i<classes.length; i++) {
099                if (c==classes[i]) return types[i];
100            }
101            if (c.isArray()) {
102                ClassNode cn = make(c.getComponentType());
103                return cn.makeArray();
104            }
105            ClassNode t = new ClassNode(c);
106            return t;
107        }
108        
109        public static ClassNode makeWithoutCaching(String name) { 
110            ClassNode cn = new ClassNode(name,Opcodes.ACC_PUBLIC,OBJECT_TYPE);
111            cn.resolved = false;
112            cn.isPrimaryNode = false;
113            return cn;
114        }
115        
116        public static ClassNode make(String name) {
117            if (name == null || name.length() == 0) return DYNAMIC_TYPE;
118            
119            for (int i=0; i<classes.length; i++) {
120                String cname = classes[i].getName();
121                if (name.equals(cname)) return types[i];
122            }        
123            return makeWithoutCaching(name);
124        }
125        
126        public static ClassNode getWrapper(ClassNode cn) {
127            cn = cn.redirect();
128            if (!isPrimitiveType(cn)) return cn;
129            if (cn==boolean_TYPE) {
130                return Boolean_TYPE;
131            } else if (cn==byte_TYPE) {
132                return Byte_TYPE;
133            } else if (cn==char_TYPE) {
134                return Character_TYPE;
135            } else if (cn==short_TYPE) {
136                return Short_TYPE;
137            } else if (cn==int_TYPE) {
138                return Integer_TYPE;
139            } else if (cn==long_TYPE) {
140                return Long_TYPE;
141            } else if (cn==float_TYPE) {
142                return Float_TYPE;
143            } else if (cn==double_TYPE) {
144                return Double_TYPE;
145            } else if (cn==VOID_TYPE) {
146                    return void_WRAPPER_TYPE;
147            }
148            else {
149                return cn;
150            }
151        }
152        
153        public static boolean isPrimitiveType(ClassNode cn) {
154            return  cn == boolean_TYPE ||
155                    cn == char_TYPE ||
156                    cn == byte_TYPE ||
157                    cn == short_TYPE ||
158                    cn == int_TYPE ||
159                    cn == long_TYPE ||
160                    cn == float_TYPE ||
161                    cn == double_TYPE ||
162                    cn == VOID_TYPE;
163        }
164        
165        public static ClassNode makeReference() {
166            return make(Reference.class);
167        }
168    
169    }