Initial implementation of method separators
#KT-13029 Fixed
This commit is contained in:
@@ -1,17 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2017 JetBrains s.r.o.
|
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
*
|
* that can be found in the license/LICENSE.txt file.
|
||||||
* 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.kotlin.test;
|
package org.jetbrains.kotlin.test;
|
||||||
@@ -115,6 +104,9 @@ public final class InTextDirectivesUtils {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static List<String> findLinesWithPrefixesRemoved(String fileText, boolean trim, String... prefixes) {
|
public static List<String> findLinesWithPrefixesRemoved(String fileText, boolean trim, String... prefixes) {
|
||||||
|
if (prefixes.length == 0) {
|
||||||
|
throw new IllegalArgumentException("Please specify the prefixes to check");
|
||||||
|
}
|
||||||
List<String> result = new ArrayList<>();
|
List<String> result = new ArrayList<>();
|
||||||
List<String> cleanedPrefixes = cleanDirectivesFromComments(Arrays.asList(prefixes));
|
List<String> cleanedPrefixes = cleanDirectivesFromComments(Arrays.asList(prefixes));
|
||||||
|
|
||||||
|
|||||||
@@ -6,24 +6,26 @@
|
|||||||
package org.jetbrains.kotlin.idea.highlighter.markers
|
package org.jetbrains.kotlin.idea.highlighter.markers
|
||||||
|
|
||||||
import com.intellij.codeHighlighting.Pass
|
import com.intellij.codeHighlighting.Pass
|
||||||
import com.intellij.codeInsight.daemon.GutterIconNavigationHandler
|
import com.intellij.codeInsight.daemon.*
|
||||||
import com.intellij.codeInsight.daemon.LineMarkerInfo
|
|
||||||
import com.intellij.codeInsight.daemon.LineMarkerProvider
|
|
||||||
import com.intellij.codeInsight.daemon.NavigateAction
|
|
||||||
import com.intellij.codeInsight.daemon.impl.LineMarkerNavigator
|
import com.intellij.codeInsight.daemon.impl.LineMarkerNavigator
|
||||||
import com.intellij.codeInsight.daemon.impl.MarkerType
|
import com.intellij.codeInsight.daemon.impl.MarkerType
|
||||||
import com.intellij.codeInsight.daemon.impl.PsiElementListNavigator
|
import com.intellij.codeInsight.daemon.impl.PsiElementListNavigator
|
||||||
import com.intellij.codeInsight.navigation.ListBackgroundUpdaterTask
|
import com.intellij.codeInsight.navigation.ListBackgroundUpdaterTask
|
||||||
import com.intellij.icons.AllIcons
|
import com.intellij.icons.AllIcons
|
||||||
import com.intellij.openapi.actionSystem.IdeActions
|
import com.intellij.openapi.actionSystem.IdeActions
|
||||||
|
import com.intellij.openapi.editor.colors.CodeInsightColors
|
||||||
|
import com.intellij.openapi.editor.colors.EditorColorsManager
|
||||||
import com.intellij.openapi.editor.markup.GutterIconRenderer
|
import com.intellij.openapi.editor.markup.GutterIconRenderer
|
||||||
|
import com.intellij.openapi.editor.markup.SeparatorPlacement
|
||||||
import com.intellij.openapi.progress.ProgressManager
|
import com.intellij.openapi.progress.ProgressManager
|
||||||
import com.intellij.openapi.project.DumbService
|
import com.intellij.openapi.project.DumbService
|
||||||
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import com.intellij.psi.NavigatablePsiElement
|
import com.intellij.psi.NavigatablePsiElement
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.psi.PsiMethod
|
import com.intellij.psi.PsiMethod
|
||||||
import com.intellij.psi.PsiNameIdentifierOwner
|
import com.intellij.psi.PsiNameIdentifierOwner
|
||||||
import com.intellij.psi.search.searches.ClassInheritorsSearch
|
import com.intellij.psi.search.searches.ClassInheritorsSearch
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
import org.jetbrains.kotlin.asJava.LightClassUtil
|
import org.jetbrains.kotlin.asJava.LightClassUtil
|
||||||
import org.jetbrains.kotlin.asJava.toLightClass
|
import org.jetbrains.kotlin.asJava.toLightClass
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
@@ -42,6 +44,7 @@ import org.jetbrains.kotlin.idea.search.declarationsSearch.toPossiblyFakeLightMe
|
|||||||
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getPrevSiblingIgnoringWhitespaceAndComments
|
||||||
import java.awt.event.MouseEvent
|
import java.awt.event.MouseEvent
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.swing.Icon
|
import javax.swing.Icon
|
||||||
@@ -49,10 +52,33 @@ import javax.swing.ListCellRenderer
|
|||||||
|
|
||||||
class KotlinLineMarkerProvider : LineMarkerProvider {
|
class KotlinLineMarkerProvider : LineMarkerProvider {
|
||||||
override fun getLineMarkerInfo(element: PsiElement): LineMarkerInfo<PsiElement>? {
|
override fun getLineMarkerInfo(element: PsiElement): LineMarkerInfo<PsiElement>? {
|
||||||
// all Kotlin markers are added in slow marker pass
|
if (DaemonCodeAnalyzerSettings.getInstance().SHOW_METHOD_SEPARATORS) {
|
||||||
|
if (element.canHaveSeparator()) {
|
||||||
|
val prevSibling = element.getPrevSiblingIgnoringWhitespaceAndComments()
|
||||||
|
if (prevSibling.canHaveSeparator() &&
|
||||||
|
(element.wantsSeparator() || prevSibling?.wantsSeparator() == true)) {
|
||||||
|
return createLineSeparatorByElement(element)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun PsiElement?.canHaveSeparator() =
|
||||||
|
this is KtFunction || this is KtClassInitializer || (this is KtProperty && !isLocal)
|
||||||
|
|
||||||
|
private fun PsiElement.wantsSeparator() = StringUtil.getLineBreakCount(text) > 0
|
||||||
|
|
||||||
|
private fun createLineSeparatorByElement(element: PsiElement): LineMarkerInfo<PsiElement> {
|
||||||
|
val anchor = PsiTreeUtil.getDeepestFirst(element)
|
||||||
|
|
||||||
|
val info = LineMarkerInfo(anchor, anchor.textRange, null, Pass.LINE_MARKERS, null, null, GutterIconRenderer.Alignment.RIGHT)
|
||||||
|
info.separatorColor = EditorColorsManager.getInstance().globalScheme.getColor(CodeInsightColors.METHOD_SEPARATORS_COLOR)
|
||||||
|
info.separatorPlacement = SeparatorPlacement.TOP
|
||||||
|
return info
|
||||||
|
}
|
||||||
|
|
||||||
override fun collectSlowLineMarkers(elements: List<PsiElement>, result: MutableCollection<LineMarkerInfo<*>>) {
|
override fun collectSlowLineMarkers(elements: List<PsiElement>, result: MutableCollection<LineMarkerInfo<*>>) {
|
||||||
if (elements.isEmpty()) return
|
if (elements.isEmpty()) return
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
// METHOD_SEPARATORS
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
object BarObj {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
<lineMarker descr="null">fun</lineMarker> baz() {
|
||||||
|
class FooLocal {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fooLocal() {
|
||||||
|
}
|
||||||
|
|
||||||
|
<lineMarker descr="null">fun</lineMarker> barLocal() {
|
||||||
|
}
|
||||||
|
|
||||||
|
val xLocal = run {
|
||||||
|
"x"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
<lineMarker descr="null">val</lineMarker> x = 0
|
||||||
|
|
||||||
|
<lineMarker descr="null">val</lineMarker> y: Int
|
||||||
|
get() = 0
|
||||||
|
|
||||||
|
<lineMarker descr="null">val</lineMarker> z = run {
|
||||||
|
"abc"
|
||||||
|
}
|
||||||
|
|
||||||
|
<lineMarker descr="null">fun</lineMarker> quux() {}
|
||||||
|
fun xyzzy() {}
|
||||||
|
}
|
||||||
@@ -1,21 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
*
|
* that can be found in the license/LICENSE.txt file.
|
||||||
* 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.kotlin.idea.codeInsight
|
package org.jetbrains.kotlin.idea.codeInsight
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings
|
||||||
import com.intellij.codeInsight.daemon.LineMarkerInfo
|
import com.intellij.codeInsight.daemon.LineMarkerInfo
|
||||||
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl
|
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
@@ -33,6 +23,7 @@ import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
|||||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
import org.jetbrains.kotlin.test.TagsTestDataUtil
|
import org.jetbrains.kotlin.test.TagsTestDataUtil
|
||||||
import org.jetbrains.kotlin.test.util.renderAsGotoImplementation
|
import org.jetbrains.kotlin.test.util.renderAsGotoImplementation
|
||||||
@@ -53,6 +44,10 @@ abstract class AbstractLineMarkersTest : KotlinLightCodeInsightFixtureTestCase()
|
|||||||
val fileText = FileUtil.loadFile(File(path))
|
val fileText = FileUtil.loadFile(File(path))
|
||||||
try {
|
try {
|
||||||
ConfigLibraryUtil.configureLibrariesByDirective(myFixture.module, PlatformTestUtil.getCommunityPath(), fileText)
|
ConfigLibraryUtil.configureLibrariesByDirective(myFixture.module, PlatformTestUtil.getCommunityPath(), fileText)
|
||||||
|
if (InTextDirectivesUtils.findStringWithPrefixes(fileText,"METHOD_SEPARATORS") != null) {
|
||||||
|
DaemonCodeAnalyzerSettings.getInstance().SHOW_METHOD_SEPARATORS = true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
myFixture.configureByFile(path)
|
myFixture.configureByFile(path)
|
||||||
val project = myFixture.project
|
val project = myFixture.project
|
||||||
@@ -98,6 +93,7 @@ abstract class AbstractLineMarkersTest : KotlinLightCodeInsightFixtureTestCase()
|
|||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
ConfigLibraryUtil.unconfigureLibrariesByDirective(myModule, fileText)
|
ConfigLibraryUtil.unconfigureLibrariesByDirective(myModule, fileText)
|
||||||
|
DaemonCodeAnalyzerSettings.getInstance().SHOW_METHOD_SEPARATORS = false
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -25,6 +25,12 @@ public class LineMarkersTestGenerated extends AbstractLineMarkersTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/codeInsight/lineMarker"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/codeInsight/lineMarker"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("MethodSeparators.kt")
|
||||||
|
public void testMethodSeparators() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/codeInsight/lineMarker/MethodSeparators.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/codeInsight/lineMarker/overrideImplement")
|
@TestMetadata("idea/testData/codeInsight/lineMarker/overrideImplement")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
Reference in New Issue
Block a user