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