org.netbeans.modules.languages.ParserManagerImpl Maven / Gradle / Ivy
The newest version!
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.modules.languages;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import javax.swing.text.AbstractDocument;
import javax.swing.text.Document;
import org.netbeans.api.languages.ASTEvaluator;
import org.netbeans.api.languages.ASTEvaluator;
import org.netbeans.api.languages.ASTItem;
import org.netbeans.api.languages.ASTPath;
import org.netbeans.api.languages.ParserManager;
import org.netbeans.api.languages.ParserManagerListener;
import org.netbeans.api.languages.ASTToken;
import org.netbeans.api.languages.SyntaxContext;
import org.netbeans.api.languages.ParseException;
import org.netbeans.api.lexer.Token;
import org.netbeans.api.lexer.TokenHierarchy;
import org.netbeans.api.lexer.TokenHierarchyEvent;
import org.netbeans.api.lexer.TokenSequence;
import org.netbeans.api.languages.SyntaxContext;
import org.netbeans.api.languages.ASTNode;
import org.netbeans.api.languages.LanguageDefinitionNotFoundException;
import org.netbeans.api.languages.TokenInput;
import org.netbeans.api.lexer.TokenHierarchyListener;
import org.netbeans.modules.languages.lexer.SLanguageHierarchy;
import org.netbeans.modules.languages.lexer.SLexer;
import org.netbeans.modules.languages.parser.LLSyntaxAnalyser;
import org.netbeans.modules.languages.parser.SyntaxError;
import org.netbeans.modules.languages.parser.TokenInputUtils;
import org.netbeans.spi.lexer.MutableTextInput;
import org.openide.util.RequestProcessor;
/**
*
* @author Jan Jancura
*/
public class ParserManagerImpl extends ParserManager {
private Document document;
private TokenHierarchy tokenHierarchy;
private ASTNode ast = ASTNode.create (null, "Root", 0);
private State state = State.NOT_PARSED;
private List syntaxErrors = Collections.emptyList ();
private boolean[] cancel = new boolean[] {false};
private Set listeners;
private Map> evaluatorsMap;
private static RequestProcessor rp = new RequestProcessor ("Parser");
public ParserManagerImpl (Document doc) {
this.document = doc;
tokenHierarchy = TokenHierarchy.get (doc);
String mimeType = (String) doc.getProperty ("mimeType");
if (tokenHierarchy == null) {
// for tests only....
if (mimeType != null) {
try {
Language language = LanguagesManager.getDefault ().getLanguage (mimeType);
if (language.getParser () != null) {
doc.putProperty (
org.netbeans.api.lexer.Language.class,
new SLanguageHierarchy (language).language ()
);
tokenHierarchy = TokenHierarchy.get (doc);
}
} catch (LanguageDefinitionNotFoundException ex) {
}
}
}
if (tokenHierarchy != null) {
new DocListener (this, tokenHierarchy);
if (mimeType != null && state == State.NOT_PARSED) {
try {
LanguagesManager.getDefault().getLanguage(mimeType);
startParsing();
} catch (LanguageDefinitionNotFoundException e) {
//not supported language
}
}
}
managers.put (doc, new WeakReference (this));
}
public static ParserManagerImpl getImpl (Document document) {
return (ParserManagerImpl) get (document);
}
public State getState () {
return state;
}
public List getSyntaxErrors () {
return syntaxErrors;
}
@Override
public boolean hasSyntaxErrors() {
return !getSyntaxErrors().isEmpty();
}
public ASTNode getAST () {
return ast;
}
public void addListener (ParserManagerListener l) {
if (listeners == null) listeners = new HashSet ();
listeners.add (l);
}
public void removeListener (ParserManagerListener l) {
if (listeners == null) return;
listeners.remove (l);
}
public void addASTEvaluator (ASTEvaluator e) {
if (evaluatorsMap == null)
evaluatorsMap = new HashMap> ();
Set evaluatorsSet = evaluatorsMap.get (e.getFeatureName ());
if (evaluatorsSet == null) {
evaluatorsSet = new HashSet ();
evaluatorsMap.put (e.getFeatureName (), evaluatorsSet);
}
evaluatorsSet.add (e);
}
public void removeASTEvaluator (ASTEvaluator e) {
if (evaluatorsMap != null) {
Set evaluatorsSet = evaluatorsMap.get (e.getFeatureName ());
if (evaluatorsSet != null)
evaluatorsSet.remove (e);
}
}
public void fire (
final State state,
final List listeners,
final Map> evaluators,
final ASTNode root
) {
if (root == null) throw new NullPointerException ();
parsingTask = rp.post (new Runnable () {
public void run () {
cancel [0] = false;
fire2 (
state,
listeners,
evaluators,
root
);
}
});
}
// private methods .........................................................
private RequestProcessor.Task parsingTask;
private synchronized void startParsing () {
setChange (State.PARSING, ast);
cancel [0] = true;
if (parsingTask != null) {
parsingTask.cancel ();
}
parsingTask = rp.post (new Runnable () {
public void run () {
cancel [0] = false;
parse ();
}
}, 1000);
}
private void setChange (State state, ASTNode root) {
if (state == this.state) return;
this.state = state;
this.ast = root;
List listeners = this.listeners == null ?
null : new ArrayList (this.listeners);
Map> evaluatorsMap = this.evaluatorsMap == null ?
null : new HashMap> (this.evaluatorsMap);
fire2 (state, listeners, evaluatorsMap, root);
}
private void fire2 (
State state,
List listeners,
Map> evaluators,
ASTNode root
) {
if (state == State.PARSING) return;
if (evaluators != null) {
if (!evaluators.isEmpty ()) {
Iterator> it = evaluators.values ().iterator ();
while (it.hasNext ()) {
Iterator it2 = it.next ().iterator ();
while (it2.hasNext ()) {
ASTEvaluator e = it2.next ();
e.beforeEvaluation (state, root);
if (cancel [0]) return;
}
}
//times = new HashMap
© 2015 - 2025 Weber Informatics LLC | Privacy Policy