diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index 62a775547c2..6bfb8439a2c 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -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( diff --git a/idea/src/org/jetbrains/jet/plugin/JetFoldingBuilder.java b/idea/src/org/jetbrains/jet/plugin/JetFoldingBuilder.java index 9e505bbccba..1517c92a1eb 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetFoldingBuilder.java +++ b/idea/src/org/jetbrains/jet/plugin/JetFoldingBuilder.java @@ -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 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; } } diff --git a/idea/testData/folding/checkCollapse/headerKDoc.kt b/idea/testData/folding/checkCollapse/headerKDoc.kt new file mode 100644 index 00000000000..68730fd38c1 --- /dev/null +++ b/idea/testData/folding/checkCollapse/headerKDoc.kt @@ -0,0 +1,11 @@ +/** + * Some header kdoc + */ +package some + +/** + * Other + */ + +// SET_TRUE: setCollapseFileHeader + diff --git a/idea/testData/folding/checkCollapse/headerMultilineComment.kt b/idea/testData/folding/checkCollapse/headerMultilineComment.kt new file mode 100644 index 00000000000..b89b0cc9e3a --- /dev/null +++ b/idea/testData/folding/checkCollapse/headerMultilineComment.kt @@ -0,0 +1,12 @@ +/* + * Some header + */ + +val a = 12 + +/* + * Other + */ + +// SET_TRUE: setCollapseFileHeader + diff --git a/idea/testData/folding/checkCollapse/imports.kt b/idea/testData/folding/checkCollapse/imports.kt new file mode 100644 index 00000000000..6ea9d3cd13c --- /dev/null +++ b/idea/testData/folding/checkCollapse/imports.kt @@ -0,0 +1,8 @@ +package some + +import first +import second + +trait A + +// SET_TRUE: setCollapseImports \ No newline at end of file diff --git a/idea/testData/folding/class.kt b/idea/testData/folding/noCollapse/class.kt similarity index 100% rename from idea/testData/folding/class.kt rename to idea/testData/folding/noCollapse/class.kt diff --git a/idea/testData/folding/function.kt b/idea/testData/folding/noCollapse/function.kt similarity index 100% rename from idea/testData/folding/function.kt rename to idea/testData/folding/noCollapse/function.kt diff --git a/idea/testData/folding/imports.kt b/idea/testData/folding/noCollapse/imports.kt similarity index 100% rename from idea/testData/folding/imports.kt rename to idea/testData/folding/noCollapse/imports.kt diff --git a/idea/testData/folding/noCollapse/kdocComments.kt b/idea/testData/folding/noCollapse/kdocComments.kt new file mode 100644 index 00000000000..fa10d6117f7 --- /dev/null +++ b/idea/testData/folding/noCollapse/kdocComments.kt @@ -0,0 +1,9 @@ +/** + * Kdoc licence + */ +package some + +/** + * Some Kdoc comment + */ +class A \ No newline at end of file diff --git a/idea/testData/folding/noCollapse/multilineComments.kt b/idea/testData/folding/noCollapse/multilineComments.kt new file mode 100644 index 00000000000..846fb05f63d --- /dev/null +++ b/idea/testData/folding/noCollapse/multilineComments.kt @@ -0,0 +1,4 @@ +/* + * Some multiline comment + */ +class A \ No newline at end of file diff --git a/idea/testData/folding/object.kt b/idea/testData/folding/noCollapse/object.kt similarity index 100% rename from idea/testData/folding/object.kt rename to idea/testData/folding/noCollapse/object.kt diff --git a/idea/testData/folding/oneImport.kt b/idea/testData/folding/noCollapse/oneImport.kt similarity index 100% rename from idea/testData/folding/oneImport.kt rename to idea/testData/folding/noCollapse/oneImport.kt diff --git a/idea/tests/org/jetbrains/jet/plugin/folding/AbstractKotlinFoldingTest.java b/idea/tests/org/jetbrains/jet/plugin/folding/AbstractKotlinFoldingTest.java index 6fb9a60988a..9af2be9017d 100644 --- a/idea/tests/org/jetbrains/jet/plugin/folding/AbstractKotlinFoldingTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/folding/AbstractKotlinFoldingTest.java @@ -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; } - - } diff --git a/idea/tests/org/jetbrains/jet/plugin/folding/KotlinFoldingTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/folding/KotlinFoldingTestGenerated.java index 3e430d49709..9d67a84b131 100644 --- a/idea/tests/org/jetbrains/jet/plugin/folding/KotlinFoldingTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/folding/KotlinFoldingTestGenerated.java @@ -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"); - } - } diff --git a/idea/tests/org/jetbrains/jet/testing/SettingsConfigurator.java b/idea/tests/org/jetbrains/jet/testing/SettingsConfigurator.java index b0b69f390e6..3e93e95461c 100644 --- a/idea/tests/org/jetbrains/jet/testing/SettingsConfigurator.java +++ b/idea/tests/org/jetbrains/jet/testing/SettingsConfigurator.java @@ -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; }