@Override public Map<String, List<OffsetRange>> folds(ParserResult info) { ASTNode root = ASTUtils.getRoot(info); if (root == null) { return Collections.emptyMap(); } GroovyParserResult rpr = ASTUtils.getParseResult(info); AnalysisResult analysisResult = rpr.getStructure(); Map<String, List<OffsetRange>> folds = new HashMap<String, List<OffsetRange>>(); List<OffsetRange> codefolds = new ArrayList<OffsetRange>(); folds.put("codeblocks", codefolds); // NOI18N final BaseDocument doc = LexUtilities.getDocument(rpr, false); if (doc == null) { return Collections.emptyMap(); } final OffsetRange[] importsRange = new OffsetRange[1]; final List<OffsetRange> commentsRanges = new ArrayList<OffsetRange>(); doc.render( new Runnable() { @Override public void run() { TokenSequence<?> ts = LexUtilities.getGroovyTokenSequence(doc, 1); int importStart = 0; int importEnd = 0; boolean startSet = false; while (ts != null && ts.isValid() && ts.moveNext()) { Token t = ts.token(); if (t.id() == GroovyTokenId.LITERAL_import) { int offset = ts.offset(); if (!startSet) { importStart = offset; startSet = true; } importEnd = offset; } else if (t.id() == GroovyTokenId.BLOCK_COMMENT) { // does this Block comment (GSF_BLOCK_COMMENT) span // multiple lines? E.g. includes \n ? StringBuffer sb = new StringBuffer(t.text()); if (sb.indexOf("\n") != -1) { int offset = ts.offset(); commentsRanges.add(new OffsetRange(offset, offset + t.length())); } } } try { importEnd = Utilities.getRowEnd(doc, importEnd); importsRange[0] = new OffsetRange(importStart, importEnd); } catch (BadLocationException ble) { Exceptions.printStackTrace(ble); } } }); if (!commentsRanges.isEmpty()) { folds.put("comments", commentsRanges); // NOI18N } try { if (importsRange[0] != null && Utilities.getRowCount(doc, importsRange[0].getStart(), importsRange[0].getEnd()) > 1) { folds.put("imports", Collections.singletonList(importsRange[0])); // NOI18N } addFolds(doc, analysisResult.getElements(), folds, codefolds); } catch (BadLocationException ex) { Exceptions.printStackTrace(ex); } return folds; }
private AnalysisResult scan(GroovyParserResult result) { AnalysisResult analysisResult = new AnalysisResult(); ASTNode root = ASTUtils.getRoot(result); if (root == null) { return analysisResult; } structure = new ArrayList<ASTElement>(); fields = new HashMap<ASTClass, Set<FieldNode>>(); methods = new ArrayList<ASTMethod>(); properties = new HashMap<ASTClass, Set<PropertyNode>>(); AstPath path = new AstPath(); path.descend(root); // TODO: I should pass in a "default" context here to stash methods etc. outside of modules and // classes scan(result, root, path, null, null, null); path.ascend(); // Process fields Map<String, FieldNode> names = new HashMap<String, FieldNode>(); for (ASTClass clz : fields.keySet()) { Set<FieldNode> assignments = fields.get(clz); // Find unique variables if (assignments != null) { for (FieldNode assignment : assignments) { names.put(assignment.getName(), assignment); } // Add unique fields for (FieldNode field : names.values()) { ASTField co = new ASTField(result, field); // co.setIn(AstUtilities.getClassOrModuleName(clz)); co.setIn(clz.getFqn()); // Make sure I don't already have an entry for this field as an // attr_accessor or writer String fieldName = field.getName(); boolean found = false; Set<PropertyNode> nodes = properties.get(clz); if (nodes != null) { for (PropertyNode node : nodes) { if (fieldName.equals(node.getName())) { found = true; break; } } } if (found) { co.setProperty(true); } clz.addChild(co); } names.clear(); } } analysisResult.setElements(structure); return analysisResult; }