PSI builder creation ordered

This commit is contained in:
Roman Shevchenko
2010-09-07 13:54:56 +04:00
parent 4bfd9aec32
commit 86e89f48c1
10 changed files with 96 additions and 78 deletions
@@ -115,7 +115,7 @@ public abstract class JavaParsingTestCase extends ParsingTestCase {
assert psi != null : chameleon;
final Project project = psi.getProject();
final PsiBuilderFactory factory = PsiBuilderFactory.getInstance();
final PsiBuilder builder = factory.createBuilder(project, chameleon, chameleon.getElementType().getLanguage(), chameleon.getChars());
final PsiBuilder builder = factory.createBuilder(project, chameleon);
builder.setDebugMode(true);
@@ -19,6 +19,8 @@ package com.intellij.lang;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author yole
@@ -28,9 +30,15 @@ public abstract class PsiBuilderFactory {
return ServiceManager.getService(PsiBuilderFactory.class);
}
public abstract PsiBuilder createBuilder(Project project, ASTNode tree, Language lang, CharSequence seq);
public abstract PsiBuilder createBuilder(@NotNull Project project, @NotNull ASTNode tree);
public abstract PsiBuilder createBuilder(Project project, ASTNode tree, Lexer lexer, Language lang, CharSequence seq);
/**
* @deprecated consider using {@link #createBuilder(com.intellij.openapi.project.Project, ASTNode)} instead.
*/
public abstract PsiBuilder createBuilder(@NotNull Project project, @NotNull ASTNode tree, @NotNull Language lang, @NotNull CharSequence seq);
public abstract PsiBuilder createBuilder(final Lexer lexer, Language lang, CharSequence seq);
public abstract PsiBuilder createBuilder(@NotNull Project project, @NotNull ASTNode tree, @Nullable Lexer lexer,
@NotNull Language lang, @NotNull CharSequence seq);
public abstract PsiBuilder createBuilder(@NotNull Lexer lexer, @NotNull Language lang, @NotNull CharSequence seq);
}
@@ -17,6 +17,7 @@ package com.intellij.psi.tree;
import com.intellij.lang.*;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NonNls;
public class IFileElementType extends ILazyParseableElementType {
@@ -29,15 +30,12 @@ public class IFileElementType extends ILazyParseableElementType {
}
public ASTNode parseContents(ASTNode chameleon) {
final Project project = chameleon.getPsi().getProject();
final PsiElement psi = chameleon.getPsi();
assert psi != null : "Bad chameleon: " + chameleon;
final Project project = psi.getProject();
final PsiBuilderFactory factory = PsiBuilderFactory.getInstance();
final PsiBuilder builder = factory.createBuilder(
project,
chameleon,
null, getLanguage(),
chameleon.getChars()
);
final PsiBuilder builder = factory.createBuilder(project, chameleon);
final PsiParser parser = LanguageParserDefinitions.INSTANCE.forLanguage(getLanguage()).createParser(project);
return parser.parse(this, builder).getFirstChildNode();
@@ -51,15 +51,11 @@ public class ILazyParseableElementType extends IElementType {
*/
public ASTNode parseContents(ASTNode chameleon) {
final PsiElement parentElement = chameleon.getTreeParent().getPsi();
assert parentElement != null : "Bad chameleon: " + chameleon;
final Project project = parentElement.getProject();
final PsiBuilderFactory factory = PsiBuilderFactory.getInstance();
final PsiBuilder builder = factory.createBuilder(
project,
chameleon,
null, getLanguage(),
chameleon.getText()
);
final PsiBuilder builder = factory.createBuilder(project, chameleon);
final PsiParser parser = LanguageParserDefinitions.INSTANCE.forLanguage(getLanguage()).createParser(project);
return parser.parse(this, builder).getFirstChildNode();
@@ -1,39 +0,0 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.lang;
import com.intellij.lang.impl.PsiBuilderImpl;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.project.Project;
/**
* @author yole
*/
public class PsiBuilderFactoryImpl extends PsiBuilderFactory {
public PsiBuilder createBuilder(Project project, final ASTNode tree, final Language lang, final CharSequence seq) {
return new PsiBuilderImpl(lang, null, tree, project, seq);
}
public PsiBuilder createBuilder(Project project, final ASTNode tree, final Lexer lexer, final Language lang, final CharSequence seq) {
return new PsiBuilderImpl(lang, lexer, tree, project, seq);
}
public PsiBuilder createBuilder(final Lexer lexer, final Language lang, final CharSequence seq) {
ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
return new PsiBuilderImpl(lexer, parserDefinition.getWhitespaceTokens(), parserDefinition.getCommentTokens(), seq);
}
}
@@ -0,0 +1,56 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.lang.impl;
import com.intellij.lang.*;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author yole
*/
public class PsiBuilderFactoryImpl extends PsiBuilderFactory {
@Override
public PsiBuilder createBuilder(@NotNull final Project project, @NotNull final ASTNode tree) {
return createBuilder(project, tree, null, tree.getElementType().getLanguage(), tree.getChars());
}
@Override
public PsiBuilder createBuilder(@NotNull final Project project, @NotNull final ASTNode tree, @NotNull final Language lang,
@NotNull final CharSequence seq) {
return createBuilder(project, tree, null, lang, seq);
}
@Override
public PsiBuilder createBuilder(@NotNull final Project project, @NotNull final ASTNode tree, @Nullable Lexer lexer,
@NotNull final Language lang, @NotNull final CharSequence seq) {
if (lexer == null) {
final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
assert parserDefinition != null : "ParserDefinition absent for language: " + lang.getID();
lexer = parserDefinition.createLexer(project);
}
return new PsiBuilderImpl(lang, lexer, tree, seq);
}
@Override
public PsiBuilder createBuilder(@NotNull final Lexer lexer, @NotNull final Language lang, @NotNull final CharSequence seq) {
ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
return new PsiBuilderImpl(lexer, parserDefinition.getWhitespaceTokens(), parserDefinition.getCommentTokens(), seq);
}
}
@@ -19,7 +19,6 @@ package com.intellij.lang.impl;
import com.intellij.lang.*;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.UserDataHolderBase;
@@ -119,20 +118,23 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
};
@NonNls private static final String UNBALANCED_MESSAGE =
"Unbalanced tree. Most probably caused by unbalanced markers. Try calling setDebugMode(true) against PsiBuilder passed to identify exact location of the problem";
"Unbalanced tree. Most probably caused by unbalanced markers. " +
"Try calling setDebugMode(true) against PsiBuilder passed to identify exact location of the problem";
public static void registerWhitespaceToken(IElementType type) {
ourAnyLanguageWhitespaceTokens = TokenSet.orSet(ourAnyLanguageWhitespaceTokens, TokenSet.create(type));
}
public PsiBuilderImpl(Language lang, Lexer lexer, final ASTNode chameleon, Project project, CharSequence text) {
public PsiBuilderImpl(@NotNull final Language lang, @NotNull final Lexer lexer, @NotNull final ASTNode chameleon,
@NotNull final CharSequence text) {
myText = text;
myTextArray = CharArrayUtil.fromSequenceWithoutCopying(text);
ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
assert parserDefinition != null : "ParserDefinition absent for language: " + lang.getID();
myLexer = lexer != null ? lexer : parserDefinition.createLexer(project);
myLexer = lexer;
myWhitespaces = parserDefinition.getWhitespaceTokens();
myComments = parserDefinition.getCommentTokens();
myCharTable = SharedImplUtil.findCharTableByTree(chameleon);
myOriginalTree = chameleon.getUserData(BlockSupport.TREE_TO_BE_REPARSED);
@@ -142,7 +144,8 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder {
}
@TestOnly
public PsiBuilderImpl(final Lexer lexer, final TokenSet whitespaces, final TokenSet comments, CharSequence text) {
public PsiBuilderImpl(@NotNull final Lexer lexer, @NotNull final TokenSet whitespaces, @NotNull final TokenSet comments,
@NotNull final CharSequence text) {
myWhitespaces = whitespaces;
myLexer = lexer;
myComments = comments;
@@ -41,7 +41,7 @@
serviceImplementation="com.intellij.execution.filters.TextConsoleBuilderFactoryImpl"/>
<applicationService serviceInterface="com.intellij.lang.PsiBuilderFactory"
serviceImplementation="com.intellij.lang.PsiBuilderFactoryImpl"/>
serviceImplementation="com.intellij.lang.impl.PsiBuilderFactoryImpl"/>
<applicationService serviceInterface="com.intellij.navigation.ChooseByNameRegistry"
serviceImplementation="com.intellij.navigation.ChooseByNameRegistry"/>
@@ -21,21 +21,21 @@ package com.intellij.psi.impl.source.parsing.xml;
import com.intellij.lang.LanguageParserDefinitions;
import com.intellij.lang.ParserDefinition;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiBuilderFactory;
import com.intellij.lang.html.HTMLLanguage;
import com.intellij.lang.html.HtmlParsing;
import com.intellij.lang.impl.PsiBuilderImpl;
import com.intellij.psi.tree.TokenSet;
public class HtmlBuilderDriver extends XmlBuilderDriver {
public HtmlBuilderDriver(final CharSequence text) {
super(text);
}
protected PsiBuilderImpl createBuilderAndParse() {
protected PsiBuilder createBuilderAndParse() {
final ParserDefinition htmlParserDef = LanguageParserDefinitions.INSTANCE.forLanguage(HTMLLanguage.INSTANCE);
assert htmlParserDef != null;
PsiBuilderImpl b = new PsiBuilderImpl(htmlParserDef.createLexer(null), htmlParserDef.getWhitespaceTokens(), TokenSet.EMPTY, getText());
PsiBuilder b = PsiBuilderFactory.getInstance().createBuilder(htmlParserDef.createLexer(null), HTMLLanguage.INSTANCE, getText());
new HtmlParsing(b).parseDocument();
return b;
}
@@ -19,9 +19,7 @@
*/
package com.intellij.psi.impl.source.parsing.xml;
import com.intellij.lang.LanguageParserDefinitions;
import com.intellij.lang.LighterASTNode;
import com.intellij.lang.ParserDefinition;
import com.intellij.lang.*;
import com.intellij.lang.impl.PsiBuilderImpl;
import com.intellij.lang.xml.XMLLanguage;
import com.intellij.openapi.util.Comparing;
@@ -29,7 +27,6 @@ import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.TokenType;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.psi.xml.XmlElementType;
import com.intellij.psi.xml.XmlTokenType;
import com.intellij.util.containers.Stack;
@@ -59,7 +56,7 @@ public class XmlBuilderDriver {
}
public void build(XmlBuilder builder) {
PsiBuilderImpl b = createBuilderAndParse();
PsiBuilder b = createBuilderAndParse();
FlyweightCapableTreeStructure<LighterASTNode> structure = b.getLightTree();
@@ -84,7 +81,7 @@ public class XmlBuilderDriver {
structure.disposeChildren(children, count);
}
private void processPrologNode(PsiBuilderImpl psiBuilder,
private void processPrologNode(PsiBuilder psiBuilder,
XmlBuilder builder,
FlyweightCapableTreeStructure<LighterASTNode> structure,
LighterASTNode prolog) {
@@ -136,24 +133,23 @@ public class XmlBuilderDriver {
return myText.subSequence(token.getStartOffset(), token.getEndOffset());
}
protected PsiBuilderImpl createBuilderAndParse() {
protected PsiBuilder createBuilderAndParse() {
final ParserDefinition xmlParserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(XMLLanguage.INSTANCE);
assert xmlParserDefinition != null;
PsiBuilderImpl b = new PsiBuilderImpl(xmlParserDefinition.createLexer(null), xmlParserDefinition.getWhitespaceTokens(), TokenSet.EMPTY,
myText);
PsiBuilder b = PsiBuilderFactory.getInstance().createBuilder(xmlParserDefinition.createLexer(null), XMLLanguage.INSTANCE, myText);
new XmlParsing(b).parseDocument();
return b;
}
private void processErrorNode(PsiBuilderImpl psiBuilder, LighterASTNode node, XmlBuilder builder) {
private void processErrorNode(PsiBuilder psiBuilder, LighterASTNode node, XmlBuilder builder) {
assert node.getTokenType() == TokenType.ERROR_ELEMENT;
String message = psiBuilder.getErrorMessage(node);
String message = PsiBuilderImpl.getErrorMessage(node);
assert message != null;
builder.error(message, node.getStartOffset(), node.getEndOffset());
}
private void processTagNode(PsiBuilderImpl psiBuilder,
private void processTagNode(PsiBuilder psiBuilder,
FlyweightCapableTreeStructure<LighterASTNode> structure,
LighterASTNode node,
XmlBuilder builder) {