001: /*
002: * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.codemodel.internal;
027:
028: import java.util.Iterator;
029: import java.util.List;
030: import java.util.Collections;
031: import java.util.ArrayList;
032:
033: /**
034: * Represents X<Y>.
035: *
036: * TODO: consider separating the decl and the use.
037: *
038: * @author
039: * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
040: */
041: class JNarrowedClass extends JClass {
042: /**
043: * A generic class with type parameters.
044: */
045: final JClass basis;
046: /**
047: * Arguments to those parameters.
048: */
049: private final List<JClass> args;
050:
051: JNarrowedClass(JClass basis, JClass arg) {
052: this (basis, Collections.singletonList(arg));
053: }
054:
055: JNarrowedClass(JClass basis, List<JClass> args) {
056: super (basis.owner());
057: this .basis = basis;
058: assert !(basis instanceof JNarrowedClass);
059: this .args = args;
060: }
061:
062: public JClass narrow(JClass clazz) {
063: List<JClass> newArgs = new ArrayList<JClass>(args);
064: newArgs.add(clazz);
065: return new JNarrowedClass(basis, newArgs);
066: }
067:
068: public JClass narrow(JClass... clazz) {
069: List<JClass> newArgs = new ArrayList<JClass>(args);
070: for (JClass c : clazz)
071: newArgs.add(c);
072: return new JNarrowedClass(basis, newArgs);
073: }
074:
075: public String name() {
076: StringBuffer buf = new StringBuffer();
077: buf.append(basis.name());
078: buf.append('<');
079: boolean first = true;
080: for (JClass c : args) {
081: if (first)
082: first = false;
083: else
084: buf.append(',');
085: buf.append(c.name());
086: }
087: buf.append('>');
088: return buf.toString();
089: }
090:
091: public String fullName() {
092: StringBuilder buf = new StringBuilder();
093: buf.append(basis.fullName());
094: buf.append('<');
095: boolean first = true;
096: for (JClass c : args) {
097: if (first)
098: first = false;
099: else
100: buf.append(',');
101: buf.append(c.fullName());
102: }
103: buf.append('>');
104: return buf.toString();
105: }
106:
107: public String binaryName() {
108: StringBuilder buf = new StringBuilder();
109: buf.append(basis.binaryName());
110: buf.append('<');
111: boolean first = true;
112: for (JClass c : args) {
113: if (first)
114: first = false;
115: else
116: buf.append(',');
117: buf.append(c.binaryName());
118: }
119: buf.append('>');
120: return buf.toString();
121: }
122:
123: public void generate(JFormatter f) {
124: f.t(basis).p('<').g(args).p(JFormatter.CLOSE_TYPE_ARGS);
125: }
126:
127: @Override
128: void printLink(JFormatter f) {
129: basis.printLink(f);
130: f.p("{@code <}");
131: boolean first = true;
132: for (JClass c : args) {
133: if (first)
134: first = false;
135: else
136: f.p(',');
137: c.printLink(f);
138: }
139: f.p("{@code >}");
140: }
141:
142: public JPackage _package() {
143: return basis._package();
144: }
145:
146: public JClass _extends() {
147: JClass base = basis._extends();
148: if (base == null)
149: return base;
150: return base.substituteParams(basis.typeParams(), args);
151: }
152:
153: public Iterator<JClass> _implements () {
154: return new Iterator<JClass>() {
155: private final Iterator<JClass> core = basis._implements ();
156:
157: public void remove() {
158: core.remove();
159: }
160:
161: public JClass next() {
162: return core.next().substituteParams(basis.typeParams(),
163: args);
164: }
165:
166: public boolean hasNext() {
167: return core.hasNext();
168: }
169: };
170: }
171:
172: public JClass erasure() {
173: return basis;
174: }
175:
176: public boolean isInterface() {
177: return basis.isInterface();
178: }
179:
180: public boolean isAbstract() {
181: return basis.isAbstract();
182: }
183:
184: public boolean isArray() {
185: return false;
186: }
187:
188: //
189: // Equality is based on value
190: //
191:
192: public boolean equals(Object obj) {
193: if (!(obj instanceof JNarrowedClass))
194: return false;
195: return fullName().equals(((JClass) obj).fullName());
196: }
197:
198: public int hashCode() {
199: return fullName().hashCode();
200: }
201:
202: protected JClass substituteParams(JTypeVar[] variables,
203: List<JClass> bindings) {
204: JClass b = basis.substituteParams(variables, bindings);
205: boolean different = b != basis;
206:
207: List<JClass> clazz = new ArrayList<JClass>(args.size());
208: for (int i = 0; i < clazz.size(); i++) {
209: JClass c = args.get(i)
210: .substituteParams(variables, bindings);
211: clazz.set(i, c);
212: different |= c != args.get(i);
213: }
214:
215: if (different)
216: return new JNarrowedClass(b, clazz);
217: else
218: return this ;
219: }
220:
221: public List<JClass> getTypeParameters() {
222: return args;
223: }
224: }
|