/* * Copyright 2013 Guidewire Software, Inc. */ package gw.plugin.ij.lang.parser; import com.intellij.lang.ASTNode; import com.intellij.lang.LanguageUtil; import com.intellij.lang.ParserDefinition; import com.intellij.lang.PsiParser; import com.intellij.lexer.Lexer; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.impl.source.tree.injected.InjectedFileViewProvider; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IFileElementType; import com.intellij.psi.tree.IStubFileElementType; import com.intellij.psi.tree.TokenSet; import gw.plugin.ij.filetypes.GosuCodeFileType; import gw.plugin.ij.lang.GosuElementType; import gw.plugin.ij.lang.GosuLanguage; import gw.plugin.ij.lang.GosuLexer; import gw.plugin.ij.lang.GosuTokenSets; import gw.plugin.ij.lang.GosuTokenTypes; import gw.plugin.ij.lang.psi.impl.GosuProgramFileImpl; import gw.plugin.ij.lang.psi.stubs.elements.GosuStubFileElementType; import org.jetbrains.annotations.NotNull; import static com.intellij.lang.ParserDefinition.SpaceRequirements.MUST_LINE_BREAK; public class GosuCodeParserDefinition implements ParserDefinition { public static final IStubFileElementType GOSU_FILE = new GosuStubFileElementType("gosu.FILE", GosuLanguage.instance()); @NotNull public Lexer createLexer(Project project) { return new GosuLexer(); } @NotNull public PsiParser createParser(Project project) { throw new UnsupportedOperationException("Should never be called, parse tree transformation happens in GosuStubFileElementType"); } @NotNull public IFileElementType getFileNodeType() { return GOSU_FILE; } @NotNull public TokenSet getWhitespaceTokens() { return GosuTokenSets.WHITE_SPACE_TOKEN_SET; } @NotNull public TokenSet getCommentTokens() { return GosuTokenSets.COMMENTS_TOKEN_SET; } @NotNull public TokenSet getStringLiteralElements() { return GosuTokenSets.STRING_LITERALS; } @NotNull public PsiElement createElement(ASTNode node) { return GosuPsiCreator.createElement(node); } public PsiFile createFile(@NotNull FileViewProvider viewProvider) { if (viewProvider instanceof InjectedFileViewProvider || viewProvider.getVirtualFile().getName().contains("Fragment")) { //final InjectedFileViewProvider p = (InjectedFileViewProvider) viewProvider; return new GosuProgramFileImpl(viewProvider); } final VirtualFile file = viewProvider.getVirtualFile(); final FileType type = file.getFileType(); return ((GosuCodeFileType) type).createPsiFile(viewProvider); } public ParserDefinition.SpaceRequirements spaceExistanceTypeBetweenTokens(@NotNull ASTNode left, @NotNull ASTNode right) { final IElementType l = left.getElementType(); final IElementType r = right.getElementType(); if (r == GosuTokenTypes.TT_uses && l != GosuTokenTypes.TT_WHITESPACE) { return MUST_LINE_BREAK; } if (l == GosuTokenTypes.TT_OP_semicolon || l == GosuTokenTypes.TT_COMMENT_LINE) { return MUST_LINE_BREAK; } if (hasParentLikeElementType(left, GosuElementTypes.ELEM_TYPE_UsesStatement) && r != GosuTokenTypes.TT_WHITESPACE) { return MUST_LINE_BREAK; } return LanguageUtil.canStickTokensTogetherByLexer(left, right, new GosuLexer()); } private boolean hasParentLikeElementType(@NotNull ASTNode node, GosuElementType elementType) { ASTNode parent = node.getTreeParent(); while (parent != null) { if (parent.getElementType() == elementType) { return true; } parent = parent.getTreeParent(); } return false; } }