From 07e41c6a31e7bd50ec9f0574ef92da2e084bf955 Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Thu, 3 Feb 2011 16:08:55 +0100 Subject: [PATCH] More validity checks in PSI builder --- .../intellij/lang/impl/PsiBuilderImpl.java | 7 ++ .../intellij/lang/PsiBuilderQuickTest.java | 91 +++++++++++++++++-- 2 files changed, 88 insertions(+), 10 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java b/platform/lang-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java index bab5d812a610..584caf86eeec 100644 --- a/platform/lang-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java +++ b/platform/lang-impl/src/com/intellij/lang/impl/PsiBuilderImpl.java @@ -988,6 +988,8 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { markTokenTypeChecked(); balanceWhiteSpaces(); + LOG.assertTrue(myProduction.size() > 0, "Parser produced no markers. Text:\n" + myText); + final StartMarker rootMarker = (StartMarker)myProduction.get(0); rootMarker.myParent = rootMarker.myFirstChild = rootMarker.myLastChild = rootMarker.myNext = null; StartMarker curNode = rootMarker; @@ -1027,6 +1029,11 @@ public class PsiBuilderImpl extends UserDataHolderBase implements PsiBuilder { LOG.error("Tokens " + missed + " were not inserted into the tree. Text:\n" + myText); } + if (rootMarker.myDoneMarker.myLexemeIndex < myLexemeCount) { + final List missed = CollectionFactory.arrayList(myLexTypes, rootMarker.myDoneMarker.myLexemeIndex, myLexemeCount); + LOG.error("Tokens " + missed + " are outside of root element \"" + rootMarker.myType + "\". Text:\n" + myText); + } + if (myLexStarts.length <= myCurrentLexeme + 1) { resizeLexemes(myCurrentLexeme + 1); } diff --git a/platform/lang-impl/testSrc/com/intellij/lang/PsiBuilderQuickTest.java b/platform/lang-impl/testSrc/com/intellij/lang/PsiBuilderQuickTest.java index c7334ee93512..ab25345b030f 100644 --- a/platform/lang-impl/testSrc/com/intellij/lang/PsiBuilderQuickTest.java +++ b/platform/lang-impl/testSrc/com/intellij/lang/PsiBuilderQuickTest.java @@ -17,6 +17,8 @@ package com.intellij.lang; import com.intellij.lang.impl.PsiBuilderImpl; import com.intellij.lexer.LexerBase; +import com.intellij.openapi.application.ex.ApplicationEx; +import com.intellij.openapi.application.ex.ApplicationManagerEx; import com.intellij.psi.TokenType; import com.intellij.psi.impl.DebugUtil; import com.intellij.psi.impl.source.tree.ASTStructure; @@ -28,6 +30,8 @@ import com.intellij.util.diff.FlyweightCapableTreeStructure; import com.intellij.util.diff.ShallowNodeComparator; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.junit.AfterClass; +import org.junit.BeforeClass; import org.junit.Test; import java.io.IOException; @@ -35,6 +39,7 @@ import java.io.OutputStream; import java.io.PrintStream; import java.util.List; +import static org.easymock.EasyMock.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; @@ -55,6 +60,30 @@ public class PsiBuilderQuickTest { private static final TokenSet WHITESPACE_SET = TokenSet.create(TokenType.WHITE_SPACE); private static final TokenSet COMMENT_SET = TokenSet.create(COMMENT); + private static ApplicationEx myMockApp = null; + + @BeforeClass + public static void setUp() { + if (ApplicationManagerEx.getApplication() == null) { + if (myMockApp == null) { + myMockApp = createMock(ApplicationEx.class); + expect(myMockApp.isInternal()).andReturn(true); + expect(myMockApp.isUnitTestMode()).andReturn(true); + myMockApp.assertReadAccessAllowed(); + expectLastCall().asStub(); + replay(myMockApp); + } + ApplicationManagerEx.setApplication(myMockApp); + } + } + + @AfterClass + public static void tearDown() { + if (myMockApp != null) { + ApplicationManagerEx.setApplication(null); + } + } + @Test public void testPlain() { doTest("a< tokens, boolean atStreamEdge, TokenTextGetter getter) { @@ -403,7 +473,7 @@ public class PsiBuilderQuickTest { } @Test - public void testLightChameleon() throws Exception { + public void testLightChameleon() { final IElementType CHAMELEON_2 = new MyLazyElementType("CHAMELEON_2") { @Override public FlyweightCapableTreeStructure parseContents(LighterLazyParseableNode chameleon) { @@ -578,6 +648,7 @@ public class PsiBuilderQuickTest { final PsiBuilder builder = new PsiBuilderImpl(new MyTestLexer(), TokenSet.EMPTY, TokenSet.EMPTY, text); builder.setDebugMode(true); parser.parse(builder); + builder.getLightTree(); fail("should fail"); } catch (AssertionError e) {