public static @CheckForNull LocalVariableAnnotation findUniqueBestMatchingParameter( ClassContext classContext, Method method, String name, String signature) { LocalVariableAnnotation match = null; int localsThatAreParameters = PreorderVisitor.getNumberArguments(method.getSignature()); int startIndex = 0; if (!method.isStatic()) startIndex = 1; SignatureParser parser = new SignatureParser(method.getSignature()); Iterator<String> signatureIterator = parser.parameterSignatureIterator(); int lowestCost = Integer.MAX_VALUE; for (int i = startIndex; i < localsThatAreParameters + startIndex; i++) { String sig = signatureIterator.next(); if (signature.equals(sig)) { LocalVariableAnnotation potentialMatch = LocalVariableAnnotation.getLocalVariableAnnotation(method, i, 0, 0); if (!potentialMatch.isNamed()) continue; int distance = EditDistance.editDistance(name, potentialMatch.getName()); if (distance < lowestCost) { match = potentialMatch; match.setDescription(DID_YOU_MEAN_ROLE); lowestCost = distance; } else if (distance == lowestCost) { // not unique best match match = null; } // signatures match } } if (lowestCost < 5) return match; return null; }
public static @CheckForNull LocalVariableAnnotation findMatchingIgnoredParameter( ClassContext classContext, Method method, String name, String signature) { try { Dataflow<BitSet, LiveLocalStoreAnalysis> llsaDataflow = classContext.getLiveLocalStoreDataflow(method); CFG cfg; cfg = classContext.getCFG(method); LocalVariableAnnotation match = null; int lowestCost = Integer.MAX_VALUE; BitSet liveStoreSetAtEntry = llsaDataflow.getAnalysis().getResultFact(cfg.getEntry()); int localsThatAreParameters = PreorderVisitor.getNumberArguments(method.getSignature()); int startIndex = 0; if (!method.isStatic()) startIndex = 1; SignatureParser parser = new SignatureParser(method.getSignature()); Iterator<String> signatureIterator = parser.parameterSignatureIterator(); for (int i = startIndex; i < localsThatAreParameters + startIndex; i++) { String sig = signatureIterator.next(); if (!liveStoreSetAtEntry.get(i) && signature.equals(sig)) { // parameter isn't live and signatures match LocalVariableAnnotation potentialMatch = LocalVariableAnnotation.getLocalVariableAnnotation(method, i, 0, 0); potentialMatch.setDescription(DID_YOU_MEAN_ROLE); if (!potentialMatch.isNamed()) return potentialMatch; int distance = EditDistance.editDistance(name, potentialMatch.getName()); if (distance < lowestCost) { match = potentialMatch; match.setDescription(DID_YOU_MEAN_ROLE); lowestCost = distance; } else if (distance == lowestCost) { // not unique best match match = null; } } } return match; } catch (DataflowAnalysisException e) { AnalysisContext.logError("", e); } catch (CFGBuilderException e) { AnalysisContext.logError("", e); } return null; }
public void visitClassContext(ClassContext classContext) { JavaClass jclass = classContext.getJavaClass(); for (Method method : jclass.getMethods()) { XMethod xmethod = XFactory.createXMethod(classContext.getJavaClass(), method); ParameterProperty nonnullParameters = AnalysisContext.currentAnalysisContext() .getUnconditionalDerefParamDatabase() .getProperty(xmethod.getMethodDescriptor()); if (nonnullParameters != null) { for (int p : nonnullParameters.iterable()) { TypeQualifierAnnotation directTypeQualifierAnnotation = TypeQualifierApplications.getDirectTypeQualifierAnnotation( xmethod, p, nonnullTypeQualifierValue); if (directTypeQualifierAnnotation != null && directTypeQualifierAnnotation.when == When.UNKNOWN) { // // The LocalVariableAnnotation is constructed using the local variable // number of the parameter, not the parameter number. // int paramLocal = xmethod.isStatic() ? p : p + 1; reporter.reportBug( new BugInstance( this, "NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE", NORMAL_PRIORITY) .addClassAndMethod(jclass, method) .add( LocalVariableAnnotation.getParameterLocalVariableAnnotation( method, paramLocal))); } } } } }