Java Code Examples for org.eclipse.jdt.core.compiler.CharOperation#subarray()
The following examples show how to use
org.eclipse.jdt.core.compiler.CharOperation#subarray() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: QualifiedTypeReference.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 6 votes |
protected TypeBinding findNextTypeBinding(int tokenIndex, Scope scope, PackageBinding packageBinding) { LookupEnvironment env = scope.environment(); try { env.missingClassFileLocation = this; if (this.resolvedType == null) { this.resolvedType = scope.getType(this.tokens[tokenIndex], packageBinding); } else { this.resolvedType = scope.getMemberType(this.tokens[tokenIndex], (ReferenceBinding) this.resolvedType); if (!this.resolvedType.isValidBinding()) { this.resolvedType = new ProblemReferenceBinding( CharOperation.subarray(this.tokens, 0, tokenIndex + 1), (ReferenceBinding)this.resolvedType.closestMatch(), this.resolvedType.problemId()); } } return this.resolvedType; } catch (AbortCompilation e) { e.updateContext(this, scope.referenceCompilationUnit().compilationResult); throw e; } finally { env.missingClassFileLocation = null; } }
Example 2
Source File: LookupEnvironment.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 6 votes |
private PackageBinding computePackageFrom(char[][] constantPoolName, boolean isMissing) { if (constantPoolName.length == 1) return this.defaultPackage; PackageBinding packageBinding = getPackage0(constantPoolName[0]); if (packageBinding == null || packageBinding == TheNotFoundPackage) { packageBinding = new PackageBinding(constantPoolName[0], this); if (isMissing) packageBinding.tagBits |= TagBits.HasMissingType; this.knownPackages.put(constantPoolName[0], packageBinding); } for (int i = 1, length = constantPoolName.length - 1; i < length; i++) { PackageBinding parent = packageBinding; if ((packageBinding = parent.getPackage0(constantPoolName[i])) == null || packageBinding == TheNotFoundPackage) { packageBinding = new PackageBinding(CharOperation.subarray(constantPoolName, 0, i + 1), parent, this); if (isMissing) { packageBinding.tagBits |= TagBits.HasMissingType; } parent.addPackage(packageBinding); } } return packageBinding; }
Example 3
Source File: BindingKeyParser.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 6 votes |
private void parseTypeVariable() { if (this.scanner.nextToken() != Scanner.TYPE) { malformedKey(); return; } char[] typeVariableName = this.scanner.getTokenSource(); char[] position; int length = typeVariableName.length; if (length > 0 && Character.isDigit(typeVariableName[0])) { int firstT = CharOperation.indexOf('T', typeVariableName); position = CharOperation.subarray(typeVariableName, 0, firstT); typeVariableName = CharOperation.subarray(typeVariableName, firstT+1, typeVariableName.length); } else { position = CharOperation.NO_CHAR; } consumeTypeVariable(position, typeVariableName); this.scanner.skipTypeEnd(); }
Example 4
Source File: CompilationUnitDeclaration.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 6 votes |
public char[] getMainTypeName() { if (this.compilationResult.compilationUnit == null) { char[] fileName = this.compilationResult.getFileName(); int start = CharOperation.lastIndexOf('/', fileName) + 1; if (start == 0 || start < CharOperation.lastIndexOf('\\', fileName)) start = CharOperation.lastIndexOf('\\', fileName) + 1; int end = CharOperation.lastIndexOf('.', fileName); if (end == -1) end = fileName.length; return CharOperation.subarray(fileName, start, end); } else { return this.compilationResult.compilationUnit.getMainTypeName(); } }
Example 5
Source File: ReferenceCollection.java From takari-lifecycle with Eclipse Public License 1.0 | 5 votes |
/** * Adds the fully-qualified type names of any new dependencies, each name is of the form "p1.p2.A.B". * * @see BuildContext#recordDependencies(String[]) */ public void addDependencies(Collection<String> typeNameDependencies) { // if each qualified type name is already known then all of its subNames can be skipped // and its expected that very few qualified names in typeNameDependencies need to be added // but could always take 'p1.p2.p3.X' and make all qualified names 'p1' 'p1.p2' 'p1.p2.p3' 'p1.p2.p3.X', then intern char[][][] qNames = new char[typeNameDependencies.size()][][]; Iterator<String> typeNameDependency = typeNameDependencies.iterator(); for (int i = 0; typeNameDependency.hasNext(); i++) { qNames[i] = CharOperation.splitOn('.', typeNameDependency.next().toCharArray()); } qNames = internQualifiedNames(qNames, false); next: for (int i = qNames.length; --i >= 0;) { char[][] qualifiedTypeName = qNames[i]; while (!includes(qualifiedTypeName)) { if (!includes(qualifiedTypeName[qualifiedTypeName.length - 1])) { this.simpleNameReferences.add(new String(qualifiedTypeName[qualifiedTypeName.length - 1])); } if (!insideRoot(qualifiedTypeName[0])) { this.rootReferences.add(new String(qualifiedTypeName[0])); } this.qualifiedNameReferences.add(CharOperation.toString(qualifiedTypeName)); qualifiedTypeName = CharOperation.subarray(qualifiedTypeName, 0, qualifiedTypeName.length - 1); char[][][] temp = internQualifiedNames(new char[][][] {qualifiedTypeName}, false); if (temp == EmptyQualifiedNames) continue next; // qualifiedTypeName is a well known name qualifiedTypeName = temp[0]; } } }
Example 6
Source File: ConstructorPattern.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 5 votes |
public void decodeIndexKey(char[] key) { int last = key.length - 1; int slash = CharOperation.indexOf(SEPARATOR, key, 0); this.declaringSimpleName = CharOperation.subarray(key, 0, slash); int start = slash + 1; slash = CharOperation.indexOf(SEPARATOR, key, start); if (slash != -1) { last = slash - 1; } boolean isDefaultConstructor = key[last] == '#'; if (isDefaultConstructor) { this.parameterCount = -1; } else { this.parameterCount = 0; int power = 1; for (int i = last; i >= start; i--) { if (i == last) { this.parameterCount = key[i] - '0'; } else { power *= 10; this.parameterCount += power * (key[i] - '0'); } } } }
Example 7
Source File: LookupEnvironment.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 5 votes |
public PackageBinding createPackage(char[][] compoundName) { PackageBinding packageBinding = getPackage0(compoundName[0]); if (packageBinding == null || packageBinding == TheNotFoundPackage) { packageBinding = new PackageBinding(compoundName[0], this); this.knownPackages.put(compoundName[0], packageBinding); } for (int i = 1, length = compoundName.length; i < length; i++) { // check to see if it collides with a known type... // this case can only happen if the package does not exist as a directory in the file system // otherwise when the source type was defined, the correct error would have been reported // unless its an unresolved type which is referenced from an inconsistent class file // NOTE: empty packages are not packages according to changes in JLS v2, 7.4.3 // so not all types cause collision errors when they're created even though the package did exist ReferenceBinding type = packageBinding.getType0(compoundName[i]); if (type != null && type != TheNotFoundType && !(type instanceof UnresolvedReferenceBinding)) return null; PackageBinding parent = packageBinding; if ((packageBinding = parent.getPackage0(compoundName[i])) == null || packageBinding == TheNotFoundPackage) { // if the package is unknown, check to see if a type exists which would collide with the new package // catches the case of a package statement of: package java.lang.Object; // since the package can be added after a set of source files have already been compiled, // we need to check whenever a package is created if (this.nameEnvironment.findType(compoundName[i], parent.compoundName) != null) return null; packageBinding = new PackageBinding(CharOperation.subarray(compoundName, 0, i + 1), parent, this); parent.addPackage(packageBinding); } } return packageBinding; }
Example 8
Source File: Classpath.java From takari-lifecycle with Eclipse Public License 1.0 | 5 votes |
@Override public NameEnvironmentAnswer findType(char[][] compoundTypeName) { if (compoundTypeName == null) { return null; } int typeNameIndex = compoundTypeName.length - 1; char[][] packageName = CharOperation.subarray(compoundTypeName, 0, typeNameIndex); return findType(new String(CharOperation.concatWith(packageName, '/')), new String(compoundTypeName[typeNameIndex])); }
Example 9
Source File: CompilationUnit.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 5 votes |
public CompilationUnit(char[] contents, String fileName, String encoding, String destinationPath, boolean ignoreOptionalProblems) { this.contents = contents; char[] fileNameCharArray = fileName.toCharArray(); switch(File.separatorChar) { case '/' : if (CharOperation.indexOf('\\', fileNameCharArray) != -1) { CharOperation.replace(fileNameCharArray, '\\', '/'); } break; case '\\' : if (CharOperation.indexOf('/', fileNameCharArray) != -1) { CharOperation.replace(fileNameCharArray, '/', '\\'); } } this.fileName = fileNameCharArray; int start = CharOperation.lastIndexOf(File.separatorChar, fileNameCharArray) + 1; int end = CharOperation.lastIndexOf('.', fileNameCharArray); if (end == -1) { end = fileNameCharArray.length; } this.mainTypeName = CharOperation.subarray(fileNameCharArray, start, end); this.encoding = encoding; this.destinationPath = destinationPath; this.ignoreOptionalProblems = ignoreOptionalProblems; }
Example 10
Source File: Signature.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 5 votes |
/** * Returns the last segment of the given dot-separated qualified name. * Returns the given name if it is not qualified. * <p> * For example: * <pre> * <code> * getSimpleName({'j', 'a', 'v', 'a', '.', 'l', 'a', 'n', 'g', '.', 'O', 'b', 'j', 'e', 'c', 't'}) -> {'O', 'b', 'j', 'e', 'c', 't'} * </code> * </pre> * </p> * * @param name the name * @return the last segment of the qualified name * @exception NullPointerException if name is null * @since 2.0 */ public static char[] getSimpleName(char[] name) { int lastDot = -1, lastGenericStart = -1, lastGenericEnd = -1; int depth = 0; int length = name.length; lastDotLookup: for (int i = length -1; i >= 0; i--) { switch (name[i]) { case '.': if (depth == 0) { lastDot = i; break lastDotLookup; } break; case '<': depth--; if (depth == 0) lastGenericStart = i; break; case '>': if (depth == 0) lastGenericEnd = i; depth++; break; } } if (lastGenericStart < 0) { if (lastDot < 0) { return name; } return CharOperation.subarray(name, lastDot + 1, length); } StringBuffer buffer = new StringBuffer(10); int nameStart = lastDot < 0 ? 0 : lastDot+1; buffer.append(name, nameStart, lastGenericStart - nameStart); appendArgumentSimpleNames(name, lastGenericStart, lastGenericEnd, buffer); buffer.append(name, lastGenericEnd+1, length-lastGenericEnd-1); // copy trailing portion, may contain dimensions char[] result = new char[length = buffer.length()]; buffer.getChars(0, length, result, 0); return result; }
Example 11
Source File: Util.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 5 votes |
public final static boolean isExcluded(char[] path, char[][] inclusionPatterns, char[][] exclusionPatterns, boolean isFolderPath) { if (inclusionPatterns == null && exclusionPatterns == null) return false; inclusionCheck: if (inclusionPatterns != null) { for (int i = 0, length = inclusionPatterns.length; i < length; i++) { char[] pattern = inclusionPatterns[i]; char[] folderPattern = pattern; if (isFolderPath) { int lastSlash = CharOperation.lastIndexOf('/', pattern); if (lastSlash != -1 && lastSlash != pattern.length-1){ // trailing slash -> adds '**' for free (see http://ant.apache.org/manual/dirtasks.html) int star = CharOperation.indexOf('*', pattern, lastSlash); if ((star == -1 || star >= pattern.length-1 || pattern[star+1] != '*')) { folderPattern = CharOperation.subarray(pattern, 0, lastSlash); } } } if (CharOperation.pathMatch(folderPattern, path, true, '/')) { break inclusionCheck; } } return true; // never included } if (isFolderPath) { path = CharOperation.concat(path, new char[] {'*'}, '/'); } if (exclusionPatterns != null) { for (int i = 0, length = exclusionPatterns.length; i < length; i++) { if (CharOperation.pathMatch(exclusionPatterns[i], path, true, '/')) { return true; } } } return false; }
Example 12
Source File: DOMField.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 5 votes |
/** * Returns the souce code to be used for this * field's type. */ protected char[] getTypeContents() { if (isTypeAltered()) { return this.fType.toCharArray(); } else { return CharOperation.subarray(this.fDocument, this.fTypeRange[0], this.fTypeRange[1] + 1); } }
Example 13
Source File: Signature.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 5 votes |
/** * Returns type fragment of a type signature. The package fragment separator must be '.' * and the type fragment separator must be '$'. * <p> * For example: * <pre> * <code> * getSignatureSimpleName({'L', 'j', 'a', 'v', 'a', '.', 'u', 't', 'i', 'l', '.', 'M', 'a', 'p', '$', 'E', 'n', 't', 'r', 'y', ';'}) -> {'M', 'a', 'p', '.', 'E', 'n', 't', 'r', 'y'} * </code> * </pre> * </p> * * @param typeSignature the type signature * @return the type fragment (separators are '.') * @since 3.1 */ public static char[] getSignatureSimpleName(char[] typeSignature) { if(typeSignature == null) return CharOperation.NO_CHAR; char[] qualifiedType = Signature.toCharArray(typeSignature); int dotCount = 0; indexFound: for(int i = 0; i < typeSignature.length; i++) { switch(typeSignature[i]) { case C_DOT: dotCount++; break; case C_GENERIC_START: break indexFound; case C_DOLLAR: break indexFound; } } if(dotCount > 0) { for(int i = 0; i < qualifiedType.length; i++) { if(qualifiedType[i] == '.') { dotCount--; } if(dotCount <= 0) { return CharOperation.subarray(qualifiedType, i + 1, qualifiedType.length); } } } return qualifiedType; }
Example 14
Source File: NamingConventions.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 4 votes |
/** * Suggest name for a setter method. The name is computed from field's name * and possible prefixes or suffixes are removed. * <p> * If the field name is <code>preFieldNamesuf</code> and the prefix for field is <code>pre</code> and * the suffix for field is <code>suf</code> then the proposed name is <code>setFieldName</code>. * If there is no prefix and suffix the proposal is <code>setPreFieldNamesuf</code>. * </p> * <p> * This method is affected by the following JavaCore options : {@link JavaCore#CODEASSIST_FIELD_PREFIXES}, * {@link JavaCore#CODEASSIST_FIELD_SUFFIXES} for instance field and {@link JavaCore#CODEASSIST_STATIC_FIELD_PREFIXES}, * {@link JavaCore#CODEASSIST_STATIC_FIELD_SUFFIXES} for static field. * </p> * <p> * For a complete description of these configurable options, see <code>getDefaultOptions</code>. * For programmaticaly change these options, see <code>JavaCore#setOptions()</code>. * </p> * * @param project project which contains the field. * @param fieldName field's name's. * @param modifiers field's modifiers as defined by the class * <code>Flags</code>. * @param isBoolean <code>true</code> if the field's type is boolean * @param excludedNames a list of names which cannot be suggested (already used names). * Can be <code>null</code> if there is no excluded names. * @return char[] a name. * @see Flags * @see JavaCore#setOptions(java.util.Hashtable) * @see JavaCore#getDefaultOptions() */ public static char[] suggestSetterName(IJavaProject project, char[] fieldName, int modifiers, boolean isBoolean, char[][] excludedNames) { if (isBoolean) { char[] name = InternalNamingConventions.getBaseName(getFieldVariableKind(modifiers), project, fieldName, false); int prefixLen = GETTER_BOOL_NAME.length; if (CharOperation.prefixEquals(GETTER_BOOL_NAME, name) && name.length > prefixLen && ScannerHelper.isUpperCase(name[prefixLen])) { name = CharOperation.subarray(name, prefixLen, name.length); return suggestNewName( CharOperation.concat(SETTER_NAME, suggestAccessorName(project, name, modifiers)), excludedNames ); } else { return suggestNewName( CharOperation.concat(SETTER_NAME, suggestAccessorName(project, fieldName, modifiers)), excludedNames ); } } else { return suggestNewName( CharOperation.concat(SETTER_NAME, suggestAccessorName(project, fieldName, modifiers)), excludedNames ); } }
Example 15
Source File: AbstractIndexer.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 4 votes |
private char[] erasure(char[] typeName) { int genericStart = CharOperation.indexOf(Signature.C_GENERIC_START, typeName); if (genericStart > -1) typeName = CharOperation.subarray(typeName, 0, genericStart); return typeName; }
Example 16
Source File: BinaryMethod.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 4 votes |
private char[][] splitParameters(char[] parametersSource, int paramCount) { // we have generic types as one of the parameter types char[][] params = new char[paramCount][]; int paramIndex = 0; int index = 0; int balance = 0; int length = parametersSource.length; int start = 0; while(index < length) { switch (parametersSource[index]) { case '<': balance++; index++; while(index < length && parametersSource[index] != '>') { index++; } break; case '>' : balance--; index++; break; case ',' : if (balance == 0 && paramIndex < paramCount) { params[paramIndex++] = CharOperation.subarray(parametersSource, start, index); start = index + 1; } index++; break; case '&' : if ((index + 4) < length) { if (parametersSource[index + 1] == 'l' && parametersSource[index + 2] == 't' && parametersSource[index + 3] == ';') { balance++; index += 4; } else if (parametersSource[index + 1] == 'g' && parametersSource[index + 2] == 't' && parametersSource[index + 3] == ';') { balance--; index += 4; } else { index++; } } else { index++; } break; default: index++; } } if (paramIndex < paramCount) { params[paramIndex++] = CharOperation.subarray(parametersSource, start, index); } if (paramIndex != paramCount) { // happens only for constructors with synthetic enclosing type in the signature System.arraycopy(params, 0, (params = new char[paramIndex][]), 0, paramIndex); } return params; }
Example 17
Source File: VerificationTypeInfo.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 4 votes |
public void replaceWithElementType() { if (this.constantPoolName[1] == 'L') { this.constantPoolName = CharOperation.subarray(this.constantPoolName, 2, this.constantPoolName.length - 1); } else { this.constantPoolName = CharOperation.subarray(this.constantPoolName, 1, this.constantPoolName.length); if (this.constantPoolName.length == 1) { switch(this.constantPoolName[0]) { case 'I' : this.id = TypeIds.T_int; break; case 'B' : this.id = TypeIds.T_byte; break; case 'S' : this.id = TypeIds.T_short; break; case 'C' : this.id = TypeIds.T_char; break; case 'J' : this.id = TypeIds.T_long; break; case 'F' : this.id = TypeIds.T_float; break; case 'D' : this.id = TypeIds.T_double; break; case 'Z' : this.id = TypeIds.T_boolean; break; case 'N' : this.id = TypeIds.T_null; break; case 'V' : this.id = TypeIds.T_void; break; } } } }
Example 18
Source File: CodeSnippetParser.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 4 votes |
/** * In case emulating local variables, wrap the (recovered) statements inside a * try statement so as to achieve local state commiting (copy local vars back to fields). * The CSToCuMapper could not be used, since it could have interfered with * the syntax recovery specific to code snippets. */ protected void consumeMethodDeclaration(boolean isNotAbstract, boolean isDefaultMethod) { // MethodDeclaration ::= MethodHeader MethodBody // AbstractMethodDeclaration ::= MethodHeader ';' super.consumeMethodDeclaration(isNotAbstract, isDefaultMethod); // now we know that we have a method declaration at the top of the ast stack MethodDeclaration methodDecl = (MethodDeclaration) this.astStack[this.astPtr]; // automatically wrap the last statement inside a return statement, if it is an expression // support have to be defined at toplevel only if (isTopLevelType()) { int last = methodDecl.statements == null ? -1 : methodDecl.statements.length - 1; if (last >= 0 && methodDecl.statements[last] instanceof Expression){ Expression lastExpression = (Expression) methodDecl.statements[last]; methodDecl.statements[last] = new CodeSnippetReturnStatement( lastExpression, lastExpression.sourceStart, lastExpression.sourceEnd); } } int start = methodDecl.bodyStart-1, end = start; long position = ((long)start << 32) + end; long[] positions = new long[]{position}; if (this.evaluationContext.localVariableNames != null) { int varCount = this.evaluationContext.localVariableNames.length; // n local decls+ try statement // generate n local variable declarations: [type] [name] = val$[name]; Statement[] newStatements = new Statement[varCount+1]; for (int i = 0; i < varCount; i++){ char[] trimmedTypeName = this.evaluationContext.localVariableTypeNames[i]; int nameEnd = CharOperation.indexOf('[', trimmedTypeName); if (nameEnd >= 0) { trimmedTypeName = CharOperation.subarray(trimmedTypeName, 0, nameEnd); } nameEnd = CharOperation.indexOf(' ', trimmedTypeName); if (nameEnd >= 0) { trimmedTypeName = CharOperation.subarray(trimmedTypeName, 0, nameEnd); } TypeReference typeReference; if (CharOperation.indexOf('.', trimmedTypeName) == -1) { typeReference = new SingleTypeReference(trimmedTypeName, position); } else { typeReference = new QualifiedTypeReference( CharOperation.splitOn('.', trimmedTypeName), positions); } int dimCount = CharOperation.occurencesOf('[', this.evaluationContext.localVariableTypeNames[i]); if (dimCount > 0) { typeReference = augmentTypeWithAdditionalDimensions(typeReference, dimCount, null, false); } NameReference init = new SingleNameReference( CharOperation.concat(LOCAL_VAR_PREFIX, this.evaluationContext.localVariableNames[i]), position); LocalDeclaration declaration = new LocalDeclaration(this.evaluationContext.localVariableNames[i], start, end); declaration.initialization = init; declaration.type = typeReference; declaration.modifiers = this.evaluationContext.localVariableModifiers[i]; newStatements[i] = declaration; } // generate try { [snippet] } finally { [save locals to fields] } // try block TryStatement tryStatement = new TryStatement(); Block tryBlock = new Block(methodDecl.explicitDeclarations); tryBlock.sourceStart = start; tryBlock.sourceEnd = end; tryBlock.statements = methodDecl.statements; // snippet statements tryStatement.tryBlock = tryBlock; // finally block Block finallyBlock = new Block(0); finallyBlock.sourceStart = start; finallyBlock.sourceEnd = end; finallyBlock.statements = new Statement[varCount]; for (int i = 0; i < varCount; i++){ SingleNameReference nameRef = new SingleNameReference(this.evaluationContext.localVariableNames[i], position); finallyBlock.statements[i] = new Assignment( new SingleNameReference(CharOperation.concat(LOCAL_VAR_PREFIX, this.evaluationContext.localVariableNames[i]), position), nameRef, nameRef.sourceEnd); } tryStatement.finallyBlock = finallyBlock; newStatements[varCount] = tryStatement; methodDecl.statements = newStatements; } }
Example 19
Source File: PossibleMatch.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 4 votes |
public char[][] getPackageName() { int length = this.compoundName.length; if (length <= 1) return CharOperation.NO_CHAR_CHAR; return CharOperation.subarray(this.compoundName, 0, length - 1); }
Example 20
Source File: Signature.java From Eclipse-Postfix-Code-Completion with Eclipse Public License 1.0 | 3 votes |
/** * Extracts the type variable name from the given formal type parameter * signature. The signature is expected to be dot-based. * * @param formalTypeParameterSignature the formal type parameter signature * @return the name of the type variable * @exception IllegalArgumentException if the signature is syntactically * incorrect * @since 3.0 */ public static char[] getTypeVariable(char[] formalTypeParameterSignature) throws IllegalArgumentException { int p = CharOperation.indexOf(C_COLON, formalTypeParameterSignature); if (p < 0) { // no ":" means can't be a formal type parameter signature throw new IllegalArgumentException(); } return CharOperation.subarray(formalTypeParameterSignature, 0, p); }