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

COVERAGE SUMMARY FOR SOURCE FILE [MethodLeakDetector.java]

nameclass, %method, %block, %line, %
MethodLeakDetector.java100% (1/1)82%  (9/11)79%  (241/304)75%  (58.8/78)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class MethodLeakDetector100% (1/1)82%  (9/11)79%  (241/304)75%  (58.8/78)
getQualifiedMessageArgs (IReference): String [] 0%   (0/1)0%   (0/28)0%   (0/6)
getSeverityKey (): String 0%   (0/1)0%   (0/2)0%   (0/1)
isProblem (IReference): boolean 100% (1/1)68%  (50/73)60%  (12/20)
matchesSourceModifiers (IApiMember): boolean 100% (1/1)79%  (22/28)70%  (7/10)
matchesSourceApiRestrictions (IApiMember): boolean 100% (1/1)96%  (101/105)95%  (22.8/24)
MethodLeakDetector (Set): void 100% (1/1)100% (4/4)100% (2/2)
considerReference (IReference): boolean 100% (1/1)100% (24/24)100% (6/6)
getElementType (IReference): int 100% (1/1)100% (2/2)100% (1/1)
getMessageArgs (IReference): String [] 100% (1/1)100% (28/28)100% (6/6)
getProblemKind (): int 100% (1/1)100% (2/2)100% (1/1)
getSourceRange (IType, IDocument, IReference): Position 100% (1/1)100% (8/8)100% (1/1)

1/*******************************************************************************
2 * Copyright (c) 2008, 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.builder;
12 
13import java.util.Set;
14 
15import org.eclipse.core.runtime.CoreException;
16import org.eclipse.core.runtime.IStatus;
17import org.eclipse.core.runtime.Status;
18import org.eclipse.jdt.core.Flags;
19import org.eclipse.jdt.core.IType;
20import org.eclipse.jface.text.BadLocationException;
21import org.eclipse.jface.text.IDocument;
22import org.eclipse.jface.text.Position;
23import org.eclipse.pde.api.tools.internal.provisional.ApiPlugin;
24import org.eclipse.pde.api.tools.internal.provisional.IApiAnnotations;
25import org.eclipse.pde.api.tools.internal.provisional.IApiDescription;
26import org.eclipse.pde.api.tools.internal.provisional.RestrictionModifiers;
27import org.eclipse.pde.api.tools.internal.provisional.VisibilityModifiers;
28import org.eclipse.pde.api.tools.internal.provisional.builder.IReference;
29import org.eclipse.pde.api.tools.internal.provisional.descriptors.IElementDescriptor;
30import org.eclipse.pde.api.tools.internal.provisional.model.IApiComponent;
31import org.eclipse.pde.api.tools.internal.provisional.model.IApiMember;
32import org.eclipse.pde.api.tools.internal.provisional.model.IApiMethod;
33import org.eclipse.pde.api.tools.internal.provisional.model.IApiType;
34import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblem;
35import org.eclipse.pde.api.tools.internal.provisional.problems.IApiProblemTypes;
36import org.eclipse.pde.api.tools.internal.util.Signatures;
37 
38import com.ibm.icu.text.MessageFormat;
39 
40/**
41 * Detects leaks in method return types and parameters
42 * 
43 * @since 1.1
44 * @noextend This class is not intended to be subclassed by clients.
45 */
46public abstract class MethodLeakDetector extends AbstractLeakProblemDetector {
47 
48        /**
49         * @param nonApiPackageNames
50         */
51        public MethodLeakDetector(Set nonApiPackageNames) {
52                super(nonApiPackageNames);
53        }
54 
55        /* (non-Javadoc)
56         * @see org.eclipse.pde.api.tools.internal.search.AbstractProblemDetector#getElementType(org.eclipse.pde.api.tools.internal.provisional.model.IReference)
57         */
58        protected int getElementType(IReference reference) {
59                return IElementDescriptor.METHOD;
60        }
61 
62        /* (non-Javadoc)
63         * @see org.eclipse.pde.api.tools.internal.search.AbstractProblemDetector#getProblemKind()
64         */
65        protected int getProblemKind() {
66                return IApiProblem.API_LEAK;
67        }
68 
69        /* (non-Javadoc)
70         * @see org.eclipse.pde.api.tools.internal.search.AbstractProblemDetector#getSeverityKey()
71         */
72        protected String getSeverityKey() {
73                return IApiProblemTypes.LEAK_METHOD_RETURN_TYPE ;
74        }
75 
76        /* (non-Javadoc)
77         * @see org.eclipse.pde.api.tools.internal.search.AbstractProblemDetector#isProblem(org.eclipse.pde.api.tools.internal.provisional.model.IReference)
78         */
79        protected boolean isProblem(IReference reference) {
80                IApiMethod method = (IApiMethod) reference.getMember();
81                IApiType type = (IApiType) reference.getResolvedReference();
82                try {
83                        // referenced type is non-API
84                        IApiAnnotations annotations = type.getApiComponent().getApiDescription().resolveAnnotations(type.getHandle());
85                        if (annotations != null) {
86                                if (VisibilityModifiers.isPrivate(annotations.getVisibility())) {
87                                        if ((Flags.AccProtected & method.getModifiers()) > 0) {
88                                                // ignore protected members if contained in a @noextend type
89                                                // TODO: we could perform this check before resolution - it's on the source location
90                                                IApiDescription description = method.getApiComponent().getApiDescription();
91                                                annotations = description.resolveAnnotations(method.getHandle().getEnclosingType());
92                                                if (annotations == null || RestrictionModifiers.isExtendRestriction(annotations.getRestrictions())) {
93                                                        // ignore
94                                                        return false;
95                                                }
96                                        }
97                                        return true;
98                                }
99                        } else {
100                                // could be a reference to a top level secondary/non-public type
101                                if (isEnclosingTypeVisible(type)) {
102                                        // this is an unexpected condition - the enclosing type is visible, but it has no annotations - log an error
103                                        ApiPlugin.log(
104                                                new Status(
105                                                        IStatus.INFO, ApiPlugin.PLUGIN_ID,
106                                                        MessageFormat.format(BuilderMessages.AbstractTypeLeakDetector_vis_type_has_no_api_description, new String[]{type.getName()})));
107                                } else {
108                                        // enclosing type is not visible - this is a problem
109                                        return true;
110                                }
111                        }
112                } catch (CoreException e) {
113                        ApiPlugin.log(e);
114                }
115                return false;
116        }
117        
118        /* (non-Javadoc)
119         * @see org.eclipse.pde.api.tools.internal.search.AbstractProblemDetector#getMessageArgs(org.eclipse.pde.api.tools.internal.provisional.model.IReference)
120         */
121        protected String[] getMessageArgs(IReference reference) throws CoreException {
122                IApiMethod method = (IApiMethod) reference.getMember();
123                IApiType type = (IApiType) reference.getResolvedReference();
124                return new String[] {
125                                getSimpleTypeName(type), 
126                                getSimpleTypeName(method), 
127                                Signatures.getMethodSignature(method)};
128        }
129        
130        /* (non-Javadoc)
131         * @see org.eclipse.pde.api.tools.internal.search.AbstractProblemDetector#getQualifiedMessageArgs(org.eclipse.pde.api.tools.internal.provisional.model.IReference)
132         */
133        protected String[] getQualifiedMessageArgs(IReference reference) throws CoreException {
134                IApiMethod method = (IApiMethod) reference.getMember();
135                IApiType type = (IApiType) reference.getResolvedReference();
136                return new String[] {
137                                getQualifiedTypeName(type), 
138                                getQualifiedTypeName(method), 
139                                Signatures.getMethodSignature(method)};
140        }
141        
142        /* (non-Javadoc)
143         * @see org.eclipse.pde.api.tools.internal.search.AbstractProblemDetector#getSourceRange(org.eclipse.jdt.core.IType, org.eclipse.jface.text.IDocument, org.eclipse.pde.api.tools.internal.provisional.model.IReference)
144         */
145        protected Position getSourceRange(IType type, IDocument doc, IReference reference) throws CoreException, BadLocationException {
146                return getSourceRangeForMethod(type, reference, (IApiMethod) reference.getMember());
147        }
148 
149        /* (non-Javadoc)
150         * @see org.eclipse.pde.api.tools.internal.provisional.search.IApiProblemDetector#considerReference(org.eclipse.pde.api.tools.internal.provisional.model.IReference)
151         */
152        public boolean considerReference(IReference reference) {
153                if (isNonAPIReference(reference)) {
154                        IApiMember member = reference.getMember();
155                        if (member != null && matchesSourceModifiers(member) && matchesSourceApiRestrictions(member)) {
156                                retainReference(reference);
157                                return true;
158                        }
159                }
160                return false;
161        }
162        
163        /**
164         * Returns if the source API restrictions for the given member matches the restrictions in the parent API description
165         * @param member
166         * @return true if it matches, false otherwise
167         */
168        protected boolean matchesSourceApiRestrictions(IApiMember member) {
169                IApiComponent apiComponent = member.getApiComponent();
170                try {
171                        IApiMethod method = (IApiMethod) member;
172                        IApiAnnotations annotations = apiComponent.getApiDescription().resolveAnnotations(method.getHandle());
173                        if (annotations != null) {
174                                if (VisibilityModifiers.isAPI(annotations.getVisibility())) {
175                                        int ares = annotations.getRestrictions();
176                                        if(ares != 0) {
177                                                if(method.isConstructor()) {
178                                                        return (ares & RestrictionModifiers.NO_REFERENCE) == 0;
179                                                }
180                                                if((ares & RestrictionModifiers.NO_OVERRIDE) == 0) {
181                                                        IApiAnnotations annot = apiComponent.getApiDescription().resolveAnnotations(method.getEnclosingType().getHandle());
182                                                        int pres = 0;
183                                                        if(annot != null) {
184                                                                pres = annot.getRestrictions();
185                                                        }
186                                                        return (ares & RestrictionModifiers.NO_REFERENCE) != 0 && (!Flags.isFinal(method.getModifiers())
187                                                                        && !Flags.isStatic(method.getModifiers())
188                                                                        && !Flags.isFinal(method.getEnclosingType().getModifiers())
189                                                                        && ((pres & RestrictionModifiers.NO_EXTEND) == 0));
190                                                }
191                                                return  (ares & RestrictionModifiers.NO_REFERENCE) == 0; 
192                                        }
193                                        else {
194                                                return !(Flags.isProtected(method.getModifiers()) && Flags.isFinal(method.getEnclosingType().getModifiers()));
195                                        }
196                                }
197                        } else {
198                                return true;
199                        }
200                } catch (CoreException e) {
201                        ApiPlugin.log(e);
202                }
203                return false;
204        }        
205        
206        /**
207         * Returns if the source modifiers for the given member match the ones specified in the detector
208         * @param member
209         * @return true if the modifiers match, false otherwise
210         */
211        protected boolean matchesSourceModifiers(IApiMember member) {
212                IApiMember lmember = member;
213                while (lmember != null) {
214                        int modifiers = lmember.getModifiers();
215                        if (Flags.isPublic(modifiers) || Flags.isProtected(modifiers)) {
216                                try {
217                                        lmember = lmember.getEnclosingType();
218                                } catch (CoreException e) {
219                                        ApiPlugin.log(e.getStatus());
220                                        return false;
221                                }
222                        } else {
223                                return false;
224                        }
225                }
226                return true;
227        }        
228 
229}

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