/* * Copyright (c) 2012 Sam Harwell, Tunnel Vision Laboratories LLC * All rights reserved. * * The source code of this document is proprietary work, and is not licensed for * distribution. For information about licensing, contact Sam Harwell at: * sam@tunnelvisionlabs.com */ package org.antlr.works.editor.grammar.fold; import java.util.ArrayList; import java.util.List; import org.antlr.grammar.v3.ANTLRParser; import org.antlr.netbeans.editor.text.DocumentSnapshot; import org.antlr.netbeans.editor.text.OffsetRegion; import org.antlr.netbeans.editor.text.SnapshotPositionRegion; import org.antlr.netbeans.parsing.spi.ParserData; import org.antlr.runtime.CommonToken; import org.antlr.runtime.Token; import org.antlr.runtime.tree.CommonTree; import org.antlr.works.editor.antlr3.fold.AbstractAntlrFoldScanner; import org.antlr.works.editor.grammar.parser.CompiledModel; import org.antlr.works.editor.grammar.parser.CompiledModelV3; /** * * @author Sam Harwell */ public class GrammarFoldScannerV3 extends AbstractAntlrFoldScanner<CompiledModel> { @Override protected List<FoldInfo> calculateFolds(ParserData<CompiledModel> baseResult) { CompiledModelV3 result3 = (CompiledModelV3)baseResult.getData(); DocumentSnapshot snapshot = result3.getSnapshot(); final List<FoldInfo> folds = new ArrayList<>(); /*if (!result.getParser().getSyntaxErrors().isEmpty() && !foldManager.currentFolds.isEmpty()) { return; }*/ ANTLRParser.grammar__return parseResult = result3.getResult().getResult(); CommonTree tree = (CommonTree)parseResult.getTree(); if (tree != null) { for (Object childObject : tree.getChildren()) { CommonTree child = (CommonTree)childObject; if (child == null || child.getText() == null || child.getText().isEmpty()) { continue; } if (child.getText().equals("rule") && child.getChildCount() > 0 || child.getText().startsWith("tokens") || child.getText().startsWith("options")) { String blockHint = "..."; if (child.getText().equals("rule")) { String ruleName = child.getChild(0).getText(); // don't try to outline the artificial tokens rule if (ruleName.equals("Tokens")) { continue; } blockHint = child.getChild(0).getText() + "..."; } else if (child.getText().startsWith("tokens")) { // this is the special tokens{} block of a combined grammar blockHint = "tokens {...}"; } else if (child.getText().startsWith("options")) { // this is the special options{} block of a grammar blockHint = "options {...}"; } FoldInfo info = createFold(child, blockHint, snapshot, result3.getResult().getTokens()); if (info != null) { folds.add(info); } } } for (CommonToken token : result3.getResult().getTokens()) { switch (token.getType()) { case ANTLRParser.DOC_COMMENT: case ANTLRParser.ML_COMMENT: case ANTLRParser.ACTION: int startLine = snapshot.findLineNumber(token.getStartIndex()); int stopLine = snapshot.findLineNumber(token.getStopIndex()); if (startLine >= stopLine) { continue; } String blockHint = null; if (token.getType() == ANTLRParser.DOC_COMMENT) { blockHint = "/** ... */"; } else if (token.getType() == ANTLRParser.ML_COMMENT) { blockHint = "/* ... */"; } else if (token.getType() == ANTLRParser.ACTION) { blockHint = "{}"; } else { throw new IllegalStateException(); } SnapshotPositionRegion region = new SnapshotPositionRegion(snapshot, OffsetRegion.fromBounds(token.getStartIndex(), token.getStopIndex() + 1)); FoldInfo info = new FoldInfo(region, blockHint); folds.add(info); break; default: break; } } } return folds; } @Override protected CommonToken getStartToken(CommonTree child, DocumentSnapshot snapshot, CommonToken[] tokens) { CommonToken startToken = super.getStartToken(child, snapshot, tokens); if (startToken.getType() == ANTLRParser.DOC_COMMENT) { for (int index = child.getTokenStartIndex(); index <= child.getTokenStopIndex(); index++) { startToken = tokens[index]; if (startToken.getType() != ANTLRParser.DOC_COMMENT && startToken.getChannel() != Token.HIDDEN_CHANNEL) { break; } } } return startToken; } }