@CheckForNull @Override public NullnessAnnotation getResolvedAnnotation(final Object o, boolean getMinimal) { Profiler profiler = Global.getAnalysisCache().getProfiler(); profiler.start(this.getClass()); try { if (o instanceof XMethodParameter) { XMethodParameter mp = (XMethodParameter) o; XMethod m = mp.getMethod(); // TODO: Handle argument to equals specially: generate special // bug code for it int parameterNumber = mp.getParameterNumber(); if (parameterNumber == 0) { if (m.getName().equals("equals") && m.getSignature().equals("(Ljava/lang/Object;)Z") && !m.isStatic()) return NullnessAnnotation.CHECK_FOR_NULL; else if (m.getName().equals("main") && m.getSignature().equals("([Ljava/lang/String;)V") && m.isStatic() && m.isPublic()) return NullnessAnnotation.NONNULL; else if (assertsFirstParameterIsNonnull(m)) return NullnessAnnotation.NONNULL; else if (m.getName().equals("compareTo") && m.getSignature().endsWith(";)Z") && !m.isStatic()) return NullnessAnnotation.NONNULL; } } else if (o instanceof XMethod) { XMethod m = (XMethod) o; String name = m.getName(); String signature = m.getSignature(); if (!m.isStatic() && (name.equals("clone") && signature.equals("()Ljava/lang/Object;") || name.equals("toString") && signature.equals("()Ljava/lang/String;") || m.isPrivate() && name.equals("readResolve") && signature.equals("()Ljava/lang/Object;"))) { NullnessAnnotation result = super.getDirectAnnotation(m); if (result != null) return result; return NullnessAnnotation.NONNULL; } } else if (o instanceof XField) { XField f = (XField) o; if (f.getName().startsWith("this$")) return NullnessAnnotation.NONNULL; } NullnessAnnotation result = super.getResolvedAnnotation(o, getMinimal); return result; } finally { profiler.end(this.getClass()); } }
/** * Look up the field referenced by given FieldInstruction, returning it as an {@link XField * XField} object. * * @param fins the FieldInstruction * @param cpg the ConstantPoolGen used by the class containing the instruction * @return an XField object representing the field, or null if no such field could be found */ public static XField findXField(FieldInstruction fins, @NonNull ConstantPoolGen cpg) throws ClassNotFoundException { String className = fins.getClassName(cpg); String fieldName = fins.getFieldName(cpg); String fieldSig = fins.getSignature(cpg); boolean isStatic = (fins.getOpcode() == Constants.GETSTATIC || fins.getOpcode() == Constants.PUTSTATIC); XField xfield = findXField(className, fieldName, fieldSig, isStatic); short opcode = fins.getOpcode(); if (xfield != null && xfield.isResolved() && xfield.isStatic() == (opcode == Constants.GETSTATIC || opcode == Constants.PUTSTATIC)) return xfield; else return null; }
@Override public void close() { field.setName(this.name); field.setDisplayString(this.displayString); field.setDescription(this.description); }
@Override public String getHeading() { StringBuilder singleLineHeading = new StringBuilder(); if (isNotBlank(field.getDisplayString())) { singleLineHeading .append(field.getDisplayString()) .append("(") .append(field.getName()) .append(")"); } else { singleLineHeading.append(field.getName()); } if (isNotBlank(field.getDescription())) { singleLineHeading.append(" [").append(field.getDescription()).append("]"); } this.name = field.getName(); this.description = field.getDescription(); this.displayString = field.getDisplayString(); field.setName(null); field.setDescription(null); field.setDisplayString(null); this.heading = singleLineHeading.toString(); return singleLineHeading.toString() + ":"; }