Java源码示例:com.strobel.assembler.metadata.TypeDefinition
示例1
private boolean allImplementationsDerivedFromSubclass(Hierarchy h, TypeReference superClass,
TypeReference subClass) {
TypeDefinition td = superClass.resolve();
if(td == null || (!td.isInterface() && !Flags.testAny(td.getFlags(), Flags.ABSTRACT)) )
return false;
for(TypeHierarchy th : h.get(td).getSubClasses()) {
if(subClass.getInternalName().equals(th.getInternalName()))
continue;
if(th.hasFlag(Flags.INTERFACE) || th.hasFlag(Flags.ABSTRACT))
continue;
TypeReference subType = td.getResolver().lookupType(th.getInternalName());
if(subType == null || Types.isInstance(subType, subClass))
continue;
return false;
}
return true;
}
示例2
@AstVisitor
public void visit(Node node, MethodContext mc, TypeHierarchy th, TypeDefinition td) {
if(node instanceof TryCatchBlock) {
Expression syncObject = Nodes.getSyncObject((TryCatchBlock) node);
if(syncObject != null) {
if(syncObject.getCode() == AstCode.InvokeVirtual && Methods.isGetClass((MethodReference) syncObject.getOperand())
&& Exprs.isThis(Exprs.getChild(syncObject, 0))) {
int priority = 0;
if(th != null && !th.hasSubClasses())
priority += 10;
if(Nodes.find(node, n -> isStaticFieldAccess(n, td)) == null)
priority += 15;
mc.report("SyncOnGetClass", priority, syncObject);
}
}
}
}
示例3
@AstVisitor(nodes = AstNodes.EXPRESSIONS)
public void visit(Expression expr, MethodContext mc) {
if (expr.getCode() != AstCode.InvokeVirtual)
return;
MethodReference mr = (MethodReference) expr.getOperand();
String name = mr.getName();
if (!Types.isObject(mr.getDeclaringType()) || (!name.equals("wait") && !name.startsWith("notify")))
return;
TypeReference type = ValuesFlow.reduceType(expr.getArguments().get(0));
if (type == null || !type.getInternalName().startsWith("java/util/concurrent/"))
return;
TypeDefinition target = type.resolve();
if (target == null || !target.isPublic())
return;
MethodDefinition replacement = findReplacement(name, target);
if(replacement != null) {
mc.report("IncorrectConcurrentMethod", 0, expr, TARGET.create(target), Roles.REPLACEMENT_METHOD.create(replacement));
}
}
示例4
@ClassVisitor
public void visitClass(TypeDefinition td, ClassContext cc) {
isSerializable = Types.isInstance(td, "java/io/Serializable");
if(Types.isInstance(td, "java/util/Comparator") && !td.isAnonymous() && !td.isLocalClass()
&& !isSerializable) {
int priority = 0;
for(FieldDefinition fd : td.getDeclaredFields()) {
TypeReference fieldType = fd.getFieldType();
while(fieldType.isArray())
fieldType = fieldType.getElementType();
if(fieldType.isPrimitive())
continue;
if(Types.isInstance(fieldType, "java/io/Serializable")) {
priority+=10;
if(priority > 20)
break;
}
}
cc.report("ComparatorIsNotSerializable", priority, SHOULD_IMPLEMENT.create("java/io/Serializable"));
}
}
示例5
@ClassVisitor
public void visitClass(TypeDefinition td, ClassContext cc) {
if (td.isAnonymous() || td.isSynthetic())
return;
String name = td.getSimpleName();
if (Character.isLetter(name.charAt(0)) && !Character.isUpperCase(name.charAt(0)) && name.indexOf('_') == -1) {
cc.report("BadNameOfClass", td.isPublic() ? 0 : 15);
}
if (name.endsWith("Exception") && !Types.isInstance(td, "java/lang/Throwable")) {
cc.report("BadNameOfClassException", td.isPublic() ? 0 : 15);
}
TypeReference superClass = td.getBaseType();
if (superClass != null && superClass.getSimpleName().equals(name)) {
cc.report("BadNameOfClassSameAsSuperclass", td.isPublic() ? 0 : 15, Roles.SUPERCLASS.create(superClass));
}
for (TypeReference iface : td.getExplicitInterfaces()) {
if (iface.getSimpleName().equals(name)) {
cc.report("BadNameOfClassSameAsInterface", td.isPublic() ? 0 : 15, Roles.INTERFACE.create(iface));
}
}
}
示例6
@AstVisitor(nodes = AstNodes.ROOT)
public void checkSameAsConstructor(Block root, MethodDefinition md, TypeDefinition td, MethodContext mc) {
if (md.getName().equals(td.getSimpleName()) && md.getReturnType().isVoid() && !md.isDeprecated()) {
int priority = 0;
if (root.getBody().isEmpty()) {
priority += 20;
} else if (root.getBody().size() == 1 && Nodes.isOp(root.getBody().get(0), AstCode.AThrow)) {
priority += 40;
}
if (td.getDeclaredMethods().stream().anyMatch(
m -> m.isConstructor() && m.getErasedSignature().equals(md.getErasedSignature()))) {
priority += 10;
}
mc.report("BadNameOfMethodSameAsConstructor", priority);
}
}
示例7
private boolean checkWrite(FieldContext fc, FieldDefinition fd, TypeDefinition td, FieldRecord fieldRecord, int flags, boolean isConstantType) {
if(!Flags.testAny(flags, FieldStats.WRITE)) {
if(fd.isStatic() && fd.isFinal() && isConstantType)
return false;
WarningAnnotation<?>[] anno = {};
int priority = 0;
String warningType = fd.isPublic() || fd.isProtected() ? "UnwrittenPublicField" : "UnwrittenPrivateField";
if (fieldRecord != null && fieldRecord.firstRead != null) {
anno = fieldRecord.firstRead.getAnnotations();
}
if(fd.isPublic()) {
priority += 5;
}
priority += tweakForSerialization(fd, td);
if(fd.getFieldType().getSimpleType() == JvmType.Boolean) {
priority += 5;
}
if(fd.getName().equalsIgnoreCase("debug")) {
priority += 5;
}
fc.report(warningType, priority, anno);
return true;
}
return false;
}
示例8
private boolean checkNull(FieldContext fc, FieldDefinition fd, TypeDefinition td, FieldRecord fieldRecord, int flags) {
if(!Flags.testAny(flags, FieldStats.WRITE_NONNULL) && Flags.testAny(flags, FieldStats.READ)) {
int priority = 0;
if(fd.isFinal() && fd.isStatic()) {
priority += 20;
String lcName = fd.getName().toLowerCase(Locale.ENGLISH);
if (lcName.contains("null") || lcName.contains("zero") || lcName.contains("empty")) {
priority += 15;
}
} else if(fd.isPublic()) {
priority += 10;
}
priority += tweakForSerialization(fd, td);
fc.report("FieldIsAlwaysNull", priority, getWriteAnnotations(fieldRecord));
return true;
}
return false;
}
示例9
private MethodDefinition findMethodInType(TypeDefinition typeDef, String uniqueStr) {
String[] linkParts = uniqueStr.split("\\|");
if (linkParts.length != 5)
return null;
String methodName = linkParts[3];
String methodErasedSignature = linkParts[4];
if (methodName.trim().length() <= 0 || methodErasedSignature.trim().length() <= 0)
return null;
List<MethodDefinition> declaredMethods = typeDef.getDeclaredMethods();
if (declaredMethods == null)
return null;
boolean isFound = false;
for (MethodDefinition declaredMethod : declaredMethods) {
isFound = (declaredMethod != null && methodName.equals(declaredMethod.getName()));
isFound = (isFound && methodErasedSignature.equals(declaredMethod.getErasedSignature()));
if (isFound) {
if (declaredMethod.isSynthetic() && !settings.getShowSyntheticMembers()) {
return null;
} else {
return declaredMethod;
}
}
}
return null;
}
示例10
@AstVisitor(nodes=AstNodes.EXPRESSIONS, methodName="<clinit>")
public void visit(Expression expr, NodeChain nc, MethodContext mc, TypeDefinition td) {
if(expr.getOperand() instanceof MemberReference) {
MemberReference mr = (MemberReference) expr.getOperand();
TypeReference tr = mr.getDeclaringType();
TypeDefinition subType = tr == null ? null : tr.resolve();
if (subType != null && (subType.isAnonymous() || subType.isLocalClass())) {
subType = subType.getBaseType().resolve();
}
if (subType != null && !td.isEquivalentTo(subType) && Types.isInstance(subType, td) && nc
.getLambdaMethod() == null) {
mc.report("InitializerRefersSubclass", td.isNonPublic() || subType.isNonPublic() ? 5 : 0, expr,
Roles.SUBCLASS.create(subType));
}
}
}
示例11
@AstVisitor(nodes = AstNodes.EXPRESSIONS)
public void visit(Expression expr, NodeChain nc, MethodContext mc, MethodDefinition md, TypeDefinition td) {
if (expr.getCode() == AstCode.Return && !expr.getArguments().isEmpty()) {
Expression child = Exprs.getChild(expr, 0);
if (child.getCode() == AstCode.AConstNull) {
MethodDefinition curMethod = nc.getLambdaMethod();
if (curMethod == null)
curMethod = md;
String warningType = curMethod.getReturnType().isArray() ? "ArrayReturnNull" : TYPE_TO_WARNING
.get(curMethod.getReturnType().getInternalName());
if (warningType != null) {
int priority = 0;
if (!td.isPublic() || md.isPrivate() || md.isPackagePrivate())
priority = 20;
else if (md.isProtected() || md != curMethod)
priority = 10;
// Method which simply contains "return null": probably stub or something
if(nc.getParent() == null && nc.isOnlyChild(expr))
priority += 10;
mc.report(warningType, priority, expr.getArguments().get(0), RETURN_TYPE.create(md
.getReturnType()));
}
}
}
}
示例12
static EType of(TypeReference tr, What what) {
if (tr == null || tr.isPrimitive() || (what == What.SUBTYPE && Types.isObject(tr)))
return UNKNOWN;
TypeDefinition td = tr.resolve();
if (td == null)
return UNKNOWN;
if (td.isFinal() || td.isPrimitive()) {
if (what == What.SUBTYPE)
what = What.EXACT;
if (what == What.NOT)
what = What.NOT_SUBTYPE;
}
TypeReference newTr = td;
while (tr.isArray()) {
tr = tr.getElementType();
newTr = newTr.makeArrayType();
}
boolean complete = Types.hasCompleteHierarchy(td);
return new SingleType(newTr, what, complete);
}
示例13
@Override
protected void visitType(TypeDefinition td) {
if (!td.isAnnotation())
return;
DeclaredAnnotation da = getOrCreate(td);
for (CustomAnnotation ca : td.getAnnotations()) {
if (Types.is(ca.getAnnotationType(), Retention.class)) {
for (AnnotationParameter ap : ca.getParameters()) {
if (ap.getMember().equals("value")) {
AnnotationElement value = ap.getValue();
if (value instanceof EnumAnnotationElement) {
EnumAnnotationElement enumValue = (EnumAnnotationElement) value;
if (Types.is(enumValue.getEnumType(), RetentionPolicy.class)) {
da.policy = RetentionPolicy.valueOf(enumValue.getEnumConstantName());
}
}
}
}
}
}
}
示例14
MetadataSystem createMetadataSystem() {
return new MetadataSystem(loader) {
Set<String> loadedTypes = new HashSet<>();
@Override
protected TypeDefinition resolveType(String descriptor, boolean mightBePrimitive) {
if(missingClasses.contains(descriptor)) {
return null;
}
try {
if(loadedTypes.add(descriptor))
incStat("ClassLoadingEfficiency.Total");
if(classes.add(descriptor))
incStat("ClassLoadingEfficiency");
return super.resolveType(descriptor, mightBePrimitive);
} catch (Throwable t) {
addError(new ErrorMessage(null, descriptor, null, null, -1, t));
missingClasses.add(descriptor);
return null;
}
}
};
}
示例15
public static boolean isInstance(TypeReference type, String wantedType) {
if (type == null || type.isPrimitive())
return false;
if (wantedType.equals("java/lang/Object"))
return true;
if (type.getInternalName().equals(wantedType))
return true;
if (type.isArray()) {
if(!wantedType.startsWith("["))
return false;
return isInstance(type.getElementType(), wantedType.substring(1));
}
TypeDefinition td = type.resolve();
if (td == null)
return false;
for (TypeReference iface : td.getExplicitInterfaces()) {
if (isInstance(iface, wantedType))
return true;
}
TypeReference bt = td.getBaseType();
if (bt == null)
return false;
return isInstance(bt, wantedType);
}
示例16
private FieldDefinition findFieldInType(TypeDefinition typeDef, String uniqueStr) {
String[] linkParts = uniqueStr.split("\\|");
if (linkParts.length != 4)
return null;
String fieldName = linkParts[3];
if (fieldName.trim().length() <= 0)
return null;
List<FieldDefinition> declaredFields = typeDef.getDeclaredFields();
if (declaredFields == null)
return null;
boolean isFound = false;
for (FieldDefinition declaredField : declaredFields) {
isFound = (declaredField != null && fieldName.equals(declaredField.getName()));
if (isFound) {
if (declaredField.isSynthetic()) {
return null;
} else {
return declaredField;
}
}
}
return null;
}
示例17
private TypeReference getMostOuterTypeRefBySlowLookuping(TypeReference typeRef) {
String name = typeRef.getName();
if (name == null)
return typeRef;
String packageName = typeRef.getPackageName();
if (packageName == null)
return typeRef;
String[] nameParts = name.split("\\$");
String newName = "";
String sep = "";
for (int i = 0; i < nameParts.length - 1; i++) {
newName = newName + sep + nameParts[i];
sep = "$";
String newInternalName = packageName.replaceAll("\\.", "/") + "/" + newName;
TypeReference newTypeRef = metadataSystem.lookupType(newInternalName);
if (newTypeRef != null) {
TypeDefinition newTypeDef = newTypeRef.resolve();
if (newTypeDef != null) {
return newTypeRef;
}
}
}
return typeRef;
}
示例18
@MethodVisitor
public void visit(MethodContext mc, MethodDefinition md, TypeDefinition td) {
TypeReference returnType = md.getReturnType();
if (Types.isCollection(returnType)) {
mc.report("SampleCustomDetector", 5);
}
}
示例19
private static int getPriority(TypeDefinition td) {
int priority = 0;
if (td.isNonPublic())
priority += 30;
if (td.isFinal())
priority += 5;
return priority;
}
示例20
@AstVisitor(nodes=AstNodes.EXPRESSIONS)
public void visit(Expression expr, NodeChain nc, MethodContext mc, MethodDefinition md, TypeDefinition td) {
if(expr.getCode() == AstCode.PutStatic) {
FieldReference fr = (FieldReference) expr.getOperand();
FieldDefinition fd = fr.resolve();
if(fd != null && fd.isSynthetic())
return;
int priority = 0;
if(md.isPrivate() || td.isPrivate())
priority += 20;
else if(!md.isPublic() || !td.isPublic())
priority += 10;
else if(md.isConstructor())
priority += 5;
if(nc.isSynchronized() || Flags.testAny(md.getFlags(), Flags.SYNCHRONIZED))
priority += 15;
if(Exprs.getChild(expr, 0).getCode() == AstCode.AConstNull)
priority += 5;
String name = fr.getName().toLowerCase(Locale.ENGLISH);
if (fr.getFieldType().getSimpleType() == JvmType.Boolean) {
priority += 10;
if (name.contains("verbose"))
priority += 5;
}
if (name.contains("debug"))
priority += 15;
if ((md.getName().equals("start") || md.getName().equals("stop")) && md.getErasedSignature().equals(
"(Lorg/osgi/framework/BundleContext;)V") && Types.isInstance(td,
"org/osgi/framework/BundleActivator")) {
priority += 30;
}
mc.report("StaticFieldFromInstanceMethod", priority, expr);
}
}
示例21
private static MethodDefinition findReplacement(String name, TypeDefinition target) {
for (MethodDefinition md : target.getDeclaredMethods()) {
if (!md.isPublic() || !md.getSignature().equals("()V"))
continue;
if (name.equals("wait") && md.getName().equals("await"))
return md;
if (name.equals("notify") && (md.getName().equals("signal") || md.getName().equals("countDown")))
return md;
if (name.equals("notifyAll") && (md.getName().equals("signalAll") || md.getName().equals("countDown")))
return md;
}
return null;
}
示例22
@MethodVisitor
public boolean check(MethodDefinition md, TypeDefinition td) {
// Skip some autogenerated methods
if(md.getName().equals("yyparse") && md.getReturnType().getInternalName().equals("java/lang/Object"))
return false;
if(md.getName().startsWith("jj") && td.getName().endsWith("TokenManager"))
return false;
if(md.getName().equals("getNextToken") && md.getSignature().equals("()I"))
return false;
return true;
}
示例23
@MethodVisitor
public void visitMethod(MethodDefinition md, MethodContext mc, TypeDefinition td) {
if(isSerializable) {
switch(md.getName()) {
case "readResolve":
if(md.getSignature().startsWith("()")) {
if(!md.getSignature().equals("()Ljava/lang/Object;")) {
mc.report("ReadResolveMustReturnObject", 0);
} else if(md.isStatic()) {
mc.report("ReadResolveIsStatic", 0);
}
}
break;
case "readObject":
if(md.getSignature().equals("(Ljava/io/ObjectInputStream;)V")) {
if(!md.isPrivate())
mc.report("SerializationMethodMustBePrivate", 0);
if(Flags.testAny(md.getFlags(), Flags.SYNCHRONIZED))
mc.report("ReadObjectIsSynchronized", 0);
}
break;
case "readObjectNoData":
if(md.getSignature().equals("()V") && !md.isPrivate())
mc.report("SerializationMethodMustBePrivate", 0);
break;
case "writeObject":
if(md.getSignature().equals("(Ljava/io/ObjectOutputStream;)V")) {
if(!md.isPrivate())
mc.report("SerializationMethodMustBePrivate", 0);
if(Flags.testAny(md.getFlags(), Flags.SYNCHRONIZED) &&
td.getDeclaredMethods().stream().noneMatch(m -> m != md &&
Flags.testAny(m.getFlags(), Flags.SYNCHRONIZED)))
mc.report("WriteObjectIsSynchronized", 0);
}
break;
}
}
}
示例24
@MethodVisitor
public void visitMethod(MethodDefinition md, TypeDefinition td, MethodContext mc) {
if (badMethodName(md.getName())) {
if (Types.isInstance(td, "org/eclipse/osgi/util/NLS"))
return;
// javacc generated methods
if (td.getName().equals("SimpleCharStream")
&& (md.getName().equals("ReInit") || md.getName().equals("BeginToken") || md.getName().equals("Done")
|| md.getName().equals("GetSuffix") || md.getName().equals("GetImage")))
return;
if (td.getName().endsWith("TokenManager") && md.getName().equals("ReInit"))
return;
int priority = 0;
if (!td.isPublic())
priority += 20;
else {
if (td.isFinal())
priority += 3;
if (md.isProtected())
priority += 3;
else if (md.isPackagePrivate())
priority += 6;
else if (md.isPrivate())
priority += 10;
}
mc.report("BadNameOfMethod", priority);
}
String javaVersion = getFutureKeywordVersion(md.getName());
if (javaVersion != null) {
mc.report("BadNameOfMethodFutureKeyword", AccessLevel.of(md).select(0, 10, 20, 30), JAVA_VERSION.create(javaVersion));
}
if (!md.isStatic() && md.isPublic()) {
MemberInfo mi = getMistakeFix(md);
if (mi != null) {
mc.report("BadNameOfMethodMistake", md.isDeprecated() ? 20 : 0, Roles.REPLACEMENT_METHOD.create(mi));
}
}
}
示例25
private int tweakForSerialization(FieldDefinition fd, TypeDefinition td) {
// Probably field is kept for backwards serialization compatibility
if(!fd.isStatic() && Types.isInstance(td, "java/io/Serializable")) {
return 10;
}
if(Flags.testAny(fd.getFlags(), Flags.TRANSIENT)) {
return 30;
}
return 0;
}
示例26
@AstVisitor(nodes = AstNodes.EXPRESSIONS, methodName = "hasNext", methodSignature = "()Z")
public void visitHasNext(Expression expr, MethodContext mc, TypeDefinition td) {
if (expr.getCode() == AstCode.InvokeVirtual) {
MethodReference mr = (MethodReference) expr.getOperand();
if (mr.getName().equals("next") && mr.getParameters().isEmpty() && Exprs.isThis(Exprs.getChild(expr, 0))) {
mc.report("IteratorHasNextCallsNext", td.isPublic() ? 0 : 30, expr);
}
}
}
示例27
@AstVisitor(nodes = AstNodes.ROOT, methodName = "next")
public void visitNext(Block body, MethodContext mc, MethodDefinition md, TypeDefinition td) {
if (md.getErasedSignature().startsWith("()")) {
AtomicBoolean sawCall = new AtomicBoolean();
Node found = Nodes.find(body, n -> {
if (Nodes.isOp(n, AstCode.AThrow)) {
Expression exc = (Expression) Nodes.getChild(n, 0);
if (Types.is(exc.getInferredType(), NoSuchElementException.class))
return true;
}
if (n instanceof Expression) {
Expression expr = (Expression) n;
if (expr.getCode() == AstCode.InvokeSpecial || expr.getCode() == AstCode.InvokeInterface
|| expr.getCode() == AstCode.InvokeVirtual) {
MethodReference mr = (MethodReference) expr.getOperand();
if (Exprs.isThis(Exprs.getChild(expr, 0)) || mr.getName().contains("next") || mr.getName().contains("previous"))
return true;
if (!sawCall.get() && !Inf.PURITY.isSideEffectFree(expr)) {
sawCall.set(true);
}
}
}
return false;
});
if (found != null)
return;
int priority = 0;
if(td.isNonPublic())
priority += 5;
if(sawCall.get())
priority += 30;
mc.report("IteratorNoThrow", priority, body);
}
}
示例28
@FieldVisitor
public void visitField(FieldDefinition fd, FieldContext fc, TypeDefinition td) {
if((fd.isPublic() || fd.isProtected()) && (td.isPublic() || td.isProtected()) &&
fd.isStatic() && !fd.isEnumConstant()) {
TypeReference fieldType = fd.getFieldType();
if(!isNotThreadSafe(fieldType))
return;
fc.report("StaticNotThreadSafeField", AccessLevel.of(fd).select(0, 20, 100, 100),
Roles.FIELD_TYPE.create(fieldType));
}
}
示例29
@AstVisitor(nodes=AstNodes.EXPRESSIONS)
public void visitCall(MethodContext mc, Expression expr, MethodDefinition md, NodeChain nc, TypeDefinition td) {
if(expr.getCode() == AstCode.InvokeVirtual) {
Expression target = expr.getArguments().get(0);
if(target.getCode() != AstCode.GetStatic) {
target = Exprs.getChild(expr, 0);
}
if(target.getCode() == AstCode.GetStatic) {
FieldReference fr = (FieldReference) target.getOperand();
if(md.isTypeInitializer() && td.isEquivalentTo(fr.getDeclaringType()))
return;
MethodReference mr = (MethodReference) expr.getOperand();
String methodName = mr.getName();
if(methodName.startsWith("get"))
return;
if(nc.isSynchronized() || Flags.testAny(md.getFlags(), Flags.SYNCHRONIZED))
return;
if(!isNotThreadSafe(mr.getDeclaringType()))
return;
int priority = 0;
if(Methods.isMain(md))
priority += 30;
if(!methodName.startsWith("set") && !DANGEROUS_METHODS.contains(methodName))
priority += 20;
mc.report("StaticNotThreadSafeFieldInvoke", priority, expr, Roles.FIELD.create(fr));
}
}
}
示例30
@ClassVisitor
public boolean checkClass(TypeDefinition td) {
for(CustomAnnotation ca : td.getAnnotations()) {
String name = ca.getAnnotationType().getInternalName();
if(name.equals("net/jcip/annotations/Immutable") || name.equals("javax/annotation/concurrent/Immutable"))
return true;
}
return false;
}