Initial implementation of JavaScript support.

This commit is contained in:
Maxim Shafirov
2005-01-31 16:38:22 +03:00
parent c56a37b40b
commit 72b1f707c2
35 changed files with 285 additions and 118 deletions
+20
View File
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4" relativePaths="true" type="JAVA_MODULE">
<component name="ModuleRootManager" />
<component name="NewModuleRootManager">
<output url="file://$MODULE_DIR$/../classes/main" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
</content>
<orderEntry type="library" name="Generic collections" level="project" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="openapi" exported="" />
<orderEntry type="module" module-name="util" exported="" />
<orderEntry type="module" module-name="idea" />
<orderEntry type="library" name="JUnit" level="project" />
<orderEntryProperties />
</component>
</module>
@@ -14,11 +14,16 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.ElementBase;
import com.intellij.psi.impl.SharedPsiElementImplUtil;
import com.intellij.psi.impl.source.resolve.ResolveUtil;
import com.intellij.psi.impl.source.tree.CompositeElement;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.util.IncorrectOperationException;
import java.util.ArrayList;
import java.util.List;
/**
* Created by IntelliJ IDEA.
* User: max
@@ -43,7 +48,15 @@ public class ASTWrapperPsiElement extends ElementBase implements PsiElement, Nav
}
public PsiElement[] getChildren() {
return new PsiElement[0];
List<PsiElement> result = new ArrayList<PsiElement>();
ASTNode child = getNode().getFirstChildNode();
while (child != null) {
if (child instanceof CompositeElement) {
result.add(childNodeToPsi(child));
}
child = child.getTreeNext();
}
return result.toArray(new PsiElement[result.size()]);
}
public PsiElement getParent() {
@@ -209,7 +222,7 @@ public class ASTWrapperPsiElement extends ElementBase implements PsiElement, Nav
}
public PsiElement getContext() {
throw new UnsupportedOperationException();
return ResolveUtil.getContext(this);
}
public boolean isPhysical() {
@@ -262,6 +275,10 @@ public class ASTWrapperPsiElement extends ElementBase implements PsiElement, Nav
return myNode;
}
public PsiElement childNodeToPsi(ASTNode node) {
return SourceTreeToPsiMap.treeElementToPsi(node);
}
public Language getLanguage() {
return myNode.getElementType().getLanguage();
}
@@ -26,7 +26,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.ex.dummy.DummyFileSystem;
import com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl;
import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.codeStyle.CodeStyleSettings;
@@ -57,10 +56,7 @@ public class LightIdeaTestCase extends TestCase implements DataProvider {
private static VirtualFile ourSourceRoot;
private static TestCase ourTestCase = null;
public static Thread ourTestThread;
static {
Logger.setFactory(TestLoggerFactory.getInstance());
}
private String oldCodeStyleSettings;
/**
* @return Project to be used in tests for example for project components retrieval.
@@ -1,11 +1,11 @@
package com.intellij.psi;
package com.intellij.testFramework;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.DebugUtil;
import com.intellij.testFramework.LightIdeaTestCase;
import java.io.File;
import java.io.FileNotFoundException;
@@ -18,10 +18,14 @@ public abstract class ParsingTestCase extends LightIdeaTestCase {
public ParsingTestCase(String dataPath, String fileExt) {
myDataPath = dataPath;
myFullDataPath = PathManagerEx.getTestDataPath() + "/psi/" + myDataPath;
myFullDataPath = testDataPath() + "/psi/" + myDataPath;
myFileExt = fileExt;
}
protected String testDataPath() {
return PathManagerEx.getTestDataPath();
}
protected void doTest(boolean checkResult) throws Exception{
String name = getTestName(false);
String text = loadFile(name + "." + myFileExt);
@@ -30,12 +34,12 @@ public abstract class ParsingTestCase extends LightIdeaTestCase {
checkResult(name + ".txt", file);
}
else{
DebugUtil.treeToString(com.intellij.psi.impl.source.SourceTreeToPsiMap.psiElementToTree(file), false);
toParseTreeText(file);
}
}
protected void checkResult(String targetDataName, final PsiFile file) throws Exception {
String treeText = DebugUtil.treeToString(com.intellij.psi.impl.source.SourceTreeToPsiMap.psiElementToTree(file), false).trim();
String treeText = toParseTreeText(file).trim();
try{
String expectedText = loadFile(targetDataName);
/*
@@ -63,6 +67,10 @@ public abstract class ParsingTestCase extends LightIdeaTestCase {
}
}
private String toParseTreeText(final PsiFile file) {
return DebugUtil.treeToString(com.intellij.psi.impl.source.SourceTreeToPsiMap.psiElementToTree(file), false);
}
protected String loadFile(String name) throws Exception {
String fullName = myFullDataPath + File.separatorChar + name;
String text = new String(FileUtil.loadFileText(new File(fullName))).trim();
@@ -31,14 +31,14 @@
*/
package com.intellij.testFramework;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ex.PathManagerEx;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiManager;
+9 -3
View File
@@ -1,10 +1,10 @@
package com.intellij.lang;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.UserDataHolder;
import com.intellij.openapi.util.Key;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
/**
* Created by IntelliJ IDEA.
@@ -14,6 +14,8 @@ import com.intellij.openapi.util.Key;
* To change this template use File | Settings | File Templates.
*/
public interface ASTNode extends UserDataHolder {
ASTNode[] EMPTY_ARRAY = new ASTNode[0];
IElementType getElementType();
String getText();
@@ -59,4 +61,8 @@ public interface ASTNode extends UserDataHolder {
<T> T getCopyableUserData(Key<T> key);
<T> void putCopyableUserData(Key<T> key, T value);
ASTNode findChildByType(IElementType type);
ASTNode[] findChildrenByFilter(TokenSet filter);
}
+1 -1
View File
@@ -43,7 +43,7 @@ public abstract class Language {
return null;
}
public ParserDefinition getParserDefinition(Project project) {
public ParserDefinition getParserDefinition() {
return null;
}
+8 -17
View File
@@ -1,7 +1,6 @@
package com.intellij.lang;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.PsiElement;
/**
* Created by IntelliJ IDEA.
@@ -11,28 +10,20 @@ import com.intellij.psi.PsiElement;
* To change this template use File | Settings | File Templates.
*/
public interface PsiBuilder {
IElementType getTokenType();
interface Marker {
}
interface Lexem {
IElementType getTokenType();
String getTokenText();
Marker preceed();
void drop();
void rollbackTo();
void done(IElementType type);
}
void advanceLexer();
Lexem getCurrentLexem();
Marker mark();
Marker start(IElementType symbol);
void rollbackTo(Marker marker);
void drop(Marker marker);
void done(Marker marker);
void insertErrorElement(String messageText);
void error(String messageText);
boolean eof();
@@ -36,6 +36,7 @@ import gnu.trove.THashSet;
import java.util.Arrays;
public class TokenSet {
public static final TokenSet EMPTY = new TokenSet();
private final THashSet<IElementType> mySet = new THashSet<IElementType>(100, (float)0.1);
public IElementType[] getTypes() {
@@ -23,7 +23,7 @@ public class DTDLanguage extends Language {
return new XmlFileHighlighter(true);
}
public ParserDefinition getParserDefinition(Project project) {
public ParserDefinition getParserDefinition() {
return new DTDParserDefinition();
}
}
@@ -33,7 +33,7 @@ public class HTMLLanguage extends XMLLanguage {
return ENCODE_EACH_SYMBOL_POLICY;
}
public ParserDefinition getParserDefinition(Project project) {
public ParserDefinition getParserDefinition() {
return new HTMLParserDefinition();
}
}
+119 -61
View File
@@ -6,6 +6,7 @@ import com.intellij.lexer.Lexer;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.impl.source.tree.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.CharTable;
import java.util.ArrayList;
@@ -21,39 +22,65 @@ import java.util.List;
public class PsiBuilderImpl implements PsiBuilder {
private static final Logger LOG = Logger.getInstance("#com.intellij.lang.impl.PsiBuilderImpl");
private List<Lexem> myLexems = new ArrayList<Lexem>();
private List<Object> myProduction = new ArrayList<Object>();
private List<Token> myLexems = new ArrayList<Token>();
private List<ProductionMarker> myProduction = new ArrayList<ProductionMarker>();
private Lexer myLexer;
private boolean myFileLevelParsing;
private TokenSet myWhitespaces;
private TokenSet myComments;
private int myCurrentLexem;
private CharTable myCharTable;
private boolean myStarted = false;
public PsiBuilderImpl(final Lexer lexer, final CharTable charTable, boolean fileLevelParsing) {
public PsiBuilderImpl(final Lexer lexer, final CharTable charTable, boolean fileLevelParsing, TokenSet whitespaces, TokenSet comments) {
myCharTable = charTable;
myLexer = lexer;
myFileLevelParsing = fileLevelParsing;
myWhitespaces = whitespaces;
myComments = comments;
}
private static class MarkerImpl implements Marker {
private class StartMarker extends ProductionMarker implements Marker {
public IElementType myType;
public int myLexemIndex;
public DoneMarker myDoneMarker = null;
public MarkerImpl(final IElementType type, int idx) {
public StartMarker(int idx) {
super(idx);
}
public Marker preceed() {
return PsiBuilderImpl.this.preceed(this);
}
public void drop() {
PsiBuilderImpl.this.drop(this);
}
public void rollbackTo() {
PsiBuilderImpl.this.rollbackTo(this);
}
public void done(IElementType type) {
myType = type;
myLexemIndex = idx;
PsiBuilderImpl.this.done(this);
}
}
private class LexemImpl implements Lexem {
private Marker preceed(final StartMarker marker) {
int idx = myProduction.indexOf(marker);
LOG.assertTrue(idx >= 0, "Cannot preceed dropped or rolled-back marker");
StartMarker pre = new StartMarker(marker.myLexemIndex);
myProduction.add(idx, pre);
return pre;
}
public class Token {
private IElementType myTokenType;
private int myTokenStart;
private int myTokenEnd;
private int myState;
public LexemImpl() {
public Token() {
myTokenType = myLexer.getTokenType();
myTokenStart = myLexer.getTokenStart();
myTokenEnd = myLexer.getTokenEnd();
@@ -69,50 +96,74 @@ public class PsiBuilderImpl implements PsiBuilder {
}
}
private static class DoneMarker {
public MarkerImpl myMarker;
private static class ProductionMarker {
public int myLexemIndex;
public DoneMarker(final MarkerImpl marker) {
myMarker = marker;
public ProductionMarker(final int lexemIndex) {
myLexemIndex = lexemIndex;
}
}
private static class ErrorItem {
private static class DoneMarker extends ProductionMarker {
public StartMarker myStart;
public DoneMarker(final StartMarker marker, int currentLexem) {
super(currentLexem);
myStart = marker;
}
}
private static class ErrorItem extends ProductionMarker {
String myMessage;
public ErrorItem(final String message) {
public ErrorItem(final String message, int idx) {
super(idx);
myMessage = message;
}
}
public IElementType getTokenType() {
final Token lex = getCurrentToken();
final IElementType tokenType = lex == null ? null : lex.getTokenType();
LOG.assertTrue(!whitespaceOrComment(tokenType));
return tokenType;
}
public void advanceLexer() {
myProduction.add(getCurrentLexem());
myCurrentLexem++;
if (myCurrentLexem > myLexems.size()) {
LOG.assertTrue(!eof());
final Lexem lxm = advanceOriginalLexer();
if (lxm == null) return;
myLexems.add(lxm);
}
public Token getCurrentToken() {
Token lastToken;
while(true) {
lastToken = getTokenOrWhitespace();
if (lastToken == null) return null;
if (whitespaceOrComment(lastToken.getTokenType())) {
myCurrentLexem++;
}
else {
break;
}
}
return lastToken;
}
private Lexem advanceOriginalLexer() {
myLexer.advance();
return myLexer.getTokenType() == null ? null : new LexemImpl();
}
public Lexem getCurrentLexem() {
private Token getTokenOrWhitespace() {
if (myCurrentLexem >= myLexems.size()) {
if (myLexer.getTokenType() == null) return null;
myLexems.add(new Token());
myLexer.advance();
}
return myLexems.get(myCurrentLexem);
}
public Marker start(IElementType symbol) {
if (!myStarted) {
myStarted = true;
myLexems.add(new LexemImpl());
}
private boolean whitespaceOrComment(IElementType token) {
return myWhitespaces.isInSet(token) || myComments.isInSet(token);
}
MarkerImpl marker = new MarkerImpl(symbol, myCurrentLexem);
public Marker mark() {
StartMarker marker = new StartMarker(myCurrentLexem);
myProduction.add(marker);
return marker;
}
@@ -120,14 +171,11 @@ public class PsiBuilderImpl implements PsiBuilder {
public boolean eof() {
if (myCurrentLexem + 1 < myLexems.size()) return false;
if (myLexer.getTokenType() == null) return true;
final Lexem lxm = advanceOriginalLexer();
if (lxm == null) return true;
myLexems.add(lxm);
return false;
return getCurrentToken() == null;
}
public void rollbackTo(Marker marker) {
myCurrentLexem = ((MarkerImpl)marker).myLexemIndex;
myCurrentLexem = ((StartMarker)marker).myLexemIndex;
int idx = myProduction.lastIndexOf(marker);
LOG.assertTrue(idx >= 0, "The marker must be added before rolled back to.");
@@ -142,31 +190,31 @@ public class PsiBuilderImpl implements PsiBuilder {
}
public void done(Marker marker) {
LOG.assertTrue(((MarkerImpl)marker).myDoneMarker == null, "Marker already done.");
LOG.assertTrue(((StartMarker)marker).myDoneMarker == null, "Marker already done.");
int idx = myProduction.lastIndexOf(marker);
LOG.assertTrue(idx >= 0, "Marker never been added.");
for (int i = myProduction.size() - 1; i > idx; i--) {
Object item = myProduction.get(i);
if (item instanceof Marker) {
MarkerImpl otherMarker = (MarkerImpl)item;
StartMarker otherMarker = (StartMarker)item;
if (otherMarker.myDoneMarker == null) {
LOG.error("Another not done marker of type [" + otherMarker.myType + "] added after this one. Must be done before this.");
}
}
}
DoneMarker doneMarker = new DoneMarker((MarkerImpl)marker);
((MarkerImpl)marker).myDoneMarker = doneMarker;
DoneMarker doneMarker = new DoneMarker((StartMarker)marker, myCurrentLexem);
((StartMarker)marker).myDoneMarker = doneMarker;
myProduction.add(doneMarker);
}
public void insertErrorElement(String messageText) {
myProduction.add(new ErrorItem(messageText));
public void error(String messageText) {
myProduction.add(new ErrorItem(messageText, myCurrentLexem));
}
public ASTNode getTreeBuilt() {
MarkerImpl rootMarker = (MarkerImpl)myProduction.get(0);
StartMarker rootMarker = (StartMarker)myProduction.get(0);
final ASTNode rootNode;
if (myFileLevelParsing) {
@@ -179,28 +227,22 @@ public class PsiBuilderImpl implements PsiBuilder {
}
ASTNode curNode = rootNode;
int curToken = 0;
for (int i = 1; i < myProduction.size(); i++) {
LOG.assertTrue(curNode != null, "Unexpected end of the production");
Object item = myProduction.get(i);
if (item instanceof LexemImpl) {
LexemImpl lexem = (LexemImpl)item;
final LeafPsiElement childNode = new LeafPsiElement(lexem.getTokenType(),
myLexer.getBuffer(),
lexem.myTokenStart,
lexem.myTokenEnd,
lexem.myState,
myCharTable);
TreeUtil.addChildren((CompositeElement)curNode, childNode);
}
else if (item instanceof MarkerImpl) {
MarkerImpl marker = (MarkerImpl)item;
ProductionMarker item = myProduction.get(i);
int lexIndex = item.myLexemIndex;
if (item instanceof StartMarker) {
StartMarker marker = (StartMarker)item;
curToken = insertLeafs(curToken, lexIndex, curNode);
ASTNode childNode = new CompositeElement(marker.myType);
TreeUtil.addChildren((CompositeElement)curNode, (TreeElement)childNode);
curNode = childNode;
}
else if (item instanceof DoneMarker) {
DoneMarker doneMarker = (DoneMarker)item;
LOG.assertTrue(doneMarker.myMarker.myType == curNode.getElementType());
curToken = insertLeafs(curToken, lexIndex, curNode);
LOG.assertTrue(doneMarker.myStart.myType == curNode.getElementType());
curNode = curNode.getTreeParent();
}
else if (item instanceof ErrorItem) {
@@ -210,8 +252,24 @@ public class PsiBuilderImpl implements PsiBuilder {
}
}
LOG.assertTrue(curToken == myLexems.size(), "Not all of the tokens inserted to the tree");
LOG.assertTrue(curNode == null, "Unbalanced tree");
return rootNode;
}
private int insertLeafs(int curToken, final int lastIdx, final ASTNode curNode) {
while (curToken < lastIdx) {
Token lexem = myLexems.get(curToken++);
final IElementType type = lexem.getTokenType();
final LeafPsiElement childNode = new LeafPsiElement(type,
myLexer.getBuffer(),
lexem.myTokenStart,
lexem.myTokenEnd,
lexem.myState,
myCharTable);
TreeUtil.addChildren((CompositeElement)curNode, childNode);
}
return curToken;
}
}
@@ -37,7 +37,7 @@ public class JavaLanguage extends Language {
};
}
public ParserDefinition getParserDefinition(Project project) {
public ParserDefinition getParserDefinition() {
return new JavaParserDefinition();
}
}
@@ -32,7 +32,7 @@ public class XHTMLLanguage extends XMLLanguage {
return ENCODE_EACH_SYMBOL_POLICY;
}
public ParserDefinition getParserDefinition(Project project) {
public ParserDefinition getParserDefinition() {
return new XHTMLParserDefinition();
}
}
@@ -43,7 +43,7 @@ public class XMLLanguage extends Language {
return CDATA_ON_ANY_ENCODED_POLICY;
}
public ParserDefinition getParserDefinition(Project project) {
public ParserDefinition getParserDefinition() {
return new XMLParserDefinition();
}
}
+27 -2
View File
@@ -1,6 +1,8 @@
package com.intellij.psi.impl;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
@@ -11,7 +13,6 @@ import com.intellij.psi.impl.source.parsing.ChameleonTransforming;
import com.intellij.psi.impl.source.tree.*;
import com.intellij.util.ArrayUtil;
import com.intellij.util.CharTable;
import com.intellij.lang.ASTNode;
/**
*
@@ -44,6 +45,24 @@ public class DebugUtil {
return buffer.toString();
}
//TODO: remove this method. Necessary for debug purposes while we do not have PsiElement's for javascript
public static PsiElement treeElementToPsi(ASTNode element) {
ProgressManager.getInstance().checkCanceled();
if (element == null) return null;
if (element instanceof PsiElement) {
return (PsiElement)element;
}
else if (element instanceof RepositoryTreeElement) {
return RepositoryElementsManager.getOrFindPsiElement((RepositoryTreeElement)element);
}
else {
PsiElement psiElement = element.getUserData(TreeElement.PSI_ELEMENT_KEY);
return psiElement;
}
}
private static void treeToBuffer(StringBuffer buffer, ASTNode root, int indent, boolean skipWhiteSpaces) {
if (skipWhiteSpaces && root.getElementType() == ElementType.WHITE_SPACE) return;
@@ -51,7 +70,13 @@ public class DebugUtil {
buffer.append(' ');
}
if (root instanceof CompositeElement) {
buffer.append(SourceTreeToPsiMap.treeElementToPsi(root).toString());
final PsiElement psiElement = treeElementToPsi(root);
if (psiElement != null) {
buffer.append(psiElement.toString());
}
else {
buffer.append(root.getElementType().toString());
}
}
else {
String text = root.getText();
@@ -615,7 +615,7 @@ public class PsiElementFactoryImpl implements PsiElementFactory {
final Project project = manager.getProject();
final CharArrayCharSequence text = new CharArrayCharSequence(chars, startOffset, endOffset);
if (fileType instanceof LanguageFileType) {
return ((LanguageFileType)fileType).getLanguage().getParserDefinition(project).createFile(project, name, text);
return ((LanguageFileType)fileType).getLanguage().getParserDefinition().createFile(project, name, text);
}
return new PsiPlainTextFileImpl(project, name, fileType, text);
}
@@ -348,7 +348,7 @@ public class FileManagerImpl implements FileManager {
final Project project = myManager.getProject();
if (fileType instanceof LanguageFileType) {
final Language language = ((LanguageFileType)fileType).getLanguage();
return language.getParserDefinition(project).createFile(project, vFile);
return language.getParserDefinition().createFile(project, vFile);
}
if (fileType instanceof JavaClassFileType) {
@@ -54,16 +54,24 @@ public abstract class PsiFileImpl extends NonSlaveRepositoryPsiElement implement
IElementType contentElementType,
String name,
CharSequence text) {
super((PsiManagerImpl)PsiManager.getInstance(project), (RepositoryTreeElement)Factory.createCompositeElement(elementType));
this(project, (FileElement)Factory.createCompositeElement(elementType), elementType, contentElementType, name);
final FileElement parent = getTreeElement();
char[] chars = CharArrayUtil.fromSequence(text);
TreeElement contentElement = createContentLeafElement(chars, 0, text.length(), parent.getCharTable());
TreeUtil.addChildren(parent, contentElement);
}
protected PsiFileImpl(Project project,
FileElement fileElement,
IElementType elementType,
IElementType contentElementType,
String name) {
super((PsiManagerImpl)PsiManager.getInstance(project), fileElement);
LOG.assertTrue(name != null);
myName = name;
myFile = null;
myElementType = elementType;
myContentElementType = contentElementType;
final FileElement parent = getTreeElement();
char[] chars = CharArrayUtil.fromSequence(text);
TreeElement contentElement = createContentLeafElement(chars, 0, text.length(), parent.getCharTable());
TreeUtil.addChildren(parent, contentElement);
myModificationStamp = LocalTimeCounter.currentTime();
}
@@ -1,12 +1,13 @@
package com.intellij.psi.impl.source;
import com.intellij.lang.ASTNode;
import com.intellij.lang.Language;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.RepositoryElementsManager;
import com.intellij.psi.impl.source.tree.RepositoryTreeElement;
import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.lang.ASTNode;
public class SourceTreeToPsiMap {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.SourceTreeToPsiMap");
@@ -23,9 +24,15 @@ public class SourceTreeToPsiMap {
return RepositoryElementsManager.getOrFindPsiElement((RepositoryTreeElement)element);
}
else {
//TODO!!!
PsiElement psiElement = element.getUserData(TreeElement.PSI_ELEMENT_KEY);
if (psiElement != null) return psiElement;
final Language lang = element.getElementType().getLanguage();
if (lang != null) {
psiElement = lang.getParserDefinition().createElement(element);
element.putUserData(TreeElement.PSI_ELEMENT_KEY, psiElement);
return psiElement;
}
LOG.error("Not PsiElement:" + element);
return null;
}
@@ -1,5 +1,6 @@
package com.intellij.psi.impl.source.tree;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.PsiElement;
@@ -12,7 +13,6 @@ import com.intellij.psi.impl.source.tree.java.ReplaceExpressionUtil;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.CharTable;
import com.intellij.lang.ASTNode;
public class CompositeElement extends TreeElement implements Cloneable {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.CompositeElement");
@@ -132,6 +132,14 @@ public class CompositeElement extends TreeElement implements Cloneable {
}
}
public ASTNode findChildByType(IElementType type) {
return TreeUtil.findChild(this, type);
}
public ASTNode[] findChildrenByFilter(TokenSet filter) {
return TreeUtil.findChildren(this, filter);
}
public String getText() {
return getText(SharedImplUtil.findCharTableByTree(this));
}
@@ -1,12 +1,11 @@
package com.intellij.psi.impl.source.tree;
import com.intellij.lang.ASTNode;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.CharTable;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.text.StringSearcher;
import com.intellij.lang.ASTNode;
import sun.plugin.dom.exception.InvalidStateException;
public abstract class LeafElement extends TreeElement {
private volatile int myState = 0; // 16 bit for type, 15 bit for state and 1 bit for parentFlag
@@ -124,6 +123,14 @@ public abstract class LeafElement extends TreeElement {
public abstract int getCharTabIndex();
public ASTNode findChildByType(IElementType type) {
return null;
}
public ASTNode[] findChildrenByFilter(TokenSet filter) {
return ASTNode.EMPTY_ARRAY;
}
public ASTNode getFirstChildNode() {
return null;
}
@@ -1,14 +1,16 @@
package com.intellij.psi.impl.source.tree;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.impl.DebugUtil;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.CharTable;
import com.intellij.lang.ASTNode;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class TreeUtil {
@@ -34,6 +36,19 @@ public class TreeUtil {
return null;
}
public static ASTNode[] findChildren(ASTNode parent, TokenSet types) {
if (DebugUtil.CHECK_INSIDE_ATOMIC_ACTION_ENABLED){
ApplicationManager.getApplication().assertReadAccessAllowed();
}
List<ASTNode> result = new ArrayList<ASTNode>();
for(ASTNode element = parent.getFirstChildNode(); element != null; element = element.getTreeNext()){
if (types.isInSet(element.getElementType())) {
result.add(element);
}
}
return result.toArray(new ASTNode[result.size()]);
}
public static ASTNode findChildBackward(ASTNode parent, IElementType type) {
if (DebugUtil.CHECK_INSIDE_ATOMIC_ACTION_ENABLED){
ApplicationManager.getApplication().assertReadAccessAllowed();