/* * 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.st4.experimental; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Arrays; import java.util.Deque; import java.util.List; import java.util.concurrent.CancellationException; import java.util.concurrent.atomic.AtomicBoolean; import org.antlr.netbeans.editor.completion.AbstractAnchor; import org.antlr.netbeans.editor.completion.Anchor; import org.antlr.netbeans.editor.text.DocumentSnapshot; import org.antlr.netbeans.editor.text.TrackingPositionRegion; import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.works.editor.st4.experimental.generated.TemplateParser; import org.antlr.works.editor.st4.experimental.generated.TemplateParserBaseListener; import org.netbeans.api.annotations.common.NonNull; import org.openide.util.Parameters; /** * * @author Sam Harwell */ public class TemplateParserAnchorListener extends TemplateParserBaseListener { private final Deque<Integer> anchorPositions = new ArrayDeque<>(); private final List<Anchor> anchors = new ArrayList<>(); private final DocumentSnapshot snapshot; private final AtomicBoolean cancel; public TemplateParserAnchorListener(DocumentSnapshot snapshot) { Parameters.notNull("snapshot", snapshot); this.snapshot = snapshot; this.cancel = null; } public TemplateParserAnchorListener(DocumentSnapshot snapshot, AtomicBoolean cancel) { Parameters.notNull("snapshot", snapshot); this.snapshot = snapshot; this.cancel = cancel; } public List<Anchor> getAnchors() { return anchors; } private void checkCancellation() { boolean cancelled; if (cancel != null) { cancelled = cancel.get(); } else { cancelled = Thread.interrupted(); } if (cancelled) { throw new CancellationException(); } } @Override public void enterEveryRule(ParserRuleContext ctx) { checkCancellation(); } @Override public void exitEveryRule(ParserRuleContext ctx) { checkCancellation(); } // @Override // public void enterRule(GrammarParser.grammarTypeContext ctx) { // enterAnchor(ctx); // } // // @Override // public void exitRule(GrammarParser.grammarTypeContext ctx) { // exitAnchor(ctx, GrammarParser.RULE_grammarType); // } // // @Override // public void enterRule(GrammarParser.ruleContext ctx) { // enterAnchor(ctx); // } // // @Override // public void exitRule(GrammarParser.ruleContext ctx) { // exitAnchor(ctx, GrammarParser.RULE_rule); // } // // @Override // public void enterRule(GrammarParser.tokenSpecContext ctx) { // enterAnchor(ctx); // } // // @Override // public void exitRule(GrammarParser.tokenSpecContext ctx) { // exitAnchor(ctx, GrammarParser.RULE_tokenSpec); // } private void enterAnchor(ParserRuleContext ctx) { anchorPositions.push(ctx.getStart().getStartIndex()); } private void exitAnchor(ParserRuleContext ctx, int anchorId) { int start = anchorPositions.pop(); int stop = ctx.getStop() != null ? ctx.getStop().getStopIndex() + 1 : snapshot.length(); TrackingPositionRegion.Bias trackingMode = ctx.getStop() != null ? TrackingPositionRegion.Bias.Exclusive : TrackingPositionRegion.Bias.Forward; anchors.add(createAnchor(ctx, start, stop, trackingMode, anchorId)); } private Anchor createAnchor(ParserRuleContext ctx, int start, int stop, TrackingPositionRegion.Bias trackingMode, int rule) { TrackingPositionRegion trackingSpan = snapshot.createTrackingRegion(start, stop - start, trackingMode); // if (rule == TemplateParser.RULE_grammarType) { // return new TemplateTypeAnchor((GrammarParser.grammarTypeContext)ctx, trackingSpan); // } else { return new TemplateAnchor(trackingSpan, rule); // } } public static class TemplateAnchor extends AbstractAnchor { private TemplateAnchor(@NonNull TrackingPositionRegion span, int rule) { super(span, rule); } @Override protected List<String> getRuleNames() { return Arrays.asList(TemplateParser.ruleNames); } } // public static class TemplateTypeAnchor extends TemplateAnchor { // // private final int templateType; // // private TemplateTypeAnchor(grammarTypeContext ctx, TrackingPositionRegion span) { // super(span, GrammarParser.RULE_grammarType); // if (ctx.t == null) { // grammarType = GrammarParser.COMBINED; // } else { // grammarType = ctx.t.getType(); // } // } // // public int getTemplateType() { // return templateType; // } // } }