blob: b50811fe4da98f10e14393239dde16f64822d76b [file] [log] [blame]
package com.intellij.tasks.youtrack.lang;
import com.intellij.extapi.psi.ASTWrapperPsiElement;
import com.intellij.lang.ASTNode;
import com.intellij.lang.ParserDefinition;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiParser;
import com.intellij.lexer.Lexer;
import com.intellij.lexer.LexerBase;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.IFileElementType;
import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author Mikhail Golubev
*/
public class YouTrackParserDefinition implements ParserDefinition {
private static final Logger LOG = Logger.getInstance(YouTrackParserDefinition.class);
public static final IElementType ANY_TEXT = new IElementType("ANY_TEXT", YouTrackLanguage.INSTANCE);
public static final IElementType QUERY = new IElementType("QUERY", YouTrackLanguage.INSTANCE);
public static final IFileElementType FILE = new IFileElementType(YouTrackLanguage.INSTANCE);
@NotNull
@Override
public Lexer createLexer(Project project) {
return new YouTrackMockLexer();
}
@Override
public PsiParser createParser(Project project) {
return new YouTrackMockParser();
}
@Override
public IFileElementType getFileNodeType() {
return FILE;
}
@NotNull
@Override
public TokenSet getWhitespaceTokens() {
return TokenSet.EMPTY;
}
@NotNull
@Override
public TokenSet getCommentTokens() {
return TokenSet.EMPTY;
}
@NotNull
@Override
public TokenSet getStringLiteralElements() {
return TokenSet.EMPTY;
}
@NotNull
@Override
public PsiElement createElement(ASTNode node) {
assert node.getElementType() == QUERY;
return new YouTrackQueryElement(node);
}
@Override
public PsiFile createFile(FileViewProvider viewProvider) {
return new YouTrackFile(viewProvider);
}
@Override
public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right) {
return SpaceRequirements.MAY;
}
/**
* Sole element that represents YouTrack query in PSI tree
*/
public static class YouTrackQueryElement extends ASTWrapperPsiElement {
YouTrackQueryElement(@NotNull ASTNode node) {
super(node);
}
}
/**
* Tokenize whole query as single {@code ANY_TEXT} token
*/
private static class YouTrackMockLexer extends LexerBase {
private int myStart;
private int myEnd;
private CharSequence myBuffer;
@Override
public void start(@NotNull CharSequence buffer, int startOffset, int endOffset, int initialState) {
//LOG.debug(String.format("buffer: '%s', start: %d, end: %d", buffer, startOffset, endOffset));
myBuffer = buffer;
myStart = startOffset;
myEnd = endOffset;
}
@Override
public int getState() {
return 0;
}
@Nullable
@Override
public IElementType getTokenType() {
return myStart >= myEnd? null : ANY_TEXT;
}
@Override
public int getTokenStart() {
return myStart;
}
@Override
public int getTokenEnd() {
return myEnd;
}
@Override
public void advance() {
myStart = myEnd;
}
@NotNull
@Override
public CharSequence getBufferSequence() {
return myBuffer;
}
@Override
public int getBufferEnd() {
return myEnd;
}
}
/**
* Parse whole YouTrack query as single {@code QUERY} element
*/
private static class YouTrackMockParser implements PsiParser {
@NotNull
@Override
public ASTNode parse(IElementType root, PsiBuilder builder) {
PsiBuilder.Marker rootMarker = builder.mark();
PsiBuilder.Marker queryMarker = builder.mark();
assert builder.getTokenType() == null || builder.getTokenType() == ANY_TEXT;
builder.advanceLexer();
queryMarker.done(QUERY);
assert builder.eof();
rootMarker.done(root);
return builder.getTreeBuilt();
}
}
}