/** * Scans the specified source {@linkplain CompilationUnit} for contributed API javadoc tags. Tags * on methods will have unresolved signatures. * * @param source the source file to scan for tags * @param description the API description to annotate with any new tag rules found * @param container optional class file container containing the class file for the given source * that can be used to resolve method signatures if required (for tags on methods). If not * provided (<code>null</code>), method signatures will be unresolved. * @param options a map of Java compiler options to use when creating the AST to scan or <code> * null</code> if default options should be used * @param monitor * @throws CoreException */ public void scan( CompilationUnit source, IApiDescription description, IApiTypeContainer container, Map options, IProgressMonitor monitor) throws CoreException { SubMonitor localmonitor = SubMonitor.convert(monitor, 2); ASTParser parser = ASTParser.newParser(AST.JLS3); InputStream inputStream = null; try { inputStream = source.getInputStream(); parser.setSource( Util.getInputStreamAsCharArray( inputStream, -1, System.getProperty("file.encoding"))); // $NON-NLS-1$ } catch (FileNotFoundException e) { throw new CoreException( new Status( IStatus.ERROR, ApiPlugin.PLUGIN_ID, MessageFormat.format( "Compilation unit source not found: {0}", new String[] {source.getName()}), e)); //$NON-NLS-1$ } catch (IOException e) { if (DEBUG) { System.err.println(source.getName()); } throw new CoreException( new Status( IStatus.ERROR, ApiPlugin.PLUGIN_ID, MessageFormat.format( "Error reading compilation unit: {0}", new String[] {source.getName()}), e)); //$NON-NLS-1$ } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { ApiPlugin.log(e); } } } Util.updateMonitor(localmonitor); Map loptions = options; if (loptions == null) { loptions = JavaCore.getOptions(); } loptions.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.ENABLED); parser.setCompilerOptions(loptions); org.eclipse.jdt.core.dom.CompilationUnit cunit = (org.eclipse.jdt.core.dom.CompilationUnit) parser.createAST(localmonitor.newChild(1)); Visitor visitor = new Visitor(description, container); cunit.accept(visitor); if (visitor.getException() != null) { throw visitor.getException(); } }
@Override public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("API problem: "); // $NON-NLS-1$ buffer .append(fResourcePath != null ? fResourcePath : "no path") .append("\n"); // $NON-NLS-1$//$NON-NLS-2$ buffer.append("\tseverity: "); // $NON-NLS-1$ buffer.append(Util.getSeverity(getSeverity())).append("\n"); // $NON-NLS-1$ buffer.append("\tcategory: "); // $NON-NLS-1$ buffer.append(ApiProblem.getProblemCategory(getCategory())).append("\n"); // $NON-NLS-1$ buffer.append("\telement kind: "); // $NON-NLS-1$ buffer .append(ApiProblem.getProblemElementKind(getCategory(), getElementKind())) .append("\n"); // $NON-NLS-1$ buffer.append("\tkind: "); // $NON-NLS-1$ buffer.append(ApiProblem.getProblemKind(getCategory(), getKind())).append("\n"); // $NON-NLS-1$ buffer.append("\tflags: "); // $NON-NLS-1$ buffer .append(ApiProblem.getProblemFlagsName(getCategory(), getFlags())) .append("\n"); // $NON-NLS-1$ buffer.append("\tmessage id: "); // $NON-NLS-1$ buffer.append(getMessageid()); buffer.append("\n\tmessage: "); // $NON-NLS-1$ buffer.append(getMessage()); return buffer.toString(); }
/* (non-Javadoc) * @see org.apache.tools.ant.Task#execute() */ public void execute() throws BuildException { if (this.debug) { System.out.println("XML report location: " + this.xmlReportsLocation); // $NON-NLS-1$ System.out.println("HTML report location: " + this.htmlReportsLocation); // $NON-NLS-1$ if (this.xsltFileLocation == null) { System.out.println("No XSLT file specified: using default"); // $NON-NLS-1$} } else { System.out.println("XSLT file location: " + this.xsltFileLocation); // $NON-NLS-1$} } } try { Util.delete(new File(this.htmlReportsLocation)); MigrationReportConvertor converter = new MigrationReportConvertor( this.htmlReportsLocation, this.xmlReportsLocation, this.toPatterns, this.filterPatterns); ApiPlugin.DEBUG_USE_REPORT_CONVERTER = this.debug; converter.convert(this.xsltFileLocation, null); File index = converter.getReportIndex(); System.out.println( NLS.bind( Messages.ApiUseReportConversionTask_conversion_complete, index.getAbsolutePath())); } catch (Exception e) { throw new BuildException(e); } }
/** * Creates an {@link IApiBaseline} from all jar'd projects listed in the '/test-search/baseline' * directory * * @return a new {@link IApiBaseline} */ IApiBaseline createBaseline(final String name, final HashSet<String> projectnames) throws CoreException { File file = TEST_SRC_ROOT.append(BASELINE_DIR_NAME).toFile(); if (!file.exists()) { fail("The baseline test directory must exist"); } IApiBaseline base = ApiModelFactory.newApiBaseline(name, Util.getEEDescriptionFile()); File[] jars = file.listFiles( new FileFilter() { public boolean accept(File pathname) { String name = pathname.getName(); if (Util.isArchive(name)) { if (projectnames != null) { IPath path = new Path(pathname.getAbsolutePath()); return projectnames.contains(path.removeFileExtension().lastSegment()); } else { return true; } } return false; } }); IApiComponent[] components = new IApiComponent[jars.length]; for (int i = 0; i < jars.length; i++) { components[i] = ApiModelFactory.newApiComponent(base, jars[i].getAbsolutePath()); } base.addApiComponents(components); return base; }
/** * Returns the populated exclude set or an empty list if the exclude file location is <code>null * </code> * * @param baseline * @param filename * @return the listing of excluded items */ protected HashSet<String> getExcludeSet(IApiBaseline baseline, String filename) { if (filename == null) { return null; } // MY fix it final FilteredElements excludedElements = Util.initializeRegexFilterList(getExcludeFilePath(filename), baseline, false); final HashSet<String> result = new HashSet<String>(excludedElements.getExactMatches()); result.addAll(excludedElements.getPartialMatches()); return result; }
/** * Return the string representation of the flags for a problem * * @param category * @param flags * @return the string for the problem flags */ public static String getProblemFlagsName(int category, int flags) { switch (category) { case IApiProblem.CATEGORY_COMPATIBILITY: return Util.getDeltaFlagsName(flags); case IApiProblem.CATEGORY_SINCETAGS: case IApiProblem.CATEGORY_USAGE: case IApiProblem.CATEGORY_VERSION: case IApiProblem.CATEGORY_API_BASELINE: case IApiProblem.CATEGORY_API_COMPONENT_RESOLUTION: { switch (flags) { case IApiProblem.LEAK_EXTENDS: return "LEAK_EXTENDS"; //$NON-NLS-1$ case IApiProblem.LEAK_FIELD: return "LEAK_FIELD"; //$NON-NLS-1$ case IApiProblem.LEAK_IMPLEMENTS: return "LEAK_IMPLEMENTS"; //$NON-NLS-1$ case IApiProblem.LEAK_METHOD_PARAMETER: return "LEAK_METHOD_PARAMETER"; //$NON-NLS-1$ case IApiProblem.LEAK_CONSTRUCTOR_PARAMETER: return "LEAK_CONSTRUCTOR_PARAMETER"; //$NON-NLS-1$ case IApiProblem.LEAK_RETURN_TYPE: return "LEAK_RETURN_TYPE"; //$NON-NLS-1$ case IApiProblem.CONSTRUCTOR_METHOD: return "CONSTRUCTOR_METHOD"; //$NON-NLS-1$ case IApiProblem.NO_FLAGS: return "NO_FLAGS"; //$NON-NLS-1$ case IApiProblem.INDIRECT_REFERENCE: return "INDIRECT_REFERENCE"; //$NON-NLS-1$ case IApiProblem.METHOD: return "METHOD"; //$NON-NLS-1$ case IApiProblem.FIELD: return "FIELD"; //$NON-NLS-1$ default: return Util.UNKNOWN_FLAGS; } } case IApiProblem.CATEGORY_API_USE_SCAN_PROBLEM: { switch (flags) { case IApiProblem.API_USE_SCAN_DELETED: return "DELETED"; //$NON-NLS-1$ case IApiProblem.API_USE_SCAN_UNRESOLVED: return "UNRESOLVED"; //$NON-NLS-1$ default: return Util.UNKNOWN_FLAGS; } } default: return Util.UNKNOWN_FLAGS; } }
/** * Returns the string representation of the element kind of an {@link IApiProblem}, given its * category * * @param category * @param kind * @return the string of the {@link IApiProblem} element kind */ public static String getProblemElementKind(int category, int kind) { switch (category) { case IApiProblem.CATEGORY_COMPATIBILITY: case IApiProblem.CATEGORY_SINCETAGS: { return Util.getDeltaElementType(kind); } case IApiProblem.CATEGORY_USAGE: case IApiProblem.CATEGORY_VERSION: case IApiProblem.CATEGORY_API_BASELINE: case IApiProblem.CATEGORY_API_COMPONENT_RESOLUTION: { return ApiProblem.getDescriptorKind(kind); } case IApiProblem.CATEGORY_API_USE_SCAN_PROBLEM: { return Util.getApiElementType(kind); } default: return Util.UNKNOWN_KIND; } }
/* * (non-Javadoc) * @see * org.eclipse.ui.views.markers.WorkbenchMarkerResolution#findOtherMarkers * (org.eclipse.core.resources.IMarker[]) */ @Override public IMarker[] findOtherMarkers(IMarker[] markers) { HashSet<IMarker> mset = new HashSet<IMarker>(markers.length); for (int i = 0; i < markers.length; i++) { if (Util.isApiProblemMarker(markers[i]) && !fBackingMarker.equals(markers[i]) && markers[i].getAttribute(IApiMarkerConstants.API_MARKER_ATTR_ID, -1) == IApiMarkerConstants.UNSUPPORTED_TAG_MARKER_ID) { mset.add(markers[i]); } } int size = mset.size(); plural = size > 0; return mset.toArray(new IMarker[size]); }
/* * (non-Javadoc) * @see org.eclipse.jdt.ui.text.java.IJavaCompletionProposalComputer# * computeCompletionProposals * (org.eclipse.jdt.ui.text.java.ContentAssistInvocationContext, * org.eclipse.core.runtime.IProgressMonitor) */ @Override public List<ICompletionProposal> computeCompletionProposals( ContentAssistInvocationContext context, IProgressMonitor monitor) { JavaContentAssistInvocationContext jcontext = null; if (context instanceof JavaContentAssistInvocationContext) { jcontext = (JavaContentAssistInvocationContext) context; IJavaProject project = jcontext.getProject(); if (Util.isApiProject(project)) { CompletionContext corecontext = jcontext.getCoreContext(); if (corecontext.isInJavadoc()) { return computeJavadocProposals(jcontext, corecontext); } } } return Collections.EMPTY_LIST; }
/* * (non-Javadoc) * @see org.eclipse.pde.api.tools.internal.builder.AbstractProblemDetector# * getMessageArgs * (org.eclipse.pde.api.tools.internal.provisional.builder.IReference) */ @Override protected String[] getMessageArgs(IReference reference) throws CoreException { IApiMember member = reference.getMember(); String eeValue = ProfileModifiers.getName(this.referenceEEs.get(reference).intValue()); String simpleTypeName = Signatures.getSimpleTypeName(reference.getReferencedTypeName()); if (simpleTypeName.indexOf('$') != -1) { simpleTypeName = simpleTypeName.replace('$', '.'); } switch (reference.getReferenceType()) { case IReference.T_TYPE_REFERENCE: { return new String[] { getDisplay(member, false), simpleTypeName, eeValue, }; } case IReference.T_FIELD_REFERENCE: { return new String[] { getDisplay(member, false), simpleTypeName, reference.getReferencedMemberName(), eeValue, }; } case IReference.T_METHOD_REFERENCE: { String referenceMemberName = reference.getReferencedMemberName(); if (Util.isConstructor(referenceMemberName)) { return new String[] { getDisplay(member, false), Signature.toString( reference.getReferencedSignature(), simpleTypeName, null, false, false), eeValue, }; } else { return new String[] { getDisplay(member, false), simpleTypeName, Signature.toString( reference.getReferencedSignature(), referenceMemberName, null, false, false), eeValue, }; } } default: break; } return null; }
/** * Cleans the report location specified by the parameter {@link CommonUtilsTask#reportLocation} */ protected void cleanReportLocation() { if (this.reportLocation == null) { return; } long time = 0; if (this.debug) { time = System.currentTimeMillis(); System.out.println("Cleaning report location..."); // $NON-NLS-1$ } File file = new File(this.reportLocation); if (file.exists()) { Util.delete(file); } if (this.debug) { System.out.println( "done in: " + (System.currentTimeMillis() - time) + " ms"); // $NON-NLS-1$ //$NON-NLS-2$ } }
/** * Returns the string representation of the kind of an {@link IApiProblem}, given its category * * @param category * @param kind * @return the string of the {@link IApiProblem} kind */ public static String getProblemKind(int category, int kind) { switch (category) { case IApiProblem.CATEGORY_COMPATIBILITY: return Util.getDeltaKindName(kind); case IApiProblem.CATEGORY_SINCETAGS: return ApiProblem.getTagsProblemKindName(kind); case IApiProblem.CATEGORY_USAGE: return ApiProblem.getUsageProblemKindName(kind); case IApiProblem.CATEGORY_VERSION: return ApiProblem.getVersionProblemKindName(kind); case IApiProblem.CATEGORY_API_BASELINE: return ApiProblem.getApiBaselineProblemKindName(kind); case IApiProblem.CATEGORY_API_COMPONENT_RESOLUTION: return ApiProblem.getApiComponentResolutionProblemKindName(kind); case IApiProblem.CATEGORY_API_USE_SCAN_PROBLEM: return ApiProblem.getApiUseScanProblemKindName(kind); default: return Util.UNKNOWN_KIND; } }
/* * (non-Javadoc) * @see org.eclipse.pde.api.tools.internal.builder.AbstractProblemDetector# * getProblemFlags * (org.eclipse.pde.api.tools.internal.provisional.builder.IReference) */ @Override protected int getProblemFlags(IReference reference) { switch (reference.getReferenceType()) { case IReference.T_TYPE_REFERENCE: { return IApiProblem.NO_FLAGS; } case IReference.T_METHOD_REFERENCE: { if (Util.isConstructor(reference.getReferencedMemberName())) { return IApiProblem.CONSTRUCTOR_METHOD; } return IApiProblem.METHOD; } case IReference.T_FIELD_REFERENCE: { return IApiProblem.FIELD; } default: { return IApiProblem.NO_FLAGS; } } }
/* * (non-Javadoc) * @see org.eclipse.pde.api.tools.internal.builder.AbstractProblemDetector# * getSourceRange(org.eclipse.jdt.core.IType, * org.eclipse.jface.text.IDocument, * org.eclipse.pde.api.tools.internal.provisional.builder.IReference) */ @Override protected Position getSourceRange(IType type, IDocument document, IReference reference) throws CoreException, BadLocationException { switch (reference.getReferenceType()) { case IReference.T_TYPE_REFERENCE: { int linenumber = reference.getLineNumber(); if (linenumber > 0) { // line number starts at 0 for the linenumber--; } if (linenumber > 0) { int offset = document.getLineOffset(linenumber); String line = document.get(offset, document.getLineLength(linenumber)); String qname = reference.getReferencedTypeName().replace('$', '.'); int first = line.indexOf(qname); if (first < 0) { qname = Signatures.getSimpleTypeName(reference.getReferencedTypeName()); qname = qname.replace('$', '.'); first = line.indexOf(qname); } Position pos = null; if (first > -1) { pos = new Position(offset + first, qname.length()); } else { // optimistically select the whole line since we can't // find the correct variable name and we can't just // select // the first occurrence pos = new Position(offset, line.length()); } return pos; } else { IApiMember apiMember = reference.getMember(); switch (apiMember.getType()) { case IApiElement.FIELD: { IApiField field = (IApiField) reference.getMember(); return getSourceRangeForField(type, reference, field); } case IApiElement.METHOD: { // reference in a method declaration IApiMethod method = (IApiMethod) reference.getMember(); return getSourceRangeForMethod(type, reference, method); } default: break; } // reference in a type declaration ISourceRange range = type.getNameRange(); Position pos = null; if (range != null) { pos = new Position(range.getOffset(), range.getLength()); } if (pos == null) { return defaultSourcePosition(type, reference); } return pos; } } case IReference.T_FIELD_REFERENCE: { int linenumber = reference.getLineNumber(); if (linenumber > 0) { return getFieldNameRange( reference.getReferencedTypeName(), reference.getReferencedMemberName(), document, reference); } // reference in a field declaration IApiField field = (IApiField) reference.getMember(); return getSourceRangeForField(type, reference, field); } case IReference.T_METHOD_REFERENCE: { if (reference.getLineNumber() >= 0) { String referenceMemberName = reference.getReferencedMemberName(); String methodName = null; boolean isConstructor = Util.isConstructor(referenceMemberName); if (isConstructor) { methodName = Signatures.getSimpleTypeName(reference.getReferencedTypeName().replace('$', '.')); } else { methodName = referenceMemberName; } Position pos = getMethodNameRange(isConstructor, methodName, document, reference); if (pos == null) { return defaultSourcePosition(type, reference); } return pos; } // reference in a method declaration IApiMethod method = (IApiMethod) reference.getMember(); return getSourceRangeForMethod(type, reference, method); } default: return null; } }
/** * Creates a problem for a specific reference in the workspace * * @param reference reference * @param associated java project (with reference source location) * @return problem or <code>null</code> if none * @exception CoreException if something goes wrong */ protected IApiProblem createProblem(IReference reference, IJavaProject javaProject) { IProject project = javaProject.getProject(); if (ApiPlugin.getDefault().getSeverityLevel(getSeverityKey(), project) == ApiPlugin.SEVERITY_IGNORE) { return null; } try { String lookupName = getTypeName(reference.getMember()).replace('$', '.'); IType type = javaProject.findType(lookupName, new NullProgressMonitor()); if (type == null) { return null; } ICompilationUnit compilationUnit = type.getCompilationUnit(); if (compilationUnit == null) { return null; } IResource resource = Util.getResource(project, type); if (resource == null) { return null; } int charStart = -1; int charEnd = -1; int lineNumber = reference.getLineNumber(); IJavaElement element = compilationUnit; if (!Util.isManifest(resource.getProjectRelativePath()) && !type.isBinary()) { IDocument document = Util.getDocument(compilationUnit); // retrieve line number, char start and char end if (lineNumber > 0) { lineNumber--; } // get the source range for the problem try { Position pos = getSourceRange(type, document, reference); if (pos != null) { charStart = pos.getOffset(); if (charStart != -1) { charEnd = charStart + pos.getLength(); lineNumber = document.getLineOfOffset(charStart); } } } catch (CoreException e) { ApiPlugin.log(e); return null; } catch (BadLocationException e) { ApiPlugin.log(e); return null; } if (charStart > -1) { element = compilationUnit.getElementAt(charStart); } } return ApiProblemFactory.newApiUsageProblem( resource.getProjectRelativePath().toPortableString(), type.getFullyQualifiedName(), getMessageArgs(reference), new String[] { IApiMarkerConstants.MARKER_ATTR_HANDLE_ID, IApiMarkerConstants.API_MARKER_ATTR_ID }, new Object[] { (element == null ? compilationUnit.getHandleIdentifier() : element.getHandleIdentifier()), new Integer(IApiMarkerConstants.API_USAGE_MARKER_ID) }, lineNumber, charStart, charEnd, getElementType(reference), getProblemKind(), getProblemFlags(reference)); } catch (CoreException e) { ApiPlugin.log(e); } return null; }
/** Run the ant task */ public void execute() throws BuildException { if (this.debug) { System.out.println("xmlReportsLocation : " + this.xmlReportsLocation); // $NON-NLS-1$ System.out.println("htmlReportsLocation : " + this.htmlReportsLocation); // $NON-NLS-1$ } if (this.xmlReportsLocation == null) { throw new BuildException(Messages.missing_xml_files_location); } this.reportsRoot = new File(this.xmlReportsLocation); if (!this.reportsRoot.exists() || !this.reportsRoot.isDirectory()) { throw new BuildException(NLS.bind(Messages.invalid_directory_name, this.xmlReportsLocation)); } SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = null; try { parser = factory.newSAXParser(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } if (parser == null) { throw new BuildException(Messages.could_not_create_sax_parser); } if (this.htmlReportsLocation == null) { this.htmlReportsLocation = this.xmlReportsLocation; } this.htmlRoot = new File(this.htmlReportsLocation); if (!this.htmlRoot.exists()) { if (!this.htmlRoot.mkdirs()) { throw new BuildException( NLS.bind(Messages.could_not_create_file, this.htmlReportsLocation)); } } if (this.debug) { System.out.println("output name :" + this.htmlReportsLocation); // $NON-NLS-1$ } try { // retrieve all xml reports File[] allFiles = Util.getAllFiles( reportsRoot, new FileFilter() { public boolean accept(File pathname) { return pathname.isDirectory() || pathname.getName().endsWith(".xml"); // $NON-NLS-1$ } }); if (allFiles != null) { int length = allFiles.length; List summariesList = new ArrayList(length); Summary nonApiBundleSummary = null; for (int i = 0; i < length; i++) { File file = allFiles[i]; ConverterDefaultHandler defaultHandler = new ConverterDefaultHandler(this.debug); parser.parse(file, defaultHandler); Report report = defaultHandler.getReport(); if (report == null) { // ignore that file. It could be the counts.xml file. if (this.debug) { System.out.println("Skipped file : " + file.getAbsolutePath()); // $NON-NLS-1$ } continue; } dumpReport(file, report); if (report.isNonApiBundlesReport()) { nonApiBundleSummary = new Summary(report); } else { summariesList.add(new Summary(report)); } } // dump index file Summary[] summaries = new Summary[summariesList.size()]; summariesList.toArray(summaries); dumpIndexFile(reportsRoot, summaries, nonApiBundleSummary); } } catch (SAXException e) { // ignore } catch (IOException e) { // ignore } }