/** * Factory method to create an unknown source line annotation. * * @param className * the class name * @param sourceFile * the source file name * @return the SourceLineAnnotation */ public static SourceLineAnnotation createUnknown(@DottedClassName String className, String sourceFile) { return createUnknown(className, sourceFile, -1, -1); }
public static SourceLineAnnotation fromRawData(String className, String sourceFile, int startLine, int endLine, int startPC, int endPC) { if (startLine == -1) { return createUnknown(className, sourceFile, startPC, endPC); } return new SourceLineAnnotation(className, sourceFile, startLine, endLine, startPC, endPC); }
/** * Factory method to create an unknown source line annotation. This doesn't * use the analysis context. * * @param className * the class name * @return the SourceLineAnnotation */ public static SourceLineAnnotation createReallyUnknown(@DottedClassName String className) { return createUnknown(className, SourceLineAnnotation.UNKNOWN_SOURCE_FILE, -1, -1); }
/** * Add a non-specific source line annotation. This will result in the entire * source file being displayed. * * @param className * the class name * @param sourceFile * the source file name * @return this object */ @Nonnull public BugInstance addUnknownSourceLine(String className, String sourceFile) { SourceLineAnnotation sourceLineAnnotation = SourceLineAnnotation.createUnknown(className, sourceFile); if (sourceLineAnnotation != null) { add(sourceLineAnnotation); } return this; }
/** * Factory method to create an unknown source line annotation. This variant * looks up the source filename automatically based on the class using best * effort. * * @param className * the class name * @return the SourceLineAnnotation */ public static SourceLineAnnotation createUnknown(@DottedClassName String className) { return createUnknown(className, AnalysisContext.currentAnalysisContext().lookupSourceFile(className), -1, -1); }
/** * Create a SourceLineAnnotation covering an entire method. * * @param javaClass * JavaClass containing the method * @param method * the method * @return a SourceLineAnnotation for the entire method */ public static SourceLineAnnotation forEntireMethod(JavaClass javaClass, @CheckForNull Method method) { String sourceFile = javaClass.getSourceFileName(); if (method == null) { return createUnknown(javaClass.getClassName(), sourceFile); } Code code = method.getCode(); LineNumberTable lineNumberTable = method.getLineNumberTable(); if (code == null || lineNumberTable == null) { return createUnknown(javaClass.getClassName(), sourceFile); } return forEntireMethod(javaClass.getClassName(), sourceFile, lineNumberTable, code.getLength()); }
return createUnknown(className, sourceFile, startPC, endPC);
/** * Factory method for creating a source line annotation describing the * source line number for a visited instruction. * * @param classContext * the ClassContext * @param methodGen * the MethodGen object representing the method * @param handle * the InstructionHandle containing the visited instruction * @return the SourceLineAnnotation, or null if we do not have line number * information for the instruction */ @Nonnull public static SourceLineAnnotation fromVisitedInstruction(ClassContext classContext, MethodGen methodGen, String sourceFile, @Nonnull InstructionHandle handle) { LineNumberTable table = methodGen.getLineNumberTable(methodGen.getConstantPool()); String className = methodGen.getClassName(); int bytecodeOffset = handle.getPosition(); if (table == null) { return createUnknown(className, sourceFile, bytecodeOffset, bytecodeOffset); } int lineNumber = table.getSourceLine(handle.getPosition()); return new SourceLineAnnotation(className, sourceFile, lineNumber, lineNumber, bytecodeOffset, bytecodeOffset); }
/** * Create a SourceLineAnnotation covering an entire method. * * @param className * name of the class the method is in * @param sourceFile * source file containing the method * @param lineNumberTable * the method's LineNumberTable * @param codeSize * size in bytes of the method's code * @return a SourceLineAnnotation covering the entire method */ public static SourceLineAnnotation forEntireMethod(@DottedClassName String className, String sourceFile, LineNumberTable lineNumberTable, int codeSize) { LineNumber[] table = lineNumberTable.getLineNumberTable(); if (table != null && table.length > 0) { LineNumber first = table[0]; LineNumber last = table[table.length - 1]; return new SourceLineAnnotation(className, sourceFile, first.getLineNumber(), last.getLineNumber(), 0, codeSize - 1); } else { return createUnknown(className, sourceFile, 0, codeSize - 1); } }
/** * Factory method for creating a source line annotation describing an entire * method. * * @param methodGen * the method being visited * @return the SourceLineAnnotation, or null if we do not have line number * information for the method */ public static SourceLineAnnotation fromVisitedMethod(MethodGen methodGen, String sourceFile) { LineNumberTable lineNumberTable = methodGen.getLineNumberTable(methodGen.getConstantPool()); String className = methodGen.getClassName(); int codeSize = methodGen.getInstructionList().getLength(); if (lineNumberTable == null) { return createUnknown(className, sourceFile, 0, codeSize - 1); } return forEntireMethod(className, sourceFile, lineNumberTable, codeSize); }
static SourceLineAnnotation getSourceAnnotationForClass(String className, String sourceFileName) { int lastLine = -1; int firstLine = Integer.MAX_VALUE; try { JavaClass targetClass = AnalysisContext.currentAnalysisContext().lookupClass(className); for (Method m : targetClass.getMethods()) { Code c = m.getCode(); if (c != null) { LineNumberTable table = c.getLineNumberTable(); if (table != null) { for (LineNumber line : table.getLineNumberTable()) { lastLine = Math.max(lastLine, line.getLineNumber()); firstLine = Math.min(firstLine, line.getLineNumber()); } } } } } catch (ClassNotFoundException e) { AnalysisContext.reportMissingClass(e); } if (firstLine < Integer.MAX_VALUE) { return new SourceLineAnnotation(className, sourceFileName, firstLine, lastLine, -1, -1); } return SourceLineAnnotation.createUnknown(className, sourceFileName); }
/** * Create from Method and bytecode offset in a visited class. * * @param jclass * JavaClass of visited class * @param method * Method in visited class * @param pc * bytecode offset in visited method * @return SourceLineAnnotation describing visited instruction */ public static SourceLineAnnotation fromVisitedInstruction(JavaClass jclass, Method method, int pc) { LineNumberTable lineNumberTable = method.getCode().getLineNumberTable(); String className = jclass.getClassName(); String sourceFile = jclass.getSourceFileName(); if (lineNumberTable == null) { return createUnknown(className, sourceFile, pc, pc); } int startLine = lineNumberTable.getSourceLine(pc); return new SourceLineAnnotation(className, sourceFile, startLine, startLine, pc, pc); }
/** * Create a SourceLineAnnotation covering an entire method. * * @param javaClass * JavaClass containing the method * @param xmethod * the method * @return a SourceLineAnnotation for the entire method */ public static SourceLineAnnotation forEntireMethod(JavaClass javaClass, XMethod xmethod) { JavaClassAndMethod m = Hierarchy.findMethod(javaClass, xmethod.getName(), xmethod.getSignature()); if (m == null) { return createUnknown(javaClass.getClassName(), javaClass.getSourceFileName()); } else { return forEntireMethod(javaClass, m.getMethod()); } }
/** * Factory method for creating a source line annotation describing the * source line numbers for a range of instructions in the method being * visited by the given visitor. * * @param visitor * a BetterVisitor which is visiting the method * @param startPC * the bytecode offset of the start instruction in the range * @param endPC * the bytecode offset of the end instruction in the range * @return the SourceLineAnnotation, or null if we do not have line number * information for the instruction */ public static SourceLineAnnotation fromVisitedInstructionRange(BytecodeScanningDetector visitor, int startPC, int endPC) { LineNumberTable lineNumberTable = getLineNumberTable(visitor); String className = visitor.getDottedClassName(); String sourceFile = visitor.getSourceFile(); if (lineNumberTable == null) { return createUnknown(className, sourceFile, startPC, endPC); } int startLine = lineNumberTable.getSourceLine(startPC); int endLine = lineNumberTable.getSourceLine(endPC); return new SourceLineAnnotation(className, sourceFile, startLine, endLine, startPC, endPC); }
/** * Factory method for creating a source line annotation describing the * source line numbers for a range of instruction in a method. * * @param classContext * theClassContext * @param methodGen * the method * @param start * the start instruction * @param end * the end instruction (inclusive) */ public static SourceLineAnnotation fromVisitedInstructionRange(ClassContext classContext, MethodGen methodGen, String sourceFile, InstructionHandle start, InstructionHandle end) { LineNumberTable lineNumberTable = methodGen.getLineNumberTable(methodGen.getConstantPool()); String className = methodGen.getClassName(); if (lineNumberTable == null) { return createUnknown(className, sourceFile, start.getPosition(), end.getPosition()); } int startLine = lineNumberTable.getSourceLine(start.getPosition()); int endLine = lineNumberTable.getSourceLine(end.getPosition()); return new SourceLineAnnotation(className, sourceFile, startLine, endLine, start.getPosition(), end.getPosition()); }
result = createUnknown(methodDescriptor.getClassDescriptor().toDottedClassName());
static SourceLineAnnotation getSourceAnnotationForMethod(String className, String methodName, String methodSig) { JavaClassAndMethod targetMethod = null; Code code = null; try { JavaClass targetClass = AnalysisContext.currentAnalysisContext().lookupClass(className); targetMethod = Hierarchy.findMethod(targetClass, methodName, methodSig); if (targetMethod != null) { Method method = targetMethod.getMethod(); if (method != null) { code = method.getCode(); } } } catch (ClassNotFoundException e) { AnalysisContext.reportMissingClass(e); } SourceInfoMap sourceInfoMap = AnalysisContext.currentAnalysisContext().getSourceInfoMap(); SourceInfoMap.SourceLineRange range = sourceInfoMap.getMethodLine(className, methodName, methodSig); if (range != null) { return new SourceLineAnnotation(className, AnalysisContext.currentAnalysisContext().lookupSourceFile(className), range.getStart(), range.getEnd(), 0, code == null ? -1 : code.getLength()); } if (sourceInfoMap.fallBackToClassfile() && targetMethod != null) { return forEntireMethod(targetMethod.getJavaClass(), targetMethod.getMethod()); } // If we couldn't find the source lines, // create an unknown source line annotation referencing // the class and source file. return createUnknown(className); }
@Test public void match() throws Exception { SourceMatcher sm = new SourceMatcher(fileName); // no source set: test incomplete data assertFalse(sm.match(bug)); bug.addClass("bla", null); assertFalse(sm.match(bug)); ClassAnnotation primaryClass = bug.getPrimaryClass(); primaryClass.setSourceLines(SourceLineAnnotation.createUnknown("bla", "")); assertFalse(sm.match(bug)); // set right source file primaryClass.setSourceLines(SourceLineAnnotation.createUnknown("bla", fileName)); // exact match assertTrue(sm.match(bug)); // regexp first part sm = new SourceMatcher("~bla.*"); assertTrue(sm.match(bug)); sm = new SourceMatcher("~blup.*"); assertFalse(sm.match(bug)); // regexp second part sm = new SourceMatcher("~.*\\.groovy"); assertTrue(sm.match(bug)); sm = new SourceMatcher("~.*\\.java"); assertFalse(sm.match(bug)); }
public static SourceLineAnnotation fromRawData(String className, String sourceFile, int startLine, int endLine, int startPC, int endPC) { if (startLine == -1) { return createUnknown(className, sourceFile, startPC, endPC); } return new SourceLineAnnotation(className, sourceFile, startLine, endLine, startPC, endPC); }
/** * Factory method to create an unknown source line annotation. This variant * looks up the source filename automatically based on the class using best * effort. * * @param className * the class name * @return the SourceLineAnnotation */ public static SourceLineAnnotation createUnknown(@DottedClassName String className) { return createUnknown(className, AnalysisContext.currentAnalysisContext().lookupSourceFile(className), -1, -1); }