/*
* Bytecode Analysis Framework
* Copyright (C) 2005, University of Maryland
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package edu.umd.cs.findbugs.ba;
import org.apache.bcel.Constants;
import edu.umd.cs.findbugs.classfile.ClassDescriptor;
import edu.umd.cs.findbugs.classfile.DescriptorFactory;
import edu.umd.cs.findbugs.internalAnnotations.DottedClassName;
public abstract class AbstractClassMember implements ClassMember {
private final @DottedClassName
String className;
private final String name;
private final String signature;
private final int accessFlags;
private boolean resolved;
private int cachedHashCode = 0;
static int slashCountClass = 0;
static int dottedCountClass = 0;
static int slashCountSignature = 0;
static int dottedCountSignature = 0;
protected AbstractClassMember(@DottedClassName String className, String name, String signature, int accessFlags) {
if (className.indexOf('.') >= 0) {
// className = className.replace('.','/');
dottedCountClass++;
} else if (className.indexOf('/') >= 0) {
assert false;
slashCountClass++;
className = className.replace('/', '.');
}
if (signature.indexOf('.') >= 0) {
assert false;
signature = signature.replace('.', '/');
dottedCountSignature++;
} else if (signature.indexOf('/') >= 0)
slashCountSignature++;
this.className = DescriptorFactory.canonicalizeString(className);
this.name = DescriptorFactory.canonicalizeString(name);
this.signature = DescriptorFactory.canonicalizeString(signature);
this.accessFlags = accessFlags;
}
public @DottedClassName
String getClassName() {
return className;
}
/*
* (non-Javadoc)
*
* @see edu.umd.cs.findbugs.ba.AccessibleEntity#getClassDescriptor()
*/
public ClassDescriptor getClassDescriptor() {
return DescriptorFactory.instance().getClassDescriptorForDottedClassName(className);
}
public String getName() {
return name;
}
public @DottedClassName
String getPackageName() {
int lastDot = className.lastIndexOf('.');
if (lastDot == -1)
return className;
return className.substring(0, lastDot);
}
public String getSignature() {
return signature;
}
public boolean isReferenceType() {
return signature.startsWith("L") || signature.startsWith("[");
}
public int getAccessFlags() {
return accessFlags;
}
public boolean isStatic() {
return (accessFlags & Constants.ACC_STATIC) != 0;
}
public boolean isFinal() {
return (accessFlags & Constants.ACC_FINAL) != 0;
}
public boolean isPublic() {
return (accessFlags & Constants.ACC_PUBLIC) != 0;
}
public boolean isProtected() {
return (accessFlags & Constants.ACC_PROTECTED) != 0;
}
public boolean isPrivate() {
return (accessFlags & Constants.ACC_PRIVATE) != 0;
}
// public int compareTo(ClassMember other) {
// // This may be compared to any kind of PackageMember object.
// // If the other object is a different kind of field,
// // just compare class names.
// if (this.getClass() != other.getClass())
// return this.getClass().getName().compareTo(other.getClass().getName());
//
// int cmp;
// cmp = className.compareTo(other.getClassName());
// if (cmp != 0)
// return cmp;
// cmp = name.compareTo(other.getName());
// if (cmp != 0)
// return cmp;
// return signature.compareTo(other.getSignature());
// }
// public int compareTo(FieldOrMethodName other) {
//
// int cmp = getClassDescriptor().compareTo(other.getClassDescriptor());
// if (cmp != 0)
// return cmp;
// cmp = name.compareTo(other.getName());
// if (cmp != 0)
// return cmp;
// cmp = signature.compareTo(other.getSignature());
// if (cmp != 0)
// return cmp;
// return (this.isStatic() ? 1 : 0) - (other.isStatic() ? 1 : 0);
// }
// public int compareTo(Object other) {
// return compareTo((FieldOrMethodName) other);
// }
public boolean isResolved() {
return resolved;
}
void markAsResolved() {
resolved = true;
}
@Override
public int hashCode() {
if (cachedHashCode == 0) {
cachedHashCode = className.hashCode() ^ name.hashCode() ^ signature.hashCode();
}
return cachedHashCode;
}
@Override
public boolean equals(Object o) {
if (o == null || this.getClass() != o.getClass())
return false;
AbstractClassMember other = (AbstractClassMember) o;
return className.equals(other.className) && name.equals(other.name) && signature.equals(other.signature);
}
@Override
public String toString() {
return className + "." + name;
}
}