Highlighting for laguage which has extended javascript

Hi,

I am doing syntax highlighting for language wich has the syntax of javascript. I followed the http://devnet.jetbrains.com/message/5450284 tutorial.
I used fileviewprovider and idea ultimate version.
That language is is built extending javascript. Which means it has no symbol to differentiate that language and javascript.
So there is no way to start a new state in the lexer called

<JAVASCRIPT>



example syntax :

///////////////////////////////////////////////////////////////////////
<%


    print("<html><body>");
    print("Method : " + request.getMethod() + "<br/>");
    print("Protocol : " + response.status+ "<br/>");
    print("User-Agent : " + request.getHeader("User-Agent"));
    print("</body></html>");

    session.get("new");
    application.remove('bar');

    var w = "ede";


   %>

//////////////////////////////////////////////////////

How this should be done?

Thanks.!!

4 comments
Comment actions Permalink

Hi,

I feel that I can do that with writing java script library which contains relevent objects and methods.
For an example

I can create request object and getMethod() method in javascript which I can import.





So what I need is just to enable javascript in <%   %> tags

Eg:


start of file...................................................................

SHOULD NOT ENABLE JAVASCRIPT

<%

PURE JAVASCRIPT CODE

%>

SHOULD NOT ENABLE JAVASCRIPT

end of file........................................................................



Your kind help is really appreciated.

Thanks..!!

0
Comment actions Permalink

Have a look at ILazyParseableElementType. I'm not totoally sure - but perhaps you can just create a subclass of it which sets the language to Javascript and use an instance of that as the element type of the token returned by your lexer.

There is also language injection, though I am not very familiar with how to implement it.

0
Comment actions Permalink

Hi,

Thank you for the reply. I did syntax higlighting for javascript in the given tags. It seems that I need to implement the html at out of the given tags.
I got the my syntax highlighting done .  Which means

//////////////////////////////////////////////////////////////////////

html

<%  javascript  %>

html

//////////////////////////////////////////////////////

Is there any good example of implementation of FileViewProvider for this purpose?

0
Comment actions Permalink

Hi,

I could manage to highlight javascript with the support of html outside.
Though the autocompletion of html is possible  syntax of html do not get highlighted.

Screenshot is attatched.

Below is my fileViewProvider class.


code 1:

package newair.org.fileType;

import com.intellij.lang.Language;
import com.intellij.lang.LanguageParserDefinitions;
import com.intellij.lang.html.HTMLLanguage;
import com.intellij.openapi.fileTypes.PlainTextLanguage;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.LanguageSubstitutors;
import com.intellij.psi.MultiplePsiFilesPerDocumentFileViewProvider;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.impl.source.PsiFileImpl;
import com.intellij.psi.templateLanguages.TemplateDataLanguageMappings;
import com.intellij.psi.templateLanguages.TemplateLanguage;
import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import wso2.org.JaggeryTokenTypes;

import java.util.Arrays;
import java.util.Set;


public class JaggeryFileViewProvider extends MultiplePsiFilesPerDocumentFileViewProvider implements TemplateLanguageFileViewProvider {

    private Language myTemplateDataLanguage1;


    public JaggeryFileViewProvider(PsiManager manager, VirtualFile virtualFile, boolean physical) {

        super(manager, virtualFile, physical);

        Language dataLang = TemplateDataLanguageMappings.getInstance(manager.getProject()).getMapping(virtualFile);
        if(dataLang == null)


        {dataLang = StdFileTypes.JS.getLanguage();}


        if(dataLang instanceof TemplateLanguage) {

            myTemplateDataLanguage1 = StdFileTypes.HTML.getLanguage();

        }

        else

        {
            myTemplateDataLanguage1 = LanguageSubstitutors.INSTANCE.substituteLanguage(dataLang, virtualFile, manager.getProject());
        }



    }


    public JaggeryFileViewProvider(PsiManager manager, VirtualFile virtualFile, boolean physical, Language language){

        super(manager, virtualFile, physical);
        this.myTemplateDataLanguage1 = language;

    }

    @NotNull
    @Override
    public Language getBaseLanguage() {
        return JaggeryLanguage.INSTANCE;  
    }

    @NotNull
    @Override
    public Language getTemplateDataLanguage() {
        return myTemplateDataLanguage1;  
    }

    @Override
    protected MultiplePsiFilesPerDocumentFileViewProvider cloneInner(VirtualFile virtualFile) {
        return  new JaggeryFileViewProvider(getManager(), virtualFile, false, myTemplateDataLanguage1);  
    }


    @NotNull
    @Override
    public Set<Language> getLanguages() {
        return new THashSet<Language>(Arrays.asList(new Language[]{JaggeryLanguage.INSTANCE, myTemplateDataLanguage1,StdFileTypes.HTML.getLanguage()}));
    }

    @Override
    protected PsiFile createFile(Language lang) {

        if(lang == myTemplateDataLanguage1) {


            PsiFileImpl file = (PsiFileImpl) LanguageParserDefinitions.INSTANCE.forLanguage(lang).createFile(this);
            file.setContentElementType(JaggeryTokenTypes.TEMPLATE_DATA_JAVASCRIPT);
            return file;


        } else if(lang == JaggeryLanguage.INSTANCE) {
            return LanguageParserDefinitions.INSTANCE.forLanguage(lang).createFile(this);
        } else if(lang == StdFileTypes.HTML.getLanguage()){
         
            return LanguageParserDefinitions.INSTANCE.forLanguage(lang).createFile(this);

        }


        else return  null;
    }

}



And relevent Token types class(refer : JaggeryTokenTypes.TEMPLATE_DATA_JAVASCRIPT) would be as follows.

code 2:

package newair.org;

import com.intellij.psi.TokenType;
import com.intellij.psi.templateLanguages.TemplateDataElementType;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.ILazyParseableElementType;
import com.intellij.psi.tree.TokenSet;
import wso2.org.fileType.JaggeryLanguage;


public interface JaggeryTokenTypes {
    /**
     * predefined token types
     */
    public static final IElementType TEMPLATE_JAVASCRIPT_TEXT = new JaggeryElementType("TEMPLATE_JAVASCRIPT_TEXT"); // produced by lexer for all Javascript code
    public static final IElementType TEMPLATE_HTML_TEXT = new JaggeryElementType("TEMPLATE_HTML_TEXT") ;
    public static final IElementType OUTER_ELEMENT_TYPE = new JaggeryElementType("OUTER_TEXT");

  //  public static final HTMLElementType OUTER_ELEMENT_TYPE = new HTMLElementType("OUTER_ELEMENT_TYPE");

    public static  TemplateDataElementType TEMPLATE_DATA_JAVASCRIPT =

    new TemplateDataElementType("JAGGERY_TEMPLATE_DATA", JaggeryLanguage.INSTANCE, TEMPLATE_JAVASCRIPT_TEXT, OUTER_ELEMENT_TYPE );

    public static  TemplateDataElementType TEMPLATE_DATA_HTML =

            new TemplateDataElementType("JAGGERY_TEMPLATE_DATA_HTML", JaggeryLanguage.INSTANCE, TEMPLATE_HTML_TEXT, OUTER_ELEMENT_TYPE);


    public static final IElementType WHITE_SPACE = TokenType.WHITE_SPACE;

    public static final IElementType JAVASCRIPT_TEXT = TEMPLATE_JAVASCRIPT_TEXT;

    public static final IElementType HTML_TEXT = TEMPLATE_HTML_TEXT;//new JaggeryElementType("HTML");//TEMPLATE_DATA_HTML;



    TokenSet WHITE_SPACES = TokenSet.create(WHITE_SPACE);

    public static final  IElementType BAD_CHARACTER = TokenType.BAD_CHARACTER;

    public static final  IElementType  END_OF_THE_FILE = new JaggeryElementType(" END_OF_THE_FILE");

    /**
     *  jaggery specific token types
     */


   

}



And also As you may think, If I change the(please refer Code 1  red coloured part)

code 3:

else if(lang == StdFileTypes.HTML.getLanguage()){
         
            return LanguageParserDefinitions.INSTANCE.forLanguage(lang).createFile(this);

        }


to

code 4:

else if(lang == StdFileTypes.HTML.getLanguage()){

            PsiFileImpl file2 = (PsiFileImpl) LanguageParserDefinitions.INSTANCE.forLanguage(lang).createFile(this);
            file2.setContentElementType(JaggeryTokenTypes.TEMPLATE_DATA_HTML);
            return file2;

        }


I do not get the autocompletion even.
Can somebdy explain me this behaviour with how fileviewprovider works??


Thank You..!!



Attachment(s):
Screenshot from 2012-09-18 14:24:30.png
0

Please sign in to leave a comment.