1 /*******************************************************************************
2  * Copyright (c) 2015, 2016 Google, Inc 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  *   Stefan Xenos (Google) - Initial implementation
13  *******************************************************************************/
14 package org.eclipse.jdt.internal.core.nd.indexer;
15 
16 import org.eclipse.jdt.internal.compiler.env.IBinaryField;
17 import org.eclipse.jdt.internal.compiler.env.IBinaryMethod;
18 import org.eclipse.jdt.internal.compiler.env.IBinaryType;
19 import org.eclipse.jdt.internal.compiler.lookup.SignatureWrapper;
20 import org.eclipse.jdt.internal.core.nd.util.CharArrayUtils;
21 
22 /**
23  * Contains static factory methods for constructing {@link SignatureWrapper} from various types.
24  */
25 public class GenericSignatures {
26 	private static final char[][] EMPTY_CHAR_ARRAY_ARRAY = new char[0][];
27 
getGenericSignature(IBinaryMethod next)28 	public static SignatureWrapper getGenericSignature(IBinaryMethod next) {
29 		char[] signature = next.getGenericSignature();
30 		if (signature == null) {
31 			signature = next.getMethodDescriptor();
32 		}
33 
34 		return new SignatureWrapper(signature);
35 	}
36 
37 	/**
38 	 * Returns the generic signature for the given field. If the field has no generic signature, one is generated
39 	 * from the type's field descriptor.
40 	 */
getGenericSignature(IBinaryType binaryType)41 	public static SignatureWrapper getGenericSignature(IBinaryType binaryType) {
42 		char[][] interfaces = binaryType.getInterfaceNames();
43 		if (interfaces == null) {
44 			interfaces = EMPTY_CHAR_ARRAY_ARRAY;
45 		}
46 		char[] genericSignature = binaryType.getGenericSignature();
47 		if (genericSignature == null) {
48 			int startIndex = binaryType.getSuperclassName() != null ? 3 : 0;
49 			char[][] toCatenate = new char[startIndex + (interfaces.length * 3)][];
50 			char[] prefix = new char[]{'L'};
51 			char[] suffix = new char[]{';'};
52 
53 			if (binaryType.getSuperclassName() != null) {
54 				toCatenate[0] = prefix;
55 				toCatenate[1] = binaryType.getSuperclassName();
56 				toCatenate[2] = suffix;
57 			}
58 
59 			for (int idx = 0; idx < interfaces.length; idx++) {
60 				int catIndex = startIndex + idx * 3;
61 				toCatenate[catIndex] = prefix;
62 				toCatenate[catIndex + 1] = interfaces[idx];
63 				toCatenate[catIndex + 2] = suffix;
64 			}
65 
66 			genericSignature = CharArrayUtils.concat(toCatenate);
67 		}
68 
69 		SignatureWrapper signatureWrapper = new SignatureWrapper(genericSignature);
70 		return signatureWrapper;
71 	}
72 
73 	/**
74 	 * Returns the generic signature for the given field. If the field has no generic signature, one is generated
75 	 * from the type's field descriptor.
76 	 */
getGenericSignatureFor(IBinaryField nextField)77 	static SignatureWrapper getGenericSignatureFor(IBinaryField nextField) {
78 		char[] signature = nextField.getGenericSignature();
79 		if (signature == null) {
80 			signature = nextField.getTypeName();
81 		}
82 		return new SignatureWrapper(signature);
83 	}
84 
85 }
86