Skip navigation links
org.netbeans.modules.parsing.api/1 9.24.0 8

Parsing API
Stable

See: Description

Parsing API 
Package Description
org.netbeans.modules.parsing.api
Support for calling of high priority parser based user tasks in multi language environment.
org.netbeans.modules.parsing.spi
Supports registration and automatic scheduling of various parser based tasks.
org.netbeans.modules.parsing.spi.support  

Parsing API defines contract between parsers registerred for diferent languages and the rest of IDE. It is language neutral and it supports language embeddings.

The basic Parsing API constructs are Source, Snapshot and Embedding. Source identificates some concrete file or document. There is always at most one Source for one FileObject. Snapshot represents some concrete content of Source, and it is immutable. And Embedding represents some part of Snapshot written in different language. Embedding can contain some virtual code that is not contained in outside language too. Content of Embedding is represented by Snapshot and it can contain another Embeddings, so embeddings are recursive.

Parser is represented by abstract class called Parser. The only way how to register a new parser for some concrete mime type is to implement ParserFactory, and register it in your manifest file in folder called "Editors/" + mimeType. A new instance of Parser is always created for some concrete Snapshot, or collection of Snapshots. One instance of parser can be reused for more Snapshots created from the same Source. Result of parsing (AST, syntax errors, semantic information) is represented by Parser.Result class. Parser creates a new instance of Parser.Result for each Task. Following example shows how to integrate parser to the NetBeans using Parsing API:

      class FooParserFactory extends ParserFactory {
      
          public Parser createParser (
              Collection<Snapshot> snapshots
          ) {
              return new FooParser ();
          }
          
          private static class FooParser extends Parser {
          
              private boolean         cancelled = false;
              private AST             ast;
              
              public void parse (
                  Snapshot            snapshot, 
                  Task                task, 
                  SchedulerEvent      event
              ) throws ParseException {
                  cancelled = false;
                  for (...) {
                      // parsing snapshot.getText ();
                      if (cancelled) return;
                  }
                  ast = ...;
              }
              
              public abstract Result getResult (
                  Task                task,
                  SchedulerEvent      event
              ) throws ParseException {
                  return new FooResult (ast);
              }

              public void cancel () {
                  cancelled = true;
              }

              public void addChangeListener (
                  ChangeListener      changeListener
              ) {
              }

              public void removeChangeListener (
                  ChangeListener      changeListener
              ) {
              }
          }
          
          public static class FooResult extends Result {
            
              private AST           ast;
              private boolean       valid = true;
              
              FooResult (
                  AST               ast
              ) {
                  this.ast = ast;
              }
              
              public AST getAST () {
                  if (!valid) throw new InvalidResultException ();
                  return ast;
              }
              
              public void invalidate () {
                  valid = false;
                  ast = null;
              }
          }
      }
      

Parsing API defines two basic kinds of Tasks. High priority UserTasks and SchedulerTasks.

Execution of UserTask is synchnonous and it stops execution of all other tasks. There are two types of UserTask. Simple UserTask that supports some computations based on one block code written in one language. And MultiLanguageUserTask (???) that supports scanning of all blocks of code written in different languages embedded in one Source.

User of Parsing API can register various implementations of SchedulerTask for any language. Each SchedulerTask is registered for some specific Scheduler. Scheduler defines when task shoud be started (for example when current editor is changed, when some nodes are selected in Project View, or when cursor position is changed).

There are two specific tasks that can define language embedding. So task implementator can recognize blocks of embedded languages. Parsing API contains support for high priority ParsingAPI

What is New (see all changes)?

Use Cases

  1. Parsing API Client can always ask for parser result. This direct call has top level priority (stops all other requests). Its designed to support direct user to IDE interaction (like request for code completion) that have to be as fast as possible. Such type of task is called UserTask. This approach is used not only for parsing of file currently edited in Editor, but it supports Refactoring too.
  2. Parsing API Implementation listens on various changes in IDE (typing in the current document, cursor movements, switching of editor tabs, changes of classpath). These changes affects parse tree of the current document, and various visualisation features based on parser results (text coloring, hints, error stripe). Parsing API Client can register some tasks that should run when such change is done (Task). Implemementation of Parsing API than calls all such registerred tasks. These calls has lower priority than UserTasks, and they should not block user interaction with IDE (typing in editor).
  3. Parsing API defines how to recognize embedded languages. It should be possible to create snapshot of some file, call some recognizers that finds blocks of embedded languages and run different parsers for embedded blocks. It should be able to use the same parser for top level language and any embedded block of code written in the same language. Embedding recognizer can add some virtual code (code that does not exists in top level source) to the embedded block. There should be some support for translation of offsets between top level source and virtual source generated for embedded piece of code.

Exported Interfaces

This table lists all of the module exported APIs with defined stability classifications. It is generated based on answers to questions about the architecture of the module. Read them all...
Group of java interfaces
Interface NameIn/OutStabilitySpecified in What Document?
ParsingAPIExportedStableindex.html

Group of logger interfaces
Interface NameIn/OutStabilitySpecified in What Document?
org.netbeans.ui.indexingExportedUnder Development

Since version 1.47 the RepositorUpdater cooperates with UI Gestures Collector by sending following messages to the org.netbeans.ui.indexing logger:
  • INDEXING_STARTED - message about a start of indexing (up to date check). Arguments:
    • {0}: Long - the time from the last indexing
  • INDEXING_FINISHED - message about an end of indexing (up to date check). Arguments:
    • {0}: Long - the time of indexing
    • For each indexer following 3 records are logged
      • {1}: String - name of indexer
      • {2}: Integer - indexer invocation count
      • {3}: Integer - indexing time spent in given indexer

Implementation Details

Where are the sources for the module?

The sources for the module are in the Apache Git repositories or in the GitHub repositories.

What do other modules need to do to declare a dependency on this one, in addition to or instead of a plain module dependency?

XXX no answer for deploy-dependencies

Read more about the implementation in the answers to architecture questions.

Skip navigation links
org.netbeans.modules.parsing.api/1 9.24.0 8