1 19 20 package org.netbeans.modules.languages.features; 21 22 import java.util.Set ; 23 import org.netbeans.api.languages.ASTEvaluator; 24 import org.netbeans.api.languages.ASTToken; 25 import org.netbeans.api.languages.LanguagesManager; 26 import org.netbeans.api.languages.ParseException; 27 import org.netbeans.api.languages.ASTPath; 28 import org.netbeans.api.languages.ParserManager.State; 29 import org.netbeans.api.languages.SyntaxContext; 30 import org.netbeans.api.editor.fold.Fold; 31 import org.netbeans.api.editor.fold.FoldHierarchy; 32 import org.netbeans.api.editor.fold.FoldType; 33 import org.netbeans.api.languages.SyntaxContext; 34 import org.netbeans.api.languages.ASTNode; 35 import org.netbeans.api.languages.ASTItem; 36 import org.netbeans.api.languages.ParseException; 37 import org.netbeans.api.lexer.Token; 38 import org.netbeans.api.lexer.TokenSequence; 39 import org.netbeans.modules.languages.Feature; 40 import org.netbeans.spi.editor.fold.FoldHierarchyTransaction; 41 import org.netbeans.spi.editor.fold.FoldManager; 42 import org.netbeans.spi.editor.fold.FoldManagerFactory; 43 import org.netbeans.spi.editor.fold.FoldOperation; 44 import org.openide.text.NbDocument; 45 import org.netbeans.modules.editor.NbEditorDocument; 46 import org.netbeans.modules.languages.Language; 47 import org.netbeans.modules.languages.LanguagesManagerImpl; 48 import org.netbeans.modules.languages.ParserManagerImpl; 49 import java.util.ArrayList ; 50 import javax.swing.SwingUtilities ; 51 import javax.swing.text.Document ; 52 import javax.swing.event.DocumentEvent ; 53 import javax.swing.text.BadLocationException ; 54 import java.util.Iterator ; 55 import java.util.List ; 56 import org.netbeans.api.lexer.TokenHierarchy; 57 58 59 63 public class LanguagesFoldManager extends ASTEvaluator implements FoldManager { 64 65 private FoldOperation operation; 66 private NbEditorDocument doc; 67 68 69 70 public LanguagesFoldManager () { 71 } 72 73 78 public void init (FoldOperation operation) { 79 Document d = operation.getHierarchy ().getComponent ().getDocument (); 80 if (d instanceof NbEditorDocument) { 81 this.operation = operation; 82 doc = (NbEditorDocument) d; 83 ParserManagerImpl.get (doc).addASTEvaluator (this); 84 } 85 } 86 87 107 public void initFolds (FoldHierarchyTransaction transaction) { 108 } 109 110 120 public void insertUpdate (DocumentEvent evt, FoldHierarchyTransaction transaction) { 121 } 122 123 133 public void removeUpdate (DocumentEvent evt, FoldHierarchyTransaction transaction) { 134 } 135 136 146 public void changedUpdate (DocumentEvent evt, FoldHierarchyTransaction transaction) { 147 } 148 149 154 public void removeEmptyNotify (Fold epmtyFold) { 155 } 156 157 162 public void removeDamagedNotify (Fold damagedFold) { 163 } 164 165 171 public void expandNotify (Fold expandedFold) { 172 } 173 174 185 public void release () { 186 if (doc != null) 188 ParserManagerImpl.get (doc).removeASTEvaluator (this); 189 } 190 191 192 194 195 private static FoldType defaultFoldType = new FoldType ("default"); 196 private List <FoldItem> folds; 197 198 public void beforeEvaluation (State state, ASTNode root) { 199 folds = new ArrayList <FoldItem> (); 200 } 201 202 public void afterEvaluation (State state, ASTNode root) { 203 SwingUtilities.invokeLater (new Runnable () { 204 public void run () { 205 FoldHierarchy hierarchy = operation.getHierarchy (); 206 FoldHierarchyTransaction transaction = operation.openTransaction (); 207 try { 208 Fold fold = operation.getHierarchy ().getRootFold (); 209 List <Fold> l = new ArrayList <Fold> (fold.getFoldCount ()); 210 int i, k = fold.getFoldCount (); 211 for (i = 0; i < k; i++) 212 l.add (fold.getFold (i)); 213 for (i = 0; i < k; i++) 214 operation.removeFromHierarchy (l.get (i), transaction); 215 Iterator <FoldItem> it = folds.iterator (); 216 while (it.hasNext ()) { 217 FoldItem f = it.next (); 218 operation.addToHierarchy ( 219 f.type, f.foldName, false, f.start, f.end, 0, 0, 220 hierarchy, transaction 221 ); 222 } 223 } catch (BadLocationException ex) { 224 ex.printStackTrace (); 225 } finally { 226 transaction.commit (); 227 } 228 } 229 }); 230 } 231 232 public void evaluate (State state, ASTPath path) { 233 try { 234 ASTItem item = path.getLeaf (); 235 int s = item.getOffset (), 236 e = item.getEndOffset (); 237 int sln = NbDocument.findLineNumber (doc, s), 238 eln = NbDocument.findLineNumber (doc, e); 239 if (sln == eln) return; 240 String mimeType = item.getMimeType (); 241 Language language = ((LanguagesManagerImpl) LanguagesManager.getDefault ()). 242 getLanguage (mimeType); 243 List <Feature> fls = language.getFeatures (Language.FOLD, path); 244 if (fls == null || fls.isEmpty()) { 245 return; 246 } 247 Feature fold = fls.get(0); 248 boolean isTokenFold = (fls.size() == 1 && (item instanceof ASTToken) && 249 fold == language.getFeature(Language.FOLD, ((ASTToken) item).getType())); 250 if (!isTokenFold) { 251 TokenHierarchy th = TokenHierarchy.get (doc); 252 TokenSequence ts = th.tokenSequence (); 253 ts.move (e - 1); 254 if (!ts.moveNext ()) return; 255 while (!ts.language ().mimeType ().equals (mimeType)) { 256 ts = ts.embedded (); 257 if (ts == null) return; 258 ts.move (e - 1); 259 if (!ts.moveNext ()) return; 260 } 261 Token t = ts.token (); 262 Set <String > skip = language.getSkipTokenTypes (); 263 while (skip.contains (t.id ().name ())) { 264 if (!ts.movePrevious ()) break; 265 t = ts.token (); 266 } 267 ts.moveNext (); 268 e = ts.offset (); 269 sln = NbDocument.findLineNumber (doc, s); 270 eln = NbDocument.findLineNumber (doc, e); 271 if (eln - sln < 1) return; 272 } 273 274 if (fold.hasSingleValue ()) { 275 String foldName = (String ) fold.getValue (SyntaxContext.create (doc, path)); 276 if (foldName == null) return; 277 folds.add (new FoldItem(foldName, s, e, defaultFoldType)); 278 return; 279 } 280 String foldName = (String ) fold.getValue ("fold_display_name", SyntaxContext.create (doc, path)); 281 if (foldName == null) foldName = "..."; 282 String foldType = (String ) fold.getValue ("collapse_type_action_name"); 283 folds.add (new FoldItem (foldName, s, e, Folds.getFoldType (foldType))); 284 } catch (ParseException ex) { 285 } 286 } 287 288 289 291 private static final class FoldItem { 292 String foldName; 293 int start; 294 int end; 295 FoldType type; 296 297 FoldItem (String foldName, int start, int end, FoldType type) { 298 this.foldName = foldName; 299 this.start = start; 300 this.end = end; 301 this.type = type; 302 } 303 } 304 305 public static final class Factory implements FoldManagerFactory { 306 307 public FoldManager createFoldManager () { 308 return new LanguagesFoldManager (); 309 } 310 311 } 312 } 313 | Popular Tags |