mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Initial implementation of JavaScript support.
This commit is contained in:
@@ -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>
|
||||
|
||||
+19
-2
@@ -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();
|
||||
}
|
||||
+1
-5
@@ -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.
|
||||
+13
-5
@@ -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();
|
||||
+4
-4
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public abstract class Language {
|
||||
return null;
|
||||
}
|
||||
|
||||
public ParserDefinition getParserDefinition(Project project) {
|
||||
public ParserDefinition getParserDefinition() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user