Thu, 12 Oct 2017 19:44:07 +0800
merge
1 /*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.codemodel.internal;
28 import java.util.Arrays;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Collections;
32 import java.util.ArrayList;
34 /**
35 * Represents X<Y>.
36 *
37 * TODO: consider separating the decl and the use.
38 *
39 * @author
40 * Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
41 */
42 class JNarrowedClass extends JClass {
43 /**
44 * A generic class with type parameters.
45 */
46 final JClass basis;
47 /**
48 * Arguments to those parameters.
49 */
50 private final List<JClass> args;
52 JNarrowedClass(JClass basis, JClass arg) {
53 this(basis,Collections.singletonList(arg));
54 }
56 JNarrowedClass(JClass basis, List<JClass> args) {
57 super(basis.owner());
58 this.basis = basis;
59 assert !(basis instanceof JNarrowedClass);
60 this.args = args;
61 }
63 @Override
64 public JClass narrow( JClass clazz ) {
65 List<JClass> newArgs = new ArrayList<JClass>(args);
66 newArgs.add(clazz);
67 return new JNarrowedClass(basis,newArgs);
68 }
70 @Override
71 public JClass narrow( JClass... clazz ) {
72 List<JClass> newArgs = new ArrayList<JClass>(args);
73 newArgs.addAll(Arrays.asList(clazz));
74 return new JNarrowedClass(basis,newArgs);
75 }
77 public String name() {
78 StringBuilder buf = new StringBuilder();
79 buf.append(basis.name());
80 buf.append('<');
81 boolean first = true;
82 for (JClass c : args) {
83 if(first)
84 first = false;
85 else
86 buf.append(',');
87 buf.append(c.name());
88 }
89 buf.append('>');
90 return buf.toString();
91 }
93 public String fullName() {
94 StringBuilder buf = new StringBuilder();
95 buf.append(basis.fullName());
96 buf.append('<');
97 boolean first = true;
98 for (JClass c : args) {
99 if(first)
100 first = false;
101 else
102 buf.append(',');
103 buf.append(c.fullName());
104 }
105 buf.append('>');
106 return buf.toString();
107 }
109 @Override
110 public String binaryName() {
111 StringBuilder buf = new StringBuilder();
112 buf.append(basis.binaryName());
113 buf.append('<');
114 boolean first = true;
115 for (JClass c : args) {
116 if(first)
117 first = false;
118 else
119 buf.append(',');
120 buf.append(c.binaryName());
121 }
122 buf.append('>');
123 return buf.toString();
124 }
126 @Override
127 public void generate(JFormatter f) {
128 f.t(basis).p('<').g(args).p(JFormatter.CLOSE_TYPE_ARGS);
129 }
131 @Override
132 void printLink(JFormatter f) {
133 basis.printLink(f);
134 f.p("{@code <}");
135 boolean first = true;
136 for( JClass c : args ) {
137 if(first)
138 first = false;
139 else
140 f.p(',');
141 c.printLink(f);
142 }
143 f.p("{@code >}");
144 }
146 public JPackage _package() {
147 return basis._package();
148 }
150 public JClass _extends() {
151 JClass base = basis._extends();
152 if(base==null) return base;
153 return base.substituteParams(basis.typeParams(),args);
154 }
156 public Iterator<JClass> _implements() {
157 return new Iterator<JClass>() {
158 private final Iterator<JClass> core = basis._implements();
159 public void remove() {
160 core.remove();
161 }
162 public JClass next() {
163 return core.next().substituteParams(basis.typeParams(),args);
164 }
165 public boolean hasNext() {
166 return core.hasNext();
167 }
168 };
169 }
171 @Override
172 public JClass erasure() {
173 return basis;
174 }
176 public boolean isInterface() {
177 return basis.isInterface();
178 }
180 public boolean isAbstract() {
181 return basis.isAbstract();
182 }
184 @Override
185 public boolean isArray() {
186 return false;
187 }
190 //
191 // Equality is based on value
192 //
194 @Override
195 public boolean equals(Object obj) {
196 if(!(obj instanceof JNarrowedClass)) return false;
197 return fullName().equals(((JClass)obj).fullName());
198 }
200 @Override
201 public int hashCode() {
202 return fullName().hashCode();
203 }
205 protected JClass substituteParams(JTypeVar[] variables, List<JClass> bindings) {
206 JClass b = basis.substituteParams(variables,bindings);
207 boolean different = b!=basis;
209 List<JClass> clazz = new ArrayList<JClass>(args.size());
210 for( int i=0; i<clazz.size(); i++ ) {
211 JClass c = args.get(i).substituteParams(variables,bindings);
212 clazz.set(i,c);
213 different |= c != args.get(i);
214 }
216 if(different)
217 return new JNarrowedClass(b,clazz);
218 else
219 return this;
220 }
222 @Override
223 public List<JClass> getTypeParameters() {
224 return args;
225 }
226 }