141 lines
4.0 KiB
Java
141 lines
4.0 KiB
Java
/*******************************************************************************
|
|
* Copyright (c) 2006 IBM Corporation.
|
|
* All rights reserved. This program and the accompanying materials
|
|
* are made available under the terms of the Eclipse Public License v1.0
|
|
* which accompanies this distribution, and is available at
|
|
* http://www.eclipse.org/legal/epl-v10.html
|
|
*
|
|
* Contributors:
|
|
* IBM Corporation - initial API and implementation
|
|
*******************************************************************************/
|
|
package com.ibm.wala.types.generics;
|
|
|
|
import java.util.StringTokenizer;
|
|
|
|
import com.ibm.wala.classLoader.IClass;
|
|
import com.ibm.wala.ipa.cha.IClassHierarchy;
|
|
import com.ibm.wala.types.ClassLoaderReference;
|
|
import com.ibm.wala.types.TypeName;
|
|
import com.ibm.wala.types.TypeReference;
|
|
|
|
/**
|
|
* Under construction.
|
|
*
|
|
* ClassTypeSignature:
|
|
* L PackageSpecifier* SimpleClassTypeSignature ClassTypeSignatureSuffix* ;
|
|
*
|
|
* SimpleClassTypeSignature:
|
|
* Identifier TypeArguments?
|
|
*
|
|
* TypeArguments:
|
|
* <TypeArguments+>
|
|
*
|
|
* @author sjfink
|
|
*
|
|
*/
|
|
public class ClassTypeSignature extends TypeSignature {
|
|
|
|
ClassTypeSignature(String s) throws IllegalArgumentException {
|
|
super(s);
|
|
if (s.length() == 0) {
|
|
throw new IllegalArgumentException();
|
|
}
|
|
if (s.charAt(0) != 'L') {
|
|
throw new IllegalArgumentException(s);
|
|
}
|
|
if (s.charAt(s.length()-1) != ';') {
|
|
throw new IllegalArgumentException(s);
|
|
}
|
|
}
|
|
|
|
public static ClassTypeSignature makeClassTypeSig(String s) throws IllegalArgumentException {
|
|
if (s == null) {
|
|
throw new IllegalArgumentException("s is null");
|
|
}
|
|
return new ClassTypeSignature(s);
|
|
}
|
|
|
|
@Override
|
|
public boolean isTypeVariable() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public boolean isClassTypeSignature() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean isArrayTypeSignature() {
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Return the name of the raw type for this signature
|
|
*/
|
|
public TypeName getRawName() {
|
|
// note: need to handle type arguments for raw signatures like the following:
|
|
// Ljava/util/IdentityHashMap<TK;TV;>.IdentityHashMapIterator<TV;>;
|
|
StringBuffer s = new StringBuffer();
|
|
StringTokenizer t = new StringTokenizer(rawString(),".");
|
|
while (t.hasMoreTokens()) {
|
|
String x = t.nextToken();
|
|
s.append(x.replaceAll("<.*>","").replace(";",""));
|
|
if (t.hasMoreElements()) {
|
|
// note that '$' is the canonical separator for inner class names
|
|
s.append('$');
|
|
}
|
|
}
|
|
return TypeName.string2TypeName(s.toString());
|
|
}
|
|
|
|
public TypeArgument[] getTypeArguments() {
|
|
// note: need to handle type arguments for raw signatures like the following:
|
|
// Ljava/util/IdentityHashMap<TK;TV;>.IdentityHashMapIterator<TV;>;
|
|
int lastDot = rawString().lastIndexOf('.');
|
|
if (rawString().indexOf('<',lastDot) == -1) {
|
|
return null;
|
|
} else {
|
|
int start = rawString().indexOf('<',lastDot);
|
|
int end = endOfTypeArguments();
|
|
return TypeArgument.make(rawString().substring(start,end));
|
|
}
|
|
}
|
|
|
|
private int endOfTypeArguments() {
|
|
// note: need to handle type arguments for raw signatures like the following:
|
|
// Ljava/util/IdentityHashMap<TK;TV;>.IdentityHashMapIterator<TV;>;
|
|
int lastDot = rawString().lastIndexOf('.');
|
|
int i = rawString().indexOf('<',lastDot) + 1;
|
|
assert (i > 0);
|
|
int depth = 1;
|
|
while (depth > 0) {
|
|
if (rawString().charAt(i) == '>') {
|
|
depth--;
|
|
}
|
|
if (rawString().charAt(i) == '<') {
|
|
depth++;
|
|
}
|
|
i++;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
@Override
|
|
public boolean isBaseType() {
|
|
return false;
|
|
}
|
|
|
|
public static IClass lookupClass(IClassHierarchy cha, ClassTypeSignature sig) {
|
|
if (sig == null) {
|
|
throw new IllegalArgumentException("sig is null");
|
|
}
|
|
if (cha == null) {
|
|
throw new IllegalArgumentException("cha is null");
|
|
}
|
|
TypeReference t = TypeReference.findOrCreate(ClassLoaderReference.Application, sig.getRawName());
|
|
return cha.lookupClass(t);
|
|
}
|
|
|
|
}
|