Add folding doc and multiline comments

This commit is contained in:
Nikolay Krasko
2013-06-18 17:43:57 +04:00
parent 9c604267f8
commit 935c5ec16d
15 changed files with 236 additions and 47 deletions
@@ -32,13 +32,12 @@ import org.jetbrains.jet.completion.AbstractJavaWithLibCompletionTest;
import org.jetbrains.jet.completion.AbstractJetJSCompletionTest;
import org.jetbrains.jet.completion.AbstractKeywordCompletionTest;
import org.jetbrains.jet.jvm.compiler.*;
import org.jetbrains.jet.plugin.codeInsight.moveUpDown.AbstractCodeMoverTest;
import org.jetbrains.jet.psi.AbstractJetPsiMatcherTest;
import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveDescriptorRendererTest;
import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveNamespaceComparingTest;
import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveTest;
import org.jetbrains.jet.modules.xml.AbstractModuleXmlParserTest;
import org.jetbrains.jet.plugin.intentions.AbstractCodeTransformationTest;
import org.jetbrains.jet.plugin.codeInsight.moveUpDown.AbstractCodeMoverTest;
import org.jetbrains.jet.plugin.codeInsight.surroundWith.AbstractSurroundWithTest;
import org.jetbrains.jet.plugin.folding.AbstractKotlinFoldingTest;
import org.jetbrains.jet.plugin.hierarchy.AbstractHierarchyTest;
@@ -46,6 +45,7 @@ import org.jetbrains.jet.plugin.highlighter.AbstractDeprecatedHighlightingTest;
import org.jetbrains.jet.plugin.navigation.JetAbstractGotoSuperTest;
import org.jetbrains.jet.plugin.quickfix.AbstractQuickFixMultiFileTest;
import org.jetbrains.jet.plugin.quickfix.AbstractQuickFixTest;
import org.jetbrains.jet.psi.AbstractJetPsiMatcherTest;
import org.jetbrains.jet.resolve.AbstractResolveTest;
import org.jetbrains.jet.test.generator.SimpleTestClassModel;
import org.jetbrains.jet.test.generator.TestClassModel;
@@ -307,7 +307,8 @@ public class GenerateTests {
"idea/tests/",
"KotlinFoldingTestGenerated",
AbstractKotlinFoldingTest.class,
testModel("idea/testData/folding")
testModel("idea/testData/folding/noCollapse", "doTest"),
testModel("idea/testData/folding/checkCollapse", "doSettingsFoldingTest")
);
generateTest(
@@ -16,6 +16,7 @@
package org.jetbrains.jet.plugin;
import com.intellij.codeInsight.folding.JavaCodeFoldingSettings;
import com.intellij.lang.ASTNode;
import com.intellij.lang.folding.FoldingBuilderEx;
import com.intellij.lang.folding.FoldingDescriptor;
@@ -23,9 +24,11 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.JetNodeTypes;
import org.jetbrains.jet.kdoc.lexer.KDocTokens;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetImportDirective;
import org.jetbrains.jet.lexer.JetTokens;
@@ -61,8 +64,8 @@ public class JetFoldingBuilder extends FoldingBuilderEx implements DumbAware {
private static void appendDescriptors(ASTNode node, Document document, List<FoldingDescriptor> descriptors) {
TextRange textRange = node.getTextRange();
IElementType type = node.getElementType();
if ((type == JetNodeTypes.BLOCK || type == JetNodeTypes.CLASS_BODY) &&
!isOneLine(textRange, document)) {
if ((type == JetNodeTypes.BLOCK || type == JetNodeTypes.CLASS_BODY || type == JetTokens.BLOCK_COMMENT || type == KDocTokens.KDOC) &&
!isOneLine(textRange, document)) {
descriptors.add(new FoldingDescriptor(node, textRange));
}
else if (node.getElementType() == JetTokens.IDE_TEMPLATE_START) {
@@ -87,29 +90,54 @@ public class JetFoldingBuilder extends FoldingBuilderEx implements DumbAware {
}
@Override
public String getPlaceholderText(@NotNull ASTNode astNode, @NotNull TextRange range) {
ASTNode prev = astNode.getTreePrev();
ASTNode next = astNode.getTreeNext();
public String getPlaceholderText(@NotNull ASTNode node) {
ASTNode prev = node.getTreePrev();
ASTNode next = node.getTreeNext();
if (prev != null && next != null && prev.getElementType() == JetTokens.IDE_TEMPLATE_START
&& next.getElementType() == JetTokens.IDE_TEMPLATE_END) {
return astNode.getText();
&& next.getElementType() == JetTokens.IDE_TEMPLATE_END) {
return node.getText();
}
if (astNode.getPsi() instanceof JetImportDirective) {
if (node.getElementType() == JetTokens.BLOCK_COMMENT) {
return "/.../";
}
if (node.getElementType() == KDocTokens.KDOC) {
return "/**...*/";
}
if (node.getPsi() instanceof JetImportDirective) {
return "...";
}
return "{...}";
}
@Override
public String getPlaceholderText(@NotNull ASTNode node) {
return "{...}";
public boolean isCollapsedByDefault(@NotNull ASTNode astNode) {
JavaCodeFoldingSettings settings = JavaCodeFoldingSettings.getInstance();
if (astNode.getPsi() instanceof JetImportDirective) {
return settings.isCollapseImports();
}
IElementType type = astNode.getElementType();
if (type == JetTokens.BLOCK_COMMENT || type == KDocTokens.KDOC) {
if (isFirstElementInFile(astNode.getPsi())) {
return settings.isCollapseFileHeader();
}
}
return false;
}
@Override
public boolean isCollapsedByDefault(@NotNull ASTNode astNode) {
if (astNode.getPsi() instanceof JetImportDirective) {
return true;
private static boolean isFirstElementInFile(PsiElement element) {
PsiElement parent = element.getParent();
if (parent instanceof JetFile) {
PsiElement firstChild = parent.getFirstChild();
if (firstChild instanceof PsiWhiteSpace) {
firstChild = firstChild.getNextSibling();
}
return element == firstChild;
}
return false;
}
}
@@ -0,0 +1,11 @@
<fold text='/**...*/' expand='~false~'>/**
* Some header kdoc
*/</fold>
package some
<fold text='/**...*/' expand='true'>/**
* Other
*/</fold>
// SET_TRUE: setCollapseFileHeader
@@ -0,0 +1,12 @@
<fold text='/.../' expand='~false~'>/*
* Some header
*/</fold>
val a = 12
<fold text='/.../' expand='true'>/*
* Other
*/</fold>
// SET_TRUE: setCollapseFileHeader
@@ -0,0 +1,8 @@
package some
import <fold text='...' expand='~false~'>first
import second</fold>
trait A
// SET_TRUE: setCollapseImports
@@ -0,0 +1,9 @@
<fold text='/**...*/'>/**
* Kdoc licence
*/</fold>
package some
<fold text='/**...*/'>/**
* Some Kdoc comment
*/</fold>
class A
@@ -0,0 +1,4 @@
<fold text='/.../'>/*
* Some multiline comment
*/</fold>
class A
@@ -16,22 +16,92 @@
package org.jetbrains.jet.plugin.folding;
import com.intellij.codeInsight.folding.JavaCodeFoldingSettings;
import com.intellij.codeInsight.folding.impl.JavaCodeFoldingSettingsImpl;
import com.intellij.openapi.editor.FoldRegion;
import com.intellij.openapi.editor.ex.FoldingModelEx;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.LightProjectDescriptor;
import com.intellij.testFramework.PlatformTestCase;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.plugin.JetLightProjectDescriptor;
import org.jetbrains.jet.testing.SettingsConfigurator;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
public abstract class AbstractKotlinFoldingTest extends LightCodeInsightFixtureTestCase {
protected void doTest(@NotNull String path) {
myFixture.testFolding(path);
}
protected void doSettingsFoldingTest(@NotNull String path) {
String fileText;
try {
fileText = StringUtil.convertLineSeparators(FileUtil.loadFile(new File(path)));
}
catch (IOException e) {
throw new RuntimeException(e);
}
JavaCodeFoldingSettings settings = JavaCodeFoldingSettings.getInstance();
JavaCodeFoldingSettingsImpl restoreSettings = new JavaCodeFoldingSettingsImpl();
restoreSettings.loadState((JavaCodeFoldingSettingsImpl) settings);
try {
String directText = fileText.replaceAll("~true~", "true").replaceAll("~false~", "false");
directText += "\n\n// Generated from: " + path;
doExpandSettingsTest(directText, settings);
// Clean all regions in model to force IDEA treat all regions as new ones
cleanAllFoldedRegions();
String invertedText = fileText
.replaceAll("~false~", "true").replaceAll("~true~", "false")
.replaceAll(SettingsConfigurator.SET_TRUE_DIRECTIVE, "~TEMP_TRUE_DIRECTIVE~")
.replaceAll(SettingsConfigurator.SET_FALSE_DIRECTIVE, SettingsConfigurator.SET_TRUE_DIRECTIVE)
.replaceAll("~TEMP_TRUE_DIRECTIVE~", SettingsConfigurator.SET_FALSE_DIRECTIVE);
invertedText += "\n\n// Generated from: " + path + " with !INVERTED! settings";
doExpandSettingsTest(invertedText, settings);
}
catch (IOException e) {
throw new IllegalStateException(e);
}
finally {
((JavaCodeFoldingSettingsImpl) JavaCodeFoldingSettings.getInstance()).loadState(restoreSettings);
}
}
private void cleanAllFoldedRegions() {
final FoldingModelEx model = (FoldingModelEx) myFixture.getEditor().getFoldingModel();
Runnable runnable = new Runnable() {
@Override
public void run() {
for (FoldRegion region : model.getAllFoldRegions()) {
model.removeFoldRegion(region);
}
}
};
model.runBatchFoldingOperation(runnable);
}
private void doExpandSettingsTest(String fileText, JavaCodeFoldingSettings settings) throws IOException {
SettingsConfigurator configurator = new SettingsConfigurator(fileText, settings);
configurator.configureSettings();
VirtualFile tempFile = PlatformTestCase.createTempFile("kt", null, fileText, Charset.defaultCharset());
myFixture.testFoldingWithCollapseStatus(tempFile.getPath());
}
@NotNull
@Override
protected LightProjectDescriptor getProjectDescriptor() {
return JetLightProjectDescriptor.INSTANCE;
}
}
@@ -30,35 +30,78 @@ import org.jetbrains.jet.plugin.folding.AbstractKotlinFoldingTest;
/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("idea/testData/folding")
@InnerTestClasses({KotlinFoldingTestGenerated.NoCollapse.class, KotlinFoldingTestGenerated.CheckCollapse.class})
public class KotlinFoldingTestGenerated extends AbstractKotlinFoldingTest {
public void testAllFilesPresentInFolding() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/folding"), Pattern.compile("^(.+)\\.kt$"), true);
@TestMetadata("idea/testData/folding/noCollapse")
public static class NoCollapse extends AbstractKotlinFoldingTest {
public void testAllFilesPresentInNoCollapse() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/folding/noCollapse"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("class.kt")
public void testClass() throws Exception {
doTest("idea/testData/folding/noCollapse/class.kt");
}
@TestMetadata("function.kt")
public void testFunction() throws Exception {
doTest("idea/testData/folding/noCollapse/function.kt");
}
@TestMetadata("imports.kt")
public void testImports() throws Exception {
doTest("idea/testData/folding/noCollapse/imports.kt");
}
@TestMetadata("kdocComments.kt")
public void testKdocComments() throws Exception {
doTest("idea/testData/folding/noCollapse/kdocComments.kt");
}
@TestMetadata("multilineComments.kt")
public void testMultilineComments() throws Exception {
doTest("idea/testData/folding/noCollapse/multilineComments.kt");
}
@TestMetadata("object.kt")
public void testObject() throws Exception {
doTest("idea/testData/folding/noCollapse/object.kt");
}
@TestMetadata("oneImport.kt")
public void testOneImport() throws Exception {
doTest("idea/testData/folding/noCollapse/oneImport.kt");
}
}
@TestMetadata("class.kt")
public void testClass() throws Exception {
doTest("idea/testData/folding/class.kt");
@TestMetadata("idea/testData/folding/checkCollapse")
public static class CheckCollapse extends AbstractKotlinFoldingTest {
public void testAllFilesPresentInCheckCollapse() throws Exception {
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/folding/checkCollapse"), Pattern.compile("^(.+)\\.kt$"), true);
}
@TestMetadata("headerKDoc.kt")
public void testHeaderKDoc() throws Exception {
doSettingsFoldingTest("idea/testData/folding/checkCollapse/headerKDoc.kt");
}
@TestMetadata("headerMultilineComment.kt")
public void testHeaderMultilineComment() throws Exception {
doSettingsFoldingTest("idea/testData/folding/checkCollapse/headerMultilineComment.kt");
}
@TestMetadata("imports.kt")
public void testImports() throws Exception {
doSettingsFoldingTest("idea/testData/folding/checkCollapse/imports.kt");
}
}
@TestMetadata("function.kt")
public void testFunction() throws Exception {
doTest("idea/testData/folding/function.kt");
public static Test suite() {
TestSuite suite = new TestSuite("KotlinFoldingTestGenerated");
suite.addTestSuite(NoCollapse.class);
suite.addTestSuite(CheckCollapse.class);
return suite;
}
@TestMetadata("imports.kt")
public void testImports() throws Exception {
doTest("idea/testData/folding/imports.kt");
}
@TestMetadata("object.kt")
public void testObject() throws Exception {
doTest("idea/testData/folding/object.kt");
}
@TestMetadata("oneImport.kt")
public void testOneImport() throws Exception {
doTest("idea/testData/folding/oneImport.kt");
}
}
@@ -24,13 +24,16 @@ import java.lang.reflect.Method;
import java.util.Arrays;
public class SettingsConfigurator {
public static final String SET_TRUE_DIRECTIVE = "SET_TRUE:";
public static final String SET_FALSE_DIRECTIVE = "SET_FALSE:";
private final String[] settingsToTrue;
private final String[] settingsToFalse;
private final Object[] objects;
public SettingsConfigurator(String fileText, Object... objects) {
settingsToTrue = InTextDirectivesUtils.findArrayWithPrefixes(fileText, "// SET_TRUE:");
settingsToFalse = InTextDirectivesUtils.findArrayWithPrefixes(fileText, "// SET_FALSE:");
settingsToTrue = InTextDirectivesUtils.findArrayWithPrefixes(fileText, SET_TRUE_DIRECTIVE);
settingsToFalse = InTextDirectivesUtils.findArrayWithPrefixes(fileText, SET_FALSE_DIRECTIVE);
this.objects = objects;
}