EMMA Coverage Report (generated Thu Nov 26 15:54:18 CST 2009)
[all classes][org.eclipse.pde.api.tools.internal.provisional.scanner]

COVERAGE SUMMARY FOR SOURCE FILE [TagScanner.java]

nameclass, %method, %block, %line, %
TagScanner.java100% (2/2)96%  (25/26)90%  (702/780)91%  (188.6/207)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class TagScanner100% (1/1)83%  (5/6)58%  (94/163)64%  (26.9/42)
setDebug (boolean): void 0%   (0/1)0%   (0/9)0%   (0/2)
scan (CompilationUnit, IApiDescription, IApiTypeContainer, Map, IProgressMoni... 100% (1/1)52%  (64/124)58%  (17.9/31)
<static initializer> 100% (1/1)100% (5/5)100% (3/3)
TagScanner (): void 100% (1/1)100% (3/3)100% (1/1)
newScanner (): TagScanner 100% (1/1)100% (8/8)100% (3/3)
scan (ICompilationUnit, IApiDescription, IApiTypeContainer, IProgressMonitor)... 100% (1/1)100% (14/14)100% (2/2)
     
class TagScanner$Visitor100% (1/1)100% (20/20)99%  (608/617)98%  (161.8/165)
visit (AnnotationTypeDeclaration): boolean 100% (1/1)86%  (12/14)75%  (3/4)
visit (EnumDeclaration): boolean 100% (1/1)86%  (12/14)75%  (3/4)
pruneTags (List, ASTNode): List 100% (1/1)97%  (163/168)97%  (45.8/47)
TagScanner$Visitor (IApiDescription, IApiTypeContainer): void 100% (1/1)100% (22/22)100% (8/8)
endVisit (AnnotationTypeDeclaration): void 100% (1/1)100% (8/8)100% (3/3)
endVisit (EnumDeclaration): void 100% (1/1)100% (8/8)100% (3/3)
endVisit (TypeDeclaration): void 100% (1/1)100% (8/8)100% (3/3)
enterType (SimpleName): void 100% (1/1)100% (19/19)100% (4/4)
exitType (): void 100% (1/1)100% (6/6)100% (2/2)
getEnclosingType (ASTNode): int 100% (1/1)100% (20/20)100% (7/7)
getException (): CoreException 100% (1/1)100% (3/3)100% (1/1)
isContinue (): boolean 100% (1/1)100% (7/7)100% (1/1)
isPrivate (int): boolean 100% (1/1)100% (3/3)100% (1/1)
processTags (IElementDescriptor, List, int, int): void 100% (1/1)100% (55/55)100% (16/16)
resolveMethod (IMethodDescriptor): IMethodDescriptor 100% (1/1)100% (103/103)100% (21/21)
visit (FieldDeclaration): boolean 100% (1/1)100% (10/10)100% (3/3)
visit (Javadoc): boolean 100% (1/1)100% (115/115)100% (27/27)
visit (MethodDeclaration): boolean 100% (1/1)100% (10/10)100% (3/3)
visit (PackageDeclaration): boolean 100% (1/1)100% (10/10)100% (3/3)
visit (TypeDeclaration): boolean 100% (1/1)100% (14/14)100% (4/4)

1/*******************************************************************************
2 * Copyright (c) 2007, 2009 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 * 
8 * Contributors:
9 *     IBM Corporation - initial API and implementation
10 *******************************************************************************/
11package org.eclipse.pde.api.tools.internal.provisional.scanner;
12 
13import java.io.FileNotFoundException;
14import java.io.IOException;
15import java.io.InputStream;
16import java.text.MessageFormat;
17import java.util.ArrayList;
18import java.util.Iterator;
19import java.util.List;
20import java.util.Map;
21 
22import org.eclipse.core.runtime.CoreException;
23import org.eclipse.core.runtime.IProgressMonitor;
24import org.eclipse.core.runtime.IStatus;
25import org.eclipse.core.runtime.Status;
26import org.eclipse.core.runtime.SubMonitor;
27import org.eclipse.jdt.core.Flags;
28import org.eclipse.jdt.core.ICompilationUnit;
29import org.eclipse.jdt.core.JavaCore;
30import org.eclipse.jdt.core.dom.AST;
31import org.eclipse.jdt.core.dom.ASTNode;
32import org.eclipse.jdt.core.dom.ASTParser;
33import org.eclipse.jdt.core.dom.ASTVisitor;
34import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
35import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
36import org.eclipse.jdt.core.dom.BodyDeclaration;
37import org.eclipse.jdt.core.dom.EnumDeclaration;
38import org.eclipse.jdt.core.dom.FieldDeclaration;
39import org.eclipse.jdt.core.dom.Javadoc;
40import org.eclipse.jdt.core.dom.MethodDeclaration;
41import org.eclipse.jdt.core.dom.Name;
42import org.eclipse.jdt.core.dom.PackageDeclaration;
43import org.eclipse.jdt.core.dom.SimpleName;
44import org.eclipse.jdt.core.dom.TagElement;
45import org.eclipse.jdt.core.dom.TypeDeclaration;
46import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
47import org.eclipse.pde.api.tools.internal.CompilationUnit;
48import org.eclipse.pde.api.tools.internal.JavadocTagManager;
49import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
50import org.eclipse.pde.api.tools.internal.provisional.Factory;
51import org.eclipse.pde.api.tools.internal.provisional.IApiDescription;
52import org.eclipse.pde.api.tools.internal.provisional.IApiJavadocTag;
53import org.eclipse.pde.api.tools.internal.provisional.RestrictionModifiers;
54import org.eclipse.pde.api.tools.internal.provisional.descriptors.IElementDescriptor;
55import org.eclipse.pde.api.tools.internal.provisional.descriptors.IMethodDescriptor;
56import org.eclipse.pde.api.tools.internal.provisional.descriptors.IPackageDescriptor;
57import org.eclipse.pde.api.tools.internal.provisional.descriptors.IReferenceTypeDescriptor;
58import org.eclipse.pde.api.tools.internal.provisional.model.IApiMethod;
59import org.eclipse.pde.api.tools.internal.provisional.model.IApiType;
60import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeContainer;
61import org.eclipse.pde.api.tools.internal.provisional.model.IApiTypeRoot;
62import org.eclipse.pde.api.tools.internal.util.Signatures;
63import org.eclipse.pde.api.tools.internal.util.Util;
64 
65/**
66 * Scans the source of a *.java file for any API javadoc tags
67 * @since 1.0.0
68 */
69public class TagScanner {
70 
71        /**
72         * Constant used for controlling tracing in the scanner
73         */
74        private static boolean DEBUG = Util.DEBUG;
75        
76        /**
77         * Method used for initializing tracing in the scanner
78         */
79        public static void setDebug(boolean debugValue) {
80                DEBUG = debugValue || Util.DEBUG;
81        }
82        
83        /**
84         * Visitor to scan a compilation unit. We only care about javadoc nodes that have either 
85         * type or enum declarations as parents, so we have to override the ones we don't care 
86         * about.
87         */
88        static class Visitor extends ASTVisitor {
89                
90                private IApiDescription fDescription = null;
91                
92                /**
93                 * Package descriptor. Initialized to default package, and overridden if a package
94                 * declaration is visited.
95                 */
96                private IPackageDescriptor fPackage = Factory.packageDescriptor(""); //$NON-NLS-1$
97                
98                /**
99                 * Type descriptor for type currently being visited.
100                 */
101                private IReferenceTypeDescriptor fType = null;
102                
103                /**
104                 * Used to look up binaries when resolving method signatures, or
105                 * <code>null</code> if not provided.
106                 */
107                private IApiTypeContainer fContainer = null;
108                
109                /**
110                 * List of exceptions encountered, or <code>null</code>
111                 */
112                private CoreException fException;
113                
114                /**
115                 * Constructor
116                 * @param description API description to annotate
117                 * @param container class file container or <code>null</code>, used
118                 *         to resolve method signatures
119                 */
120                public Visitor(IApiDescription description, IApiTypeContainer container) {
121                        fDescription = description;
122                        fContainer = container;
123                }
124                
125                /* (non-Javadoc)
126                 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.Javadoc)
127                 */
128                public boolean visit(Javadoc node) {
129                        List tags = node.tags();
130                        ASTNode parent = node.getParent();
131                        if(parent != null) {
132                                switch(parent.getNodeType()) {
133                                        case ASTNode.TYPE_DECLARATION: {
134                                                TypeDeclaration type = (TypeDeclaration) parent;
135                                                if(type.isInterface()) {
136                                                        processTags(fType, pruneTags(tags, type), IApiJavadocTag.TYPE_INTERFACE, IApiJavadocTag.MEMBER_NONE);
137                                                }
138                                                else {
139                                                        processTags(fType, pruneTags(tags, type), IApiJavadocTag.TYPE_CLASS, IApiJavadocTag.MEMBER_NONE);
140                                                }
141                                                break;
142                                        }
143                                        case ASTNode.METHOD_DECLARATION: {
144                                                MethodDeclaration method = (MethodDeclaration) parent;
145                                                String signature = Signatures.getMethodSignatureFromNode(method);
146                                                if(signature != null) {
147                                                        String methodname = method.getName().getFullyQualifiedName();
148                                                        int member = IApiJavadocTag.MEMBER_METHOD;
149                                                        if(method.isConstructor()) {
150                                                                member = IApiJavadocTag.MEMBER_CONSTRUCTOR;
151                                                                methodname = "<init>"; //$NON-NLS-1$
152                                                        }
153                                                        IMethodDescriptor descriptor = fType.getMethod(methodname, signature);
154                                                        processTags(descriptor, pruneTags(tags, method), getEnclosingType(method), member);
155                                                }
156                                                break;
157                                        }
158                                        case ASTNode.FIELD_DECLARATION: {
159                                                FieldDeclaration field = (FieldDeclaration) parent;
160                                                List fields = field.fragments();
161                                                VariableDeclarationFragment fragment = null;
162                                                for(Iterator iter = fields.iterator(); iter.hasNext();) {
163                                                        fragment = (VariableDeclarationFragment) iter.next();
164                                                        processTags(fType.getField(fragment.getName().getFullyQualifiedName()), pruneTags(tags, field), getEnclosingType(field), IApiJavadocTag.MEMBER_FIELD);
165                                                }
166                                                break;
167                                        }
168                                }
169                        }
170                        return false;
171                }
172                
173                private int getEnclosingType(ASTNode node) {
174                        ASTNode lnode = node;
175                        while (!(lnode instanceof AbstractTypeDeclaration)) {
176                                lnode = lnode.getParent();
177                        }
178                        if (lnode instanceof TypeDeclaration) {
179                                if (((TypeDeclaration)lnode).isInterface()) {
180                                        return IApiJavadocTag.TYPE_INTERFACE;
181                                }
182                        }
183                        return IApiJavadocTag.TYPE_CLASS;
184                }
185                
186                /**
187                 * A type has been entered - update the type being visited.
188                 * 
189                 * @param name name from type node
190                 */
191                private void enterType(SimpleName name) {
192                        if (fType == null) {
193                                fType = fPackage.getType(name.getFullyQualifiedName());
194                        } else {
195                                fType = fType.getType(name.getFullyQualifiedName());
196                        }                        
197                }
198                
199                /**
200                 * A type has been exited - update the type being visited.
201                 */
202                private void exitType() {
203                        fType = fType.getEnclosingType();
204                }
205                
206                /**
207                 * Processes the tags for the given {@link IElementDescriptor}
208                 * @param descriptor the descriptor
209                 * @param tags the listing of tags from the AST
210                 * @param type one of <code>CLASS</code> or <code>INTERFACE</code>
211                 * @param member one of <code>METHOD</code> or <code>FIELD</code> or <code>NONE</code>
212                 */
213                protected void processTags(IElementDescriptor descriptor, List tags, int type, int member) {
214                        JavadocTagManager jtm = ApiPlugin.getJavadocTagManager();
215                        TagElement tag = null;
216                        String tagname = null;
217                        int restrictions = RestrictionModifiers.NO_RESTRICTIONS;
218                        for(Iterator iter = tags.iterator(); iter.hasNext();) {
219                                tag = (TagElement) iter.next();
220                                tagname = tag.getTagName();
221                                restrictions |= jtm.getRestrictionsForTag(tagname, type, member);
222                        }
223                        if (restrictions != RestrictionModifiers.NO_RESTRICTIONS) {
224                                IElementDescriptor ldesc = descriptor;
225                                if (ldesc.getElementType() == IElementDescriptor.METHOD) {
226                                        try {
227                                                ldesc = resolveMethod((IMethodDescriptor)ldesc);
228                                        } catch (CoreException e) {
229                                                fException = e;
230                                        }
231                                }
232                                fDescription.setRestrictions(ldesc, restrictions);
233                        }
234                }
235                
236                /**
237                 * Method to post process returned flags from the {@link Javadoc} node of the element
238                 * @param tags the tags to process
239                 * @param element the {@link ASTNode} the tag appears on
240                 * @return the list of valid tags to process restrictions for
241                 */
242                private List pruneTags(final List tags, ASTNode node) {
243                        ArrayList pruned = new ArrayList(tags.size());
244                        TagElement tag = null;
245                        switch(node.getNodeType()) {
246                                case ASTNode.TYPE_DECLARATION: {
247                                        TypeDeclaration type = (TypeDeclaration) node;
248                                        int flags = type.getModifiers();
249                                        for (Iterator iterator = tags.iterator(); iterator.hasNext();) {
250                                                tag = (TagElement) iterator.next();
251                                                String tagname = tag.getTagName();
252                                                if(type.isInterface() && 
253                                                                ("@noextend".equals(tagname) || //$NON-NLS-1$
254                                                                "@noimplement".equals(tagname))) { //$NON-NLS-1$
255                                                        pruned.add(tag);
256                                                }
257                                                else {
258                                                        if("@noextend".equals(tagname)) { //$NON-NLS-1$
259                                                                if(!Flags.isFinal(flags)) {
260                                                                        pruned.add(tag);
261                                                                        continue;
262                                                                }
263                                                        }
264                                                        if("@noinstantiate".equals(tagname)) { //$NON-NLS-1$
265                                                                if(!Flags.isAbstract(flags)) {
266                                                                        pruned.add(tag);
267                                                                        continue;
268                                                                }
269                                                        }
270                                                }
271                                        }
272                                        break;
273                                }
274                                case ASTNode.METHOD_DECLARATION: {
275                                        MethodDeclaration method = (MethodDeclaration) node;
276                                        int flags = method.getModifiers();
277                                        for (Iterator iterator = tags.iterator(); iterator.hasNext();) {
278                                                tag = (TagElement) iterator.next();
279                                                if("@noreference".equals(tag.getTagName())) { //$NON-NLS-1$
280                                                        pruned.add(tag);
281                                                        continue;
282                                                }
283                                                if("@nooverride".equals(tag.getTagName())) { //$NON-NLS-1$
284                                                        ASTNode parent = method.getParent();
285                                                        int pflags = 0;
286                                                        if(parent instanceof BodyDeclaration) {
287                                                                pflags = ((BodyDeclaration)parent).getModifiers();
288                                                        }
289                                                        if(!Flags.isFinal(flags) && 
290                                                                        !Flags.isStatic(flags) &&
291                                                                        !Flags.isFinal(pflags)) {
292                                                                pruned.add(tag);
293                                                                continue;
294                                                        }
295                                                }
296                                        }
297                                        break;
298                                }
299                                case ASTNode.FIELD_DECLARATION: {
300                                        FieldDeclaration field = (FieldDeclaration) node;
301                                        for (Iterator iterator = tags.iterator(); iterator.hasNext();) {
302                                                tag = (TagElement) iterator.next();
303                                                boolean isfinal = Flags.isFinal(field.getModifiers());
304                                                if(isfinal || (isfinal && Flags.isStatic(field.getModifiers()))) {
305                                                        break;
306                                                }
307                                                if("@noreference".equals(tag.getTagName())) { //$NON-NLS-1$
308                                                        pruned.add(tag);
309                                                        break;
310                                                }
311                                        }
312                                        break;
313                                }
314                        }
315                        return pruned;
316                }
317                
318                /**
319                 * Returns whether to continue processing children.
320                 * 
321                 * @return whether to continue processing children.
322                 */
323                private boolean isContinue() {
324                        return fException == null;
325                }
326                
327                /**
328                 * Returns an exception that aborted processing, or <code>null</code> if none.
329                 * 
330                 * @return an exception that aborted processing, or <code>null</code> if none
331                 */
332                CoreException getException() {
333                        return fException;
334                }
335                
336                /* (non-Javadoc)
337                 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.TypeDeclaration)
338                 */
339                public boolean visit(TypeDeclaration node) {
340                        if(isPrivate(node.getModifiers())) {
341                                return false;
342                        }
343                        enterType(node.getName());
344                        return isContinue();
345                }
346                /* (non-Javadoc)
347                 * @see org.eclipse.jdt.core.dom.ASTVisitor#endVisit(org.eclipse.jdt.core.dom.TypeDeclaration)
348                 */
349                public void endVisit(TypeDeclaration node) {
350                        if(!isPrivate(node.getModifiers())) {
351                                exitType();
352                        }
353                }
354                /* (non-Javadoc)
355                 * @see org.eclipse.jdt.core.dom.ASTVisitor#endVisit(org.eclipse.jdt.core.dom.AnnotationTypeDeclaration)
356                 */
357                public void endVisit(AnnotationTypeDeclaration node) {
358                        if(!isPrivate(node.getModifiers())) {
359                                exitType();
360                        }
361                }
362                /* (non-Javadoc)
363                 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.AnnotationTypeDeclaration)
364                 */
365                public boolean visit(AnnotationTypeDeclaration node) {
366                        if(isPrivate(node.getModifiers())) {
367                                return false;
368                        }
369                        enterType(node.getName());
370                        return isContinue();
371                }
372                /* (non-Javadoc)
373                 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.EnumDeclaration)
374                 */
375                public boolean visit(EnumDeclaration node) {
376                        if(isPrivate(node.getModifiers())) {
377                                return false;
378                        }
379                        enterType(node.getName());
380                        return isContinue();
381                }
382                /* (non-Javadoc)
383                 * @see org.eclipse.jdt.core.dom.ASTVisitor#endVisit(org.eclipse.jdt.core.dom.EnumDeclaration)
384                 */
385                public void endVisit(EnumDeclaration node) {
386                        if(!isPrivate(node.getModifiers())) {
387                                exitType();
388                        }
389                }
390                /* (non-Javadoc)
391                 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.PackageDeclaration)
392                 */
393                public boolean visit(PackageDeclaration node) {
394                        Name name = node.getName();
395                        fPackage = Factory.packageDescriptor(name.getFullyQualifiedName());
396                        return false;
397                }
398                /* (non-Javadoc)
399                 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.MethodDeclaration)
400                 */
401                public boolean visit(MethodDeclaration node) {
402                        if(isPrivate(node.getModifiers())) {
403                                return false;
404                        }
405                        return isContinue();
406                }
407                /* (non-Javadoc)
408                 * @see org.eclipse.jdt.core.dom.ASTVisitor#visit(org.eclipse.jdt.core.dom.FieldDeclaration)
409                 */
410                public boolean visit(FieldDeclaration node) {
411                        if(isPrivate(node.getModifiers())) {
412                                return false;
413                        }
414                        return isContinue();
415                }
416                private boolean isPrivate(int flags) {
417                        return Flags.isPrivate(flags);
418                }
419                /**
420                 * Returns a method descriptor with a resolved signature for the given method
421                 * descriptor with an unresolved signature.
422                 * 
423                 * @param descriptor method to resolve
424                 * @return resolved method descriptor or the same method descriptor if unable to
425                 *         resolve
426                 * @exception CoreException if unable to resolve the method and a class file
427                 *  container was provided for this purpose
428                 */
429                private IMethodDescriptor resolveMethod(IMethodDescriptor descriptor) throws CoreException {
430                        if (fContainer != null) {
431                                IReferenceTypeDescriptor type = descriptor.getEnclosingType();
432                                IApiTypeRoot classFile = fContainer.findTypeRoot(type.getQualifiedName());
433                                if(classFile != null) {
434                                        IApiType structure = classFile.getStructure();
435                                        if(structure != null) {
436                                                IApiMethod[] methods = structure.getMethods();
437                                                for (int i = 0; i < methods.length; i++) {
438                                                        IApiMethod method = methods[i];
439                                                        if (descriptor.getName().equals(method.getName())) {
440                                                                String signature = method.getSignature();
441                                                                String descriptorSignature = descriptor.getSignature().replace('/', '.');
442                                                                if (Signatures.matchesSignatures(descriptorSignature, signature.replace('/', '.'))) {
443                                                                        return descriptor.getEnclosingType().getMethod(method.getName(), signature);
444                                                                }
445                                                                String genericSignature = method.getGenericSignature();
446                                                                if (genericSignature != null) {
447                                                                        if (Signatures.matchesSignatures(descriptorSignature, genericSignature.replace('/', '.'))) {
448                                                                                return descriptor.getEnclosingType().getMethod(method.getName(), signature);
449                                                                        }
450                                                                }
451                                                        }
452                                                }
453                                        }
454                                }
455                                throw new CoreException(new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID,
456                                        MessageFormat.format("Unable to resolve method signature: {0}", new String[]{descriptor.toString()}), null)); //$NON-NLS-1$
457                        }
458                        return descriptor;
459                }
460                
461        }
462 
463        /**
464         * The singleton instance of the scanner
465         */
466        private static TagScanner fSingleton = null;
467        
468        /**
469         * Delegate for getting the singleton instance of the scanner
470         * @return
471         */
472        public static final TagScanner newScanner() {
473                if(fSingleton == null) {
474                        fSingleton = new TagScanner();
475                }
476                return fSingleton;
477        }
478        
479        /**
480         * Constructor
481         * Cannot be instantiated
482         */
483        private TagScanner() {}
484        
485        /**
486         * Scans the specified {@link ICompilationUnit} for contributed API Javadoc tags.
487         * Tags on methods will have unresolved signatures.
488         * @param unit the compilation unit source
489         * @param description the API description to annotate with any new tag rules found
490         * @param container optional class file container containing the class file for the given source
491         *         that can be used to resolve method signatures if required (for tags on methods). If 
492         *         not provided (<code>null</code>), method signatures will be unresolved.
493         * @param monitor
494         * 
495         * @throws CoreException
496         */
497        public void scan(ICompilationUnit unit, IApiDescription description, IApiTypeContainer container, IProgressMonitor monitor) throws CoreException {
498                scan(new CompilationUnit(unit), description, container, unit.getJavaProject().getOptions(true), monitor);
499        }
500        
501        /**
502         * Scans the specified source {@linkplain CompilationUnit} for contributed API javadoc tags.
503         * Tags on methods will have unresolved signatures.
504         * 
505         * @param source the source file to scan for tags
506         * @param description the API description to annotate with any new tag rules found
507         * @param container optional class file container containing the class file for the given source
508         *         that can be used to resolve method signatures if required (for tags on methods). If 
509         *         not provided (<code>null</code>), method signatures will be unresolved.
510         * @param options a map of Java compiler options to use when creating the AST to scan
511         *  or <code>null</code> if default options should be used 
512         *  @param monitor
513         * 
514         * @throws CoreException 
515         */
516        public void scan(CompilationUnit source, IApiDescription description, IApiTypeContainer container, Map options, IProgressMonitor monitor) throws CoreException {
517                SubMonitor localmonitor = SubMonitor.convert(monitor, 2);
518                ASTParser parser = ASTParser.newParser(AST.JLS3);
519                InputStream inputStream = null;
520                try {
521                        inputStream = source.getInputStream();
522                        parser.setSource(Util.getInputStreamAsCharArray(inputStream, -1, System.getProperty("file.encoding"))); //$NON-NLS-1$
523                } catch (FileNotFoundException e) {
524                        throw new CoreException(new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID,
525                                        MessageFormat.format("Compilation unit source not found: {0}", new String[]{source.getName()}), e)); //$NON-NLS-1$
526                } catch (IOException e) {
527                        if (DEBUG) {
528                                System.err.println(source.getName());
529                        }
530                        throw new CoreException(new Status(IStatus.ERROR, ApiPlugin.PLUGIN_ID,
531                                        MessageFormat.format("Error reading compilation unit: {0}", new String[]{source.getName()}), e)); //$NON-NLS-1$
532                } finally {
533                        if (inputStream != null) {
534                                try {
535                                        inputStream.close();
536                                } catch(IOException e) {
537                                        ApiPlugin.log(e);
538                                }
539                        }
540                }
541                Util.updateMonitor(localmonitor);
542                Map loptions = options;
543                if(loptions == null) {
544                        loptions = JavaCore.getOptions();
545                }
546                loptions.put(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, JavaCore.ENABLED);
547                parser.setCompilerOptions(loptions);
548                org.eclipse.jdt.core.dom.CompilationUnit cunit = (org.eclipse.jdt.core.dom.CompilationUnit) parser.createAST(localmonitor.newChild(1));
549                Visitor visitor = new Visitor(description, container);
550                cunit.accept(visitor);
551                if (visitor.getException() != null) {
552                        throw visitor.getException();
553                }
554        }        
555}

[all classes][org.eclipse.pde.api.tools.internal.provisional.scanner]
EMMA 2.0.5312 EclEmma Fix 1 (C) Vladimir Roubtsov