KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > hints > UncaughtExceptionCreator


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.java.hints;
20
21 import com.sun.source.tree.BlockTree;
22 import com.sun.source.tree.CatchTree;
23 import com.sun.source.tree.ExpressionTree;
24 import com.sun.source.tree.MethodTree;
25 import com.sun.source.tree.StatementTree;
26 import com.sun.source.tree.ThrowTree;
27 import com.sun.source.tree.Tree;
28 import com.sun.source.tree.Tree.Kind;
29 import com.sun.source.tree.TryTree;
30 import com.sun.source.util.TreePath;
31 import java.io.IOException JavaDoc;
32 import java.util.ArrayList JavaDoc;
33 import java.util.Collections JavaDoc;
34 import java.util.EnumSet JavaDoc;
35 import java.util.HashSet JavaDoc;
36 import java.util.List JavaDoc;
37 import java.util.Map JavaDoc;
38 import java.util.Set JavaDoc;
39 import javax.lang.model.element.Element;
40 import javax.lang.model.element.ElementKind;
41 import javax.lang.model.element.ExecutableElement;
42 import javax.lang.model.element.Modifier;
43 import javax.lang.model.element.VariableElement;
44 import javax.lang.model.type.TypeMirror;
45 import javax.lang.model.type.TypeKind;
46 import javax.swing.text.Document JavaDoc;
47 import javax.tools.Diagnostic;
48 import org.netbeans.api.java.source.CancellableTask;
49 import org.netbeans.api.java.source.CompilationInfo;
50 import org.netbeans.api.java.source.ElementHandle;
51 import org.netbeans.api.java.source.JavaSource;
52 import org.netbeans.api.java.source.JavaSource.Phase;
53 import org.netbeans.api.java.source.TreeMaker;
54 import org.netbeans.api.java.source.TypeMirrorHandle;
55 import org.netbeans.api.java.source.WorkingCopy;
56 import org.netbeans.modules.editor.java.Utilities;
57 import org.netbeans.modules.java.hints.ImportClassEnabler.ImportCandidatesHolder;
58 import org.netbeans.modules.java.hints.spi.ErrorRule;
59 import org.netbeans.spi.editor.hints.ChangeInfo;
60 import org.netbeans.spi.editor.hints.ErrorDescriptionFactory;
61 import org.netbeans.spi.editor.hints.Fix;
62 import org.netbeans.spi.editor.hints.LazyFixList;
63 import org.openide.ErrorManager;
64
65 /**
66  *
67  * @author Jan Lahoda
68  */

69 public final class UncaughtExceptionCreator implements ErrorRule<Void JavaDoc> {
70     
71     /**
72      * Creates a new instance of UncaughtExceptionCreator
73      */

74     public UncaughtExceptionCreator() {
75     }
76
77     private List JavaDoc<? extends TypeMirror> findUncauchedExceptions(CompilationInfo info, TreePath path, List JavaDoc<? extends TypeMirror> exceptions) {
78         List JavaDoc<TypeMirror> result = new ArrayList JavaDoc<TypeMirror>();
79         
80         result.addAll(exceptions);
81         
82         while (path != null) {
83             Element currentElement = info.getTrees().getElement(path);
84             
85             if (currentElement != null && EXECUTABLE_ELEMENTS.contains(currentElement.getKind())) {
86                 ExecutableElement ee = (ExecutableElement) currentElement;
87                 
88                 result.removeAll(ee.getThrownTypes());
89                 break;
90             }
91             
92             Tree currentTree = path.getLeaf();
93             
94             if (currentTree.getKind() == Kind.TRY) {
95                 TryTree tt = (TryTree) currentTree;
96                 
97                 for (CatchTree c : tt.getCatches()) {
98                     TreePath catchPath = new TreePath(new TreePath(path, c), c.getParameter());
99                     VariableElement variable = (VariableElement) info.getTrees().getElement(catchPath);
100                     
101                     result.remove(variable.asType());
102                 }
103             }
104             
105             path = path.getParentPath();
106         }
107         
108         return result;
109     }
110     
111     public Set JavaDoc<String JavaDoc> getCodes() {
112         return Collections.singleton("compiler.err.unreported.exception.need.to.catch.or.throw");
113     }
114     
115     public List JavaDoc<Fix> run(CompilationInfo info, String JavaDoc diagnosticKey, int offset, TreePath treePath, Data<Void JavaDoc> data) {
116         List JavaDoc<Fix> result = new ArrayList JavaDoc<Fix>();
117         TreePath path = info.getTreeUtilities().pathFor(offset + 1);
118         List JavaDoc<? extends TypeMirror> uncauched = null;
119         Element el;
120         
121         OUTTER: while (path != null) {
122             Tree leaf = path.getLeaf();
123             
124             switch (leaf.getKind()) {
125                 case NEW_CLASS:
126                 case METHOD_INVOCATION:
127                     el = info.getTrees().getElement(path);
128                     if (el != null && EXECUTABLE_ELEMENTS.contains(el.getKind())) {
129                         uncauched = ((ExecutableElement) el).getThrownTypes();
130                     }
131                     path = path.getParentPath();
132                     break OUTTER;
133                 case THROW:
134                     TypeMirror uncaughtException = info.getTrees().getTypeMirror(new TreePath(path, ((ThrowTree) leaf).getExpression()));
135                     uncauched = Collections.singletonList(uncaughtException);
136                     break OUTTER;
137             }
138             
139             path = path.getParentPath();
140         }
141         
142         if (uncauched != null) {
143             uncauched = findUncauchedExceptions(info, path, uncauched);
144             
145             TreePath pathRec = path;
146             
147             while (pathRec != null && pathRec.getLeaf().getKind() != Kind.METHOD) {
148                 pathRec = pathRec.getParentPath();
149             }
150             
151             ExecutableElement method = pathRec != null ? (ExecutableElement) info.getTrees().getElement(pathRec) : null;
152             
153             if (method != null) {
154                 for (TypeMirror tm : uncauched) {
155                     if (tm.getKind() != TypeKind.ERROR)
156                         result.add(new AddThrowsClauseHintImpl(info.getJavaSource(), Utilities.getTypeName(tm, true).toString(), TypeMirrorHandle.create(tm), ElementHandle.create(method)));
157                 }
158             }
159             
160             if (!uncauched.isEmpty()) {
161                 List JavaDoc<TypeMirrorHandle> thandles = new ArrayList JavaDoc<TypeMirrorHandle>();
162                 
163                 for (TypeMirror tm : uncauched) {
164                     if (tm.getKind() != TypeKind.ERROR)
165                         thandles.add(TypeMirrorHandle.create(tm));
166                 }
167                 result.add(new MagicSurroundWithTryCatch(info.getJavaSource(), thandles, offset));
168             }
169         }
170         
171         return result;
172     }
173     
174     public void cancel() {
175         //XXX: not done yet
176
}
177     
178     public String JavaDoc getId() {
179         return UncaughtExceptionCreator.class.getName();
180     }
181     
182     public String JavaDoc getDisplayName() {
183         return "Add Throws Clause and Surround With try-catch Fixes";
184     }
185     
186     public String JavaDoc getDescription() {
187         return "Add Throws Clause and Surround With try-catch Fixes";
188     }
189     
190     private static final Set JavaDoc<ElementKind> EXECUTABLE_ELEMENTS = EnumSet.of(ElementKind.CONSTRUCTOR, ElementKind. METHOD);
191     
192     private static final class AddThrowsClauseHintImpl implements Fix {
193         
194         private JavaSource js;
195         private String JavaDoc fqn;
196         private TypeMirrorHandle thandle;
197         private ElementHandle<ExecutableElement> method;
198         
199         public AddThrowsClauseHintImpl(JavaSource js, String JavaDoc fqn, TypeMirrorHandle thandle, ElementHandle<ExecutableElement> method) {
200             this.js = js;
201             this.fqn = fqn;
202             this.thandle = thandle;
203             this.method = method;
204         }
205         
206         public String JavaDoc getText() {
207             return "Add throws clause for " + fqn;
208         }
209         
210         public ChangeInfo implement() {
211             try {
212                 js.runModificationTask(new CancellableTask<WorkingCopy>() {
213                     public void cancel() {
214                     }
215                     public void run(WorkingCopy wc) throws Exception JavaDoc {
216                         wc.toPhase(Phase.RESOLVED);
217                         Tree tree = wc.getTrees().getTree(method.resolve(wc));
218                         
219                         assert tree != null;
220                         assert tree.getKind() == Kind.METHOD;
221                         
222                         MethodTree nue = wc.getTreeMaker().addMethodThrows((MethodTree) tree, (ExpressionTree) wc.getTreeMaker().Type(thandle.resolve(wc)));
223                         
224                         wc.rewrite(tree, nue);
225                     }
226                 }).commit();
227             } catch (IOException JavaDoc e) {
228                 ErrorManager.getDefault().notify(e);
229             }
230             return null;
231         }
232         
233     }
234     
235     private static final class SurroundWithTryCatch implements Fix {
236         
237         private JavaSource js;
238         private List JavaDoc<TypeMirrorHandle> thandles;
239         private int offset;
240         
241         public SurroundWithTryCatch(JavaSource js, List JavaDoc<TypeMirrorHandle> thandles, int offset) {
242             this.js = js;
243             this.thandles = thandles;
244             this.offset = offset;
245         }
246         
247         public String JavaDoc getText() {
248             return "Surround with try-catch";
249         }
250         
251         public ChangeInfo implement() {
252             try {
253                 js.runModificationTask(new CancellableTask<WorkingCopy>() {
254                     public void cancel() {
255                     }
256                     public void run(WorkingCopy wc) throws Exception JavaDoc {
257                         wc.toPhase(Phase.RESOLVED);
258                         TreePath currentPath = wc.getTreeUtilities().pathFor(offset + 1);
259                         
260                         //find statement:
261
while (currentPath != null && !STATEMENT_KINDS.contains(currentPath.getLeaf().getKind()))
262                             currentPath = currentPath.getParentPath();
263                         
264                         TreeMaker make = wc.getTreeMaker();
265                         Tree t = currentPath.getLeaf();
266                         BlockTree bt = make.Block(Collections.singletonList((StatementTree) t), false);
267                         List JavaDoc<CatchTree> catches = new ArrayList JavaDoc<CatchTree>();
268                         
269                         for (TypeMirrorHandle th : thandles) {
270                             catches.add(make.Catch(make.Variable(make.Modifiers(EnumSet.noneOf(Modifier.class)), "ex", make.Type(th.resolve(wc)), null), make.Block(Collections.<StatementTree>emptyList(), false)));
271                         }
272                         wc.rewrite(t, make.Try(bt, catches, null));
273                     }
274                 }).commit();
275             } catch (IOException JavaDoc e) {
276                 ErrorManager.getDefault().notify(e);
277             }
278             return null;
279         }
280         
281     }
282     
283     static final Set JavaDoc<Kind> STATEMENT_KINDS;
284     
285     static {
286         Set JavaDoc<Kind> kinds = new HashSet JavaDoc<Kind>();
287         
288         for (Kind k : Kind.values()) {
289             Class JavaDoc c = k.asInterface();
290             
291             if (c != null && StatementTree.class.isAssignableFrom(c)) {
292                 kinds.add(k);
293             }
294         }
295         
296         STATEMENT_KINDS = Collections.unmodifiableSet(EnumSet.copyOf(kinds));
297     }
298     
299 }
300
Popular Tags