/*
* 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.antlr4.semantics;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingUtilities;
import javax.swing.text.StyledDocument;
import org.antlr.netbeans.editor.text.DocumentSnapshot;
import org.antlr.netbeans.parsing.spi.ParserData;
import org.antlr.netbeans.parsing.spi.ParserDataDefinition;
import org.antlr.v4.runtime.tree.ParseTree;
import org.antlr.v4.runtime.tree.ParseTreeListener;
import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.netbeans.api.annotations.common.NonNull;
import org.netbeans.editor.BaseDocument;
import org.netbeans.spi.editor.highlighting.support.OffsetsBag;
/**
*
* @author Sam Harwell
* @param <Listener>
* @param <Data>
*/
public abstract class AbstractParseTreeSemanticHighlighter<Listener extends ParseTreeListener, Data> extends AbstractSemanticHighlighter<Data> {
// -J-Dorg.antlr.works.editor.antlr4.semantics.AbstractParseTreeSemanticHighlighter.level=FINE
private static final Logger LOGGER = Logger.getLogger(AbstractParseTreeSemanticHighlighter.class.getName());
protected AbstractParseTreeSemanticHighlighter(@NonNull StyledDocument document, ParserDataDefinition<? extends Data> semanticDataDefinition) {
super(document, semanticDataDefinition);
}
protected abstract Listener createListener(@NonNull ParserData<? extends Data> parserData);
protected abstract ParseTree getParseTree(@NonNull final ParserData<? extends Data> parserData);
protected abstract void updateHighlights(OffsetsBag container, DocumentSnapshot sourceSnapshot, DocumentSnapshot currentSnapshot, Listener listener);
protected ParseTreeWalker getParseTreeWalker(@NonNull final ParserData<? extends Data> parserData) {
return ParseTreeWalker.DEFAULT;
}
@Override
protected Callable<Void> createAnalyzerTask(@NonNull final ParserData<? extends Data> parserData) {
return new Callable<Void>() {
@Override
public Void call() {
final Listener listener = createListener(parserData);
if (listener == null) {
return null;
}
try {
ParseTreeWalker.DEFAULT.walk(listener, getParseTree(parserData));
} catch (RuntimeException ex) {
LOGGER.log(Level.WARNING, "An exception occurred while walking the parse tree.", ex);
throw ex;
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
((BaseDocument)getDocument()).render(new Runnable() {
@Override
public void run() {
DocumentSnapshot sourceSnapshot = parserData.getSnapshot();
DocumentSnapshot currentSnapshot = sourceSnapshot.getVersionedDocument().getCurrentSnapshot();
updateHighlights(getContainer(), sourceSnapshot, currentSnapshot, listener);
}
});
}
});
return null;
}
};
}
}