diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetModifiableBlockHelper.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetModifiableBlockHelper.java index e78f20432b1..70ed7f8c362 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetModifiableBlockHelper.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetModifiableBlockHelper.java @@ -26,7 +26,9 @@ public final class JetModifiableBlockHelper { private JetModifiableBlockHelper() { } - // TODO: Need tests for this method + /** + * Tested in OutOfBlockModificationTest + */ public static boolean shouldChangeModificationCount(PsiElement place) { JetDeclaration declaration = PsiTreeUtil.getParentOfType(place, JetDeclaration.class, true); if (declaration != null) { @@ -38,6 +40,9 @@ public final class JetModifiableBlockHelper { return shouldChangeModificationCount(function); } + else if (declaration instanceof JetPropertyAccessor) { + return false; + } else if (declaration instanceof JetProperty) { JetProperty property = (JetProperty) declaration; if (property.getPropertyTypeRef() != null) { @@ -47,6 +52,7 @@ public final class JetModifiableBlockHelper { return shouldChangeModificationCount(property); } else if (declaration instanceof JetFunctionLiteral) { + // TODO: Check return type return shouldChangeModificationCount(declaration); } } diff --git a/idea/testData/codeInsight/outOfBlock/FunInFun.kt b/idea/testData/codeInsight/outOfBlock/FunInFun.kt new file mode 100644 index 00000000000..0b3c23504f1 --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/FunInFun.kt @@ -0,0 +1,4 @@ +// FALSE +fun main() { + fun some = 12 +} \ No newline at end of file diff --git a/idea/testData/codeInsight/outOfBlock/FunNoBody.kt b/idea/testData/codeInsight/outOfBlock/FunNoBody.kt new file mode 100644 index 00000000000..458f568b695 --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/FunNoBody.kt @@ -0,0 +1,2 @@ +// TRUE +fun some() = 12 \ No newline at end of file diff --git a/idea/testData/codeInsight/outOfBlock/InClass.kt b/idea/testData/codeInsight/outOfBlock/InClass.kt new file mode 100644 index 00000000000..6a6e0731fd1 --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/InClass.kt @@ -0,0 +1,4 @@ +// TRUE +class Some { + fun +} diff --git a/idea/testData/codeInsight/outOfBlock/InClassPropertyAccessor.kt b/idea/testData/codeInsight/outOfBlock/InClassPropertyAccessor.kt new file mode 100644 index 00000000000..41d43fc007f --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/InClassPropertyAccessor.kt @@ -0,0 +1,9 @@ +// FALSE +class Test { + val more : Int = 0 + val test : Int + get() { + + return more + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/outOfBlock/InFunWithInference.kt b/idea/testData/codeInsight/outOfBlock/InFunWithInference.kt new file mode 100644 index 00000000000..9db1fbd928f --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/InFunWithInference.kt @@ -0,0 +1,2 @@ +// TRUE +fun more() = { println } \ No newline at end of file diff --git a/idea/testData/codeInsight/outOfBlock/InFunctionLiteral.kt b/idea/testData/codeInsight/outOfBlock/InFunctionLiteral.kt new file mode 100644 index 00000000000..0a22e760487 --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/InFunctionLiteral.kt @@ -0,0 +1,5 @@ +// FALSE + +fun main() { + jq() { pri } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/outOfBlock/InMethod.kt b/idea/testData/codeInsight/outOfBlock/InMethod.kt new file mode 100644 index 00000000000..5760a37a861 --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/InMethod.kt @@ -0,0 +1,6 @@ +// FALSE + +fun test() { + val a = 1 +} + diff --git a/idea/testData/codeInsight/outOfBlock/InPropertyWithFunctionLiteral.kt b/idea/testData/codeInsight/outOfBlock/InPropertyWithFunctionLiteral.kt new file mode 100644 index 00000000000..083f7a24071 --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/InPropertyWithFunctionLiteral.kt @@ -0,0 +1,4 @@ +// FALSE +class Test { + val a : () -> Int = { pri } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/outOfBlock/InPropertyWithInference.kt b/idea/testData/codeInsight/outOfBlock/InPropertyWithInference.kt new file mode 100644 index 00000000000..5cde4f2a5c2 --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/InPropertyWithInference.kt @@ -0,0 +1,4 @@ +// TRUE +class Test { + val a = "aasdf" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/OutOfBlockModificationTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/OutOfBlockModificationTest.java new file mode 100644 index 00000000000..c81dd27ed55 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/OutOfBlockModificationTest.java @@ -0,0 +1,119 @@ +/* + * Copyright 2010-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight; + +import com.intellij.psi.*; +import com.intellij.psi.impl.JavaCodeBlockModificationListener; +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import org.jetbrains.jet.plugin.PluginTestCaseBase; + +/** + * @author Nikolay Krasko + */ +public class OutOfBlockModificationTest extends LightCodeInsightFixtureTestCase { + + public void testFunInFun() { + doTest(); + } + + public void testFunNoBody() { + doTest(); + } + + public void testInClass() { + doTest(); + } + + public void testInClassPropertyAccessor() { + doTest(); + } + + public void testInFunctionLiteral() { + doTest(); + } + + public void testInFunWithInference() { + doTest(); + } + + public void testInMethod() { + doTest(); + } + + public void testInPropertyWithFunctionLiteral() { + doTest(); + } + + public void testInPropertyWithInference() { + doTest(); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + myFixture.setTestDataPath(PluginTestCaseBase.getTestDataPathBase() + "/codeInsight/outOfBlock"); + } + + protected void doTest() { + myFixture.configureByFile(getTestName(false) + ".kt"); + String text = myFixture.getDocument(myFixture.getFile()).getText(); + + boolean expectedOutOfBlock = false; + if (text.startsWith("// TRUE")) { + expectedOutOfBlock = true; + } + else if (text.startsWith("// FALSE")) { + expectedOutOfBlock = false; + } + else { + fail("Expectation of code block result test should be configured with " + + "\"// TRUE\" or \"// FALSE\" directive in the beginning of the file"); + } + + PsiElement element = myFixture.getFile().findElementAt(myFixture.getCaretOffset()); + assertNotNull("Should be valid element", element); + + assertEquals("Result for out of block test is differs from expected on element " + element, + !expectedOutOfBlock, isInsideCodeBlock(element)); + } + + /** + * Copy of private {@link JavaCodeBlockModificationListener.isInsideCodeBlock()} + */ + @SuppressWarnings("JavadocReference") + private static boolean isInsideCodeBlock(PsiElement element) { + if (element instanceof PsiFileSystemItem) { + return false; + } + + if (element == null || element.getParent() == null) return true; + + PsiElement parent = element; + while (true) { + if (parent instanceof PsiFile || parent instanceof PsiDirectory || parent == null) { + return false; + } + if (parent instanceof PsiClass) return false; // anonymous or local class + if (parent instanceof PsiModifiableCodeBlock) { + if (!((PsiModifiableCodeBlock)parent).shouldChangeModificationCount(element)) { + return true; + } + } + parent = parent.getParent(); + } + } +}