org.netbeans.modules.csl.api.StructureScanner

When using the CSL API, you should not use org.netbeans.spi.editor.fold.FoldManager directly. It is too heavyweight, when compared to the alternative provided by the CSL API:  org.netbeans.modules.csl.api.StructureScanner.

If you have a class like this, i.e., extending org.netbeans.modules.csl.spi.DefaultLanguageConfig and using the org.netbeans.modules.csl.spi.LanguageRegistration annotation, then you can pass in a StructureScanner, as shown below:

package org.simplejava;

import org.netbeans.api.lexer.Language;
import org.netbeans.modules.csl.api.StructureScanner;
import org.netbeans.modules.csl.spi.DefaultLanguageConfig;
import org.netbeans.modules.csl.spi.LanguageRegistration;
import org.netbeans.modules.parsing.spi.Parser;
import org.simplejava.lexer.SJTokenId;
import org.simplejava.parser.SJParser;
import org.simplejava.parser.SJStructureScanner;

@LanguageRegistration(mimeType = "text/x-sj")
public class SJLanguage extends DefaultLanguageConfig {

    @Override
    public Language<SJTokenId> getLexerLanguage() {
        return SJTokenId.getLanguage();
    }

    @Override
    public String getDisplayName() {
        return "SJ";
    }

    @Override
    public Parser getParser() {
        return new SJParser();
    }

    @Override
    public StructureScanner getStructureScanner() {
        return new SJStructureScanner();
    }

    @Override
    public boolean hasStructureScanner() {
        return true;
    }

}

Then here's a dummy implementation of the above:

package org.simplejava.parser;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.netbeans.modules.csl.api.OffsetRange;
import org.netbeans.modules.csl.api.StructureItem;
import org.netbeans.modules.csl.api.StructureScanner;
import org.netbeans.modules.csl.api.StructureScanner.Configuration;
import org.netbeans.modules.csl.spi.ParserResult;

public class SJStructureScanner implements StructureScanner {

    @Override
    public List<? extends StructureItem> scan(ParserResult pr) {
        return new ArrayList<>();
    }

    @Override
    public Map<String, List<OffsetRange>> folds(ParserResult pr) {
        return new HashMap<>();
    }

    @Override
    public Configuration getConfiguration() {
        return null;
    }
    
}

When you look in GsfFoldManager.java, which any CSL plugin automatically includes thanks to the @LanguageRegistration annotation above, you'll see that from the DefaultLanguageConfig extension the StructureScanner is located and an internal FoldManager implementation is used to get the folds defined in StructureScanner.folds(), after which all the necessary things are done for you.

Some default folds are created automatically by the internal FoldManager implementation, such as for the initial comment, as shown below:

As the ParserResult from your parser is passed to the SS.folds() method, you should be able to get the folds since the parser result should contain a parse tree where the code block is described by some node in the tree.

Note: For the above to work, your ParserResult class must extend org.netbeans.modules.csl.spi.ParserResult and NOT org.netbeans.modules.parsing.spi.parser.Result. Just return Collections.EMPTY_LIST from getDiagnostics initially.

Useful implementations:

Thanks to Marek Fukala for help with the above. 
Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

Geertjan Wielenga (@geertjanw) is a Principal Product Manager in the Oracle Developer Tools group living & working in Amsterdam. He is a Java technology enthusiast, evangelist, trainer, speaker, and writer. He blogs here daily.

The focus of this blog is mostly on NetBeans (a development tool primarily for Java programmers), with an occasional reference to NetBeans, and sometimes diverging to topics relating to NetBeans. And then there are days when NetBeans is mentioned, just for a change.

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
12
13
14
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today