1 19 package org.netbeans.modules.java.editor.semantic; 20 21 import com.sun.source.tree.ClassTree; 22 import com.sun.source.tree.CompilationUnitTree; 23 import com.sun.source.tree.IdentifierTree; 24 import com.sun.source.tree.MemberSelectTree; 25 import com.sun.source.tree.MethodTree; 26 import com.sun.source.tree.PrimitiveTypeTree; 27 import com.sun.source.tree.Tree; 28 import com.sun.source.util.SourcePositions; 29 import com.sun.source.util.TreePath; 30 import java.awt.Color ; 31 import java.beans.PropertyChangeEvent ; 32 import java.io.IOException ; 33 import java.util.Collections ; 34 import java.util.Set ; 35 import java.util.logging.Level ; 36 import java.util.logging.Logger ; 37 import javax.lang.model.element.Element; 38 import javax.swing.event.CaretEvent ; 39 import javax.swing.text.Document ; 40 import javax.swing.text.JTextComponent ; 41 import org.netbeans.api.java.source.CancellableTask; 42 import org.netbeans.api.java.source.CompilationInfo; 43 import org.netbeans.api.timers.TimesCollector; 44 import org.netbeans.modules.editor.highlights.spi.Highlight; 45 import org.netbeans.modules.editor.highlights.spi.Highlighter; 46 import org.openide.ErrorManager; 47 import org.openide.cookies.EditorCookie; 48 import org.openide.filesystems.FileObject; 49 import org.openide.filesystems.FileUtil; 50 import org.openide.loaders.DataObject; 51 52 56 public class MarkOccurencesHighlighter implements CancellableTask<CompilationInfo> { 57 58 private FileObject file; 59 60 61 MarkOccurencesHighlighter(FileObject file) { 62 this.file = file; 63 } 64 65 public static final Color ES_COLOR = new Color ( 175, 172, 102 ); 67 public Document getDocument() { 68 try { 69 DataObject d = DataObject.find(file); 70 EditorCookie ec = (EditorCookie) d.getCookie(EditorCookie.class); 71 72 if (ec == null) 73 return null; 74 75 return ec.getDocument(); 76 } catch (IOException e) { 77 Logger.getLogger(MarkOccurencesHighlighter.class.getName()).log(Level.INFO, "SemanticHighlighter: Cannot find DataObject for file: " + FileUtil.getFileDisplayName(file), e); 78 return null; 79 } 80 } 81 82 public void run(CompilationInfo info) { 83 resume(); 84 85 Document doc = getDocument(); 86 87 if (doc == null) { 88 Logger.getLogger(MarkOccurencesHighlighter.class.getName()).log(Level.INFO, "SemanticHighlighter: Cannot get document!"); 89 return ; 90 } 91 92 long start = System.currentTimeMillis(); 93 94 int caretPosition = MarkOccurrencesHighlighterFactory.getLastPosition(file); 95 96 if (isCancelled()) 97 return; 98 99 Set <Highlight> highlights = processImpl(info, doc, caretPosition); 100 101 if (isCancelled()) 102 return; 103 104 TimesCollector.getDefault().reportTime(((DataObject) doc.getProperty(Document.StreamDescriptionProperty)).getPrimaryFile(), "occurrences", "Occurrences", (System.currentTimeMillis() - start)); 105 106 Highlighter.getDefault().setHighlights(file, "occurrences", highlights); 107 OccurrencesMarkProvider.get(doc).setOccurrences(highlights); 108 } 109 110 private boolean isIn(CompilationUnitTree cu, SourcePositions sp, Tree tree, int position) { 111 return sp.getStartPosition(cu, tree) <= position && position <= sp.getEndPosition(cu, tree); 112 } 113 114 private boolean isIn(int caretPosition, int[] span) { 115 return span[0] <= caretPosition && caretPosition <= span[1]; 119 } 120 121 Set <Highlight> processImpl(CompilationInfo info, Document doc, int caretPosition) { 122 CompilationUnitTree cu = info.getCompilationUnit(); 123 Tree lastTree = null; 124 Set <Highlight> localUsages = null; 125 TreePath tp = info.getTreeUtilities().pathFor(caretPosition); 126 while(tp != null) { 127 if (isCancelled()) 128 return Collections.emptySet(); 129 130 Tree tree = tp.getLeaf(); 131 if (tree instanceof MethodTree && (lastTree instanceof IdentifierTree 133 || lastTree instanceof PrimitiveTypeTree 134 || lastTree instanceof MemberSelectTree)) { 135 MethodTree decl = (MethodTree) tree; 137 Tree type = decl.getReturnType(); 138 139 if (isIn(cu, info.getTrees().getSourcePositions(), type, caretPosition)) { 140 MethodExitDetector med = new MethodExitDetector(); 141 142 setExitDetector(med); 143 144 try { 145 return med.process(info, doc, decl, null); 146 } finally { 147 setExitDetector(null); 148 } 149 } 150 151 for (Tree exc : decl.getThrows()) { 152 if (isIn(cu, info.getTrees().getSourcePositions(), exc, caretPosition)) { 153 MethodExitDetector med = new MethodExitDetector(); 154 155 setExitDetector(med); 156 157 try { 158 return med.process(info, doc, decl, Collections.singletonList(exc)); 159 } finally { 160 setExitDetector(null); 161 } 162 } 163 } 164 } 165 166 if (localUsages != null) 167 return localUsages; 168 169 Element el = info.getTrees().getElement(tp); 171 if ( el != null 172 && (!(tree instanceof ClassTree) || isIn(caretPosition, Utilities.findIdentifierSpan(tp, cu, info.getTrees().getSourcePositions(), doc))) 173 && !Utilities.isKeyword(tree) 174 && (!(tree instanceof MethodTree) || lastTree == null)) { 175 FindLocalUsagesQuery fluq = new FindLocalUsagesQuery(); 176 177 setLocalUsages(fluq); 178 179 try { 180 localUsages = fluq.findUsages(el, info, doc); 181 } finally { 182 setLocalUsages(null); 183 } 184 } 185 lastTree = tree; 186 tp = tp.getParentPath(); 187 } 188 189 if (localUsages != null) 190 return localUsages; 191 192 return Collections.emptySet(); 193 } 194 195 private boolean canceled; 196 private MethodExitDetector exitDetector; 197 private FindLocalUsagesQuery localUsages; 198 199 private final synchronized void setExitDetector(MethodExitDetector detector) { 200 this.exitDetector = detector; 201 } 202 203 private final synchronized void setLocalUsages(FindLocalUsagesQuery localUsages) { 204 this.localUsages = localUsages; 205 } 206 207 public final synchronized void cancel() { 208 canceled = true; 209 210 if (exitDetector != null) { 211 exitDetector.cancel(); 212 } 213 if (localUsages != null) { 214 localUsages.cancel(); 215 } 216 } 217 218 protected final synchronized boolean isCancelled() { 219 return canceled; 220 } 221 222 protected final synchronized void resume() { 223 canceled = false; 224 } 225 226 } 227 | Popular Tags |