c40d56b0f4afdf18cff80f9077aca73ca063ac80
[idea/community.git] / platform / core-api / src / com / intellij / lang / ParserDefinition.java
1 /*
2  * Copyright 2000-2009 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.intellij.lang;
17
18 import com.intellij.lexer.Lexer;
19 import com.intellij.openapi.project.Project;
20 import com.intellij.psi.FileViewProvider;
21 import com.intellij.psi.PsiElement;
22 import com.intellij.psi.PsiFile;
23 import com.intellij.psi.tree.IFileElementType;
24 import com.intellij.psi.tree.TokenSet;
25 import org.jetbrains.annotations.NotNull;
26
27 /**
28  * Defines the implementation of a parser for a custom language.
29  *
30  * @see LanguageParserDefinitions#forLanguage(Language)
31  */
32 public interface ParserDefinition {
33   /**
34    * Returns the lexer for lexing files in the specified project. This lexer does not need to support incremental relexing - it is always
35    * called for the entire file.
36    *
37    * @param project the project to which the lexer is connected.
38    * @return the lexer instance.
39    */
40   @NotNull
41   Lexer createLexer(Project project);
42
43   /**
44    * Returns the parser for parsing files in the specified project.
45    *
46    * @param project the project to which the parser is connected.
47    * @return the parser instance.
48    */
49   PsiParser createParser(Project project);
50
51   /**
52    * Returns the element type of the node describing a file in the specified language.
53    *
54    * @return the file node element type.
55    */
56   IFileElementType getFileNodeType();
57
58   /**
59    * Returns the set of token types which are treated as whitespace by the PSI builder.
60    * Tokens of those types are automatically skipped by PsiBuilder. Whitespace elements
61    * on the bounds of nodes built by PsiBuilder are automatically excluded from the text
62    * range of the nodes.
63    * <p><strong>It is strongly advised you return TokenSet that only contains {@link com.intellij.psi.TokenType#WHITE_SPACE},
64    * which is suitable for all the languages unless you really need to use special whitespace token</strong>
65    *
66    * @return the set of whitespace token types.
67    */
68   @NotNull
69   TokenSet getWhitespaceTokens();
70
71   /**
72    * Returns the set of token types which are treated as comments by the PSI builder.
73    * Tokens of those types are automatically skipped by PsiBuilder. Also, To Do patterns
74    * are searched in the text of tokens of those types.
75    * This token set shouldn't contain types of non-leaf comment inner elements.
76    *
77    * @return the set of comment token types.
78    */
79   @NotNull
80   TokenSet getCommentTokens();
81
82   /**
83    * Returns the set of element types which are treated as string literals. "Search in strings"
84    * option in refactorings is applied to the contents of such tokens.
85    *
86    * @return the set of string literal element types.
87    */
88   @NotNull
89   TokenSet getStringLiteralElements();
90
91   /**
92    * Creates a PSI element for the specified AST node. The AST tree is a simple, semantic-free
93    * tree of AST nodes which is built during the PsiBuilder parsing pass. The PSI tree is built
94    * over the AST tree and includes elements of different types for different language constructs.
95    *
96    * !!!WARNING!!! PSI element types should be unambiguously determined by AST node element types.
97    * You can not produce different PSI elements from AST nodes of the same types (e.g. based on AST node content).
98    * Typically, your code should be as simple as that:
99    * <code>
100    *   if (node.getElementType == MY_ELEMENT_TYPE) {
101    *     return new MyPsiElement(node);
102    *   }
103    * </code>
104    *
105    * @param node the node for which the PSI element should be returned.
106    * @return the PSI element matching the element type of the AST node.
107    */
108   @NotNull
109   PsiElement createElement(ASTNode node);
110
111   /**
112    * Creates a PSI element for the specified virtual file.
113    *
114    * @param viewProvider virtual file.
115    * @return the PSI file element.
116    */
117   PsiFile createFile(FileViewProvider viewProvider);
118
119   /**
120    * Checks if the specified two token types need to be separated by a space according to the language grammar.
121    * For example, in Java two keywords are always separated by a space; a keyword and an opening parenthesis may
122    * be separated or not separated. This is used for automatic whitespace insertion during AST modification operations.
123    *
124    * @param left  the first token to check.
125    * @param right the second token to check.
126    * @return the spacing requirements.
127    * @since 6.0
128    */
129   SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right);
130
131   /**
132    * Requirements for spacing between tokens.
133    *
134    * @see ParserDefinition#spaceExistanceTypeBetweenTokens
135    */
136   enum SpaceRequirements {
137     /** Whitespace between tokens is optional. */
138     MAY,
139     /** Whitespace between tokens is required. */
140     MUST,
141     /** Whitespace between tokens is not allowed. */
142     MUST_NOT,
143     /** A line break is required between tokens. */
144     MUST_LINE_BREAK,
145   }
146 }