1 /*******************************************************************************
2  * Copyright (c) 2004, 2015 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *     Stephan Herrmann - Contribution for
14  *								Bug 466279 - [hovering] IAE on hover when annotation-based null analysis is enabled
15  *******************************************************************************/
16 package org.eclipse.jdt.internal.core;
17 
18 import org.eclipse.jdt.core.*;
19 import org.eclipse.jdt.core.compiler.CharOperation;
20 
21 public class TypeParameter extends SourceRefElement implements ITypeParameter {
22 
23 	static final ITypeParameter[] NO_TYPE_PARAMETERS = new ITypeParameter[0];
24 
25 	protected String name;
26 
TypeParameter(JavaElement parent, String name)27 	public TypeParameter(JavaElement parent, String name) {
28 		super(parent);
29 		this.name = name;
30 	}
31 
32 	@Override
equals(Object o)33 	public boolean equals(Object o) {
34 		if (!(o instanceof TypeParameter)) return false;
35 		return super.equals(o);
36 	}
37 
38 	@Override
getBounds()39 	public String[] getBounds() throws JavaModelException {
40 		TypeParameterElementInfo info = (TypeParameterElementInfo) getElementInfo();
41 		return CharOperation.toStrings(info.bounds);
42 	}
43 
44 	@Override
getBoundsSignatures()45 	public String[] getBoundsSignatures() throws JavaModelException {
46 
47 		String[] boundSignatures = null;
48 		TypeParameterElementInfo info = (TypeParameterElementInfo) this.getElementInfo();
49 
50 		// For a binary type or method, the signature is already available from the .class file.
51 		// No need to construct again
52 		if (this.parent instanceof BinaryMember) {
53 			char[][] boundsSignatures = info.boundsSignatures;
54 			if (boundsSignatures == null || boundsSignatures.length == 0) {
55 				return CharOperation.NO_STRINGS;
56 			}
57 			return CharOperation.toStrings(info.boundsSignatures);
58 		}
59 
60 		char[][] bounds = info.bounds;
61 		if (bounds == null || bounds.length == 0) {
62 			return CharOperation.NO_STRINGS;
63 		}
64 
65 		int boundsLength = bounds.length;
66 		boundSignatures = new String[boundsLength];
67 		for (int i = 0; i < boundsLength; i++) {
68 			boundSignatures[i] = new String(Signature.createCharArrayTypeSignature(bounds[i], false));
69 		}
70 		return boundSignatures;
71 	}
72 
73 	@Override
getDeclaringMember()74 	public IMember getDeclaringMember() {
75 		return (IMember) getParent();
76 	}
77 
78 	@Override
getElementName()79 	public String getElementName() {
80 		return this.name;
81 	}
82 
83 	@Override
getElementType()84 	public int getElementType() {
85 		return TYPE_PARAMETER;
86 	}
87 
88 	@Override
getHandleMementoDelimiter()89 	protected char getHandleMementoDelimiter() {
90 		return JavaElement.JEM_TYPE_PARAMETER;
91 	}
92 
getKey(boolean forceOpen)93 	public String getKey(boolean forceOpen) throws JavaModelException {
94 		StringBuilder buf = new StringBuilder();
95 		if (this.parent instanceof IType) {
96 			if (this.parent instanceof BinaryType)
97 				buf.append(((BinaryType) this.parent).getKey(forceOpen));
98 			else
99 				buf.append(((IType) this.parent).getKey());
100 		} else if (this.parent instanceof IMember) {
101 			if (this.parent instanceof BinaryMember)
102 				buf.append(((BinaryMember) this.parent).getKey(forceOpen));
103 			else
104 				buf.append(((IMethod) this.parent).getKey());
105 		}
106 		buf.append(":T"); //$NON-NLS-1$
107 		buf.append(this.name);
108 		buf.append(';');
109 		return buf.toString();
110 	}
111 
112 	@Override
getNameRange()113 	public ISourceRange getNameRange() throws JavaModelException {
114 		SourceMapper mapper= getSourceMapper();
115 		if (mapper != null) {
116 			// ensure the class file's buffer is open so that source ranges are computed
117 			IClassFile classFile = getClassFile();
118 			if (classFile != null) {
119 				classFile.getBuffer();
120 				return mapper.getNameRange(this);
121 			}
122 		}
123 		TypeParameterElementInfo info = (TypeParameterElementInfo) getElementInfo();
124 		return new SourceRange(info.nameStart, info.nameEnd - info.nameStart + 1);
125 	}
126 
127 	/*
128 	 * @see ISourceReference
129 	 */
130 	@Override
getSourceRange()131 	public ISourceRange getSourceRange() throws JavaModelException {
132 		SourceMapper mapper= getSourceMapper();
133 		if (mapper != null) {
134 			// ensure the class file's buffer is open so that source ranges are computed
135 			IClassFile classFile = getClassFile();
136 			if (classFile != null) {
137 				classFile.getBuffer();
138 				return mapper.getSourceRange(this);
139 			}
140 		}
141 		return super.getSourceRange();
142 	}
143 
144 	@Override
getClassFile()145 	public IClassFile getClassFile() {
146 		return ((JavaElement)getParent()).getClassFile();
147 	}
148 
149 	/**
150 	 * {@inheritDoc}
151 	 * @since 3.7
152 	 */
153 	@Override
getTypeRoot()154 	public ITypeRoot getTypeRoot() {
155 		return this.getDeclaringMember().getTypeRoot();
156 	}
157 
158 	@Override
toStringName(StringBuffer buffer)159 	protected void toStringName(StringBuffer buffer) {
160 		buffer.append('<');
161 		buffer.append(getElementName());
162 		buffer.append('>');
163 	}
164 }
165