1/*
2 * Javassist, a Java-bytecode translator toolkit.
3 * Copyright (C) 1999-2007 Shigeru Chiba, and others. All Rights Reserved.
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License.  Alternatively, the contents of this file may be used under
8 * the terms of the GNU Lesser General Public License Version 2.1 or later.
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 */
15package javassist.bytecode.analysis;
16
17import javassist.ClassPool;
18import javassist.CtClass;
19import javassist.NotFoundException;
20
21/**
22 * Represents an array of {@link MultiType} instances.
23 *
24 * @author Jason T. Greene
25 */
26public class MultiArrayType extends Type {
27    private MultiType component;
28    private int dims;
29
30    public MultiArrayType(MultiType component, int dims) {
31        super(null);
32        this.component = component;
33        this.dims = dims;
34    }
35
36    public CtClass getCtClass() {
37        CtClass clazz = component.getCtClass();
38        if (clazz == null)
39            return null;
40
41        ClassPool pool = clazz.getClassPool();
42        if (pool == null)
43            pool = ClassPool.getDefault();
44
45        String name = arrayName(clazz.getName(), dims);
46
47        try {
48            return pool.get(name);
49        } catch (NotFoundException e) {
50            throw new RuntimeException(e);
51        }
52    }
53
54    boolean popChanged() {
55        return component.popChanged();
56    }
57
58    public int getDimensions() {
59        return dims;
60    }
61
62    public Type getComponent() {
63       return dims == 1 ? (Type)component : new MultiArrayType(component, dims - 1);
64    }
65
66    public int getSize() {
67        return 1;
68    }
69
70    public boolean isArray() {
71        return true;
72    }
73
74    public boolean isAssignableFrom(Type type) {
75        throw new UnsupportedOperationException("Not implemented");
76    }
77
78    public boolean isReference() {
79       return true;
80    }
81
82    public boolean isAssignableTo(Type type) {
83        if (eq(type.getCtClass(), Type.OBJECT.getCtClass()))
84            return true;
85
86        if (eq(type.getCtClass(), Type.CLONEABLE.getCtClass()))
87            return true;
88
89        if (eq(type.getCtClass(), Type.SERIALIZABLE.getCtClass()))
90            return true;
91
92        if (! type.isArray())
93            return false;
94
95        Type typeRoot = getRootComponent(type);
96        int typeDims = type.getDimensions();
97
98        if (typeDims > dims)
99            return false;
100
101        if (typeDims < dims) {
102            if (eq(typeRoot.getCtClass(), Type.OBJECT.getCtClass()))
103                return true;
104
105            if (eq(typeRoot.getCtClass(), Type.CLONEABLE.getCtClass()))
106                return true;
107
108            if (eq(typeRoot.getCtClass(), Type.SERIALIZABLE.getCtClass()))
109                return true;
110
111            return false;
112        }
113
114        return component.isAssignableTo(typeRoot);
115    }
116
117    public boolean equals(Object o) {
118        if (! (o instanceof MultiArrayType))
119            return false;
120        MultiArrayType multi = (MultiArrayType)o;
121
122        return component.equals(multi.component) && dims == multi.dims;
123    }
124
125    public String toString() {
126        // follows the same detailed formating scheme as component
127        return arrayName(component.toString(), dims);
128    }
129}
130