From d308c959ff5bb4d580af073e07c1ba981a285437 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Thu, 23 Jul 2015 20:40:52 +0300 Subject: [PATCH] Moved soft keyword highlighting and other analysis that do not require keywords into separate pass executed before running any resolve --- .../kotlin/idea/highlighter/JetPsiChecker.kt | 10 --- .../KotlinBeforeResolveHighlightingPass.kt | 81 +++++++++++++++++++ .../LabelsHighlightingVisitor.java | 7 +- .../SoftKeywordsHighlightingVisitor.java | 7 +- .../idea/kdoc/KDocHighlightingVisitor.kt | 7 +- idea/src/META-INF/plugin.xml | 5 +- idea/testData/highlighter/Dynamic.kt | 2 +- 7 files changed, 99 insertions(+), 20 deletions(-) create mode 100644 idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/KotlinBeforeResolveHighlightingPass.kt diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/JetPsiChecker.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/JetPsiChecker.kt index 9e981b0d3ff..a5e2920a947 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/JetPsiChecker.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/JetPsiChecker.kt @@ -48,8 +48,6 @@ import org.jetbrains.kotlin.psi.JetCodeFragment import org.jetbrains.kotlin.psi.JetFile import org.jetbrains.kotlin.psi.JetParameter import org.jetbrains.kotlin.psi.JetReferenceExpression -import org.jetbrains.kotlin.psi.psiUtil.endOffset -import org.jetbrains.kotlin.psi.psiUtil.startOffset import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics import kotlin.platform.platformStatic @@ -59,8 +57,6 @@ public open class JetPsiChecker : Annotator, HighlightRangeExtension { override fun annotate(element: PsiElement, holder: AnnotationHolder) { if (!(ProjectRootsUtil.isInProjectOrLibraryContent(element) || element.getContainingFile() is JetCodeFragment)) return - getBeforeAnalysisVisitors(holder).forEach { visitor -> element.accept(visitor) } - val file = element.getContainingFile() as JetFile val analysisResult = file.analyzeFullyAndGetResult() @@ -240,12 +236,6 @@ public open class JetPsiChecker : Annotator, HighlightRangeExtension { } } - private fun getBeforeAnalysisVisitors(holder: AnnotationHolder) = arrayOf( - SoftKeywordsHighlightingVisitor(holder), - LabelsHighlightingVisitor(holder), - KDocHighlightingVisitor(holder) - ) - private fun getAfterAnalysisVisitor(holder: AnnotationHolder, bindingContext: BindingContext) = arrayOf( PropertiesHighlightingVisitor(holder, bindingContext), FunctionsHighlightingVisitor(holder, bindingContext), diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/KotlinBeforeResolveHighlightingPass.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/KotlinBeforeResolveHighlightingPass.kt new file mode 100644 index 00000000000..f15b5650ddd --- /dev/null +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/KotlinBeforeResolveHighlightingPass.kt @@ -0,0 +1,81 @@ +/* + * Copyright 2010-2015 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.kotlin.idea.highlighter + +import com.intellij.codeHighlighting.Pass +import com.intellij.codeHighlighting.TextEditorHighlightingPass +import com.intellij.codeHighlighting.TextEditorHighlightingPassFactory +import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar +import com.intellij.codeInsight.daemon.impl.AnnotationHolderImpl +import com.intellij.codeInsight.daemon.impl.HighlightInfo +import com.intellij.codeInsight.daemon.impl.UpdateHighlightersUtil +import com.intellij.lang.annotation.AnnotationSession +import com.intellij.openapi.components.AbstractProjectComponent +import com.intellij.openapi.editor.Document +import com.intellij.openapi.editor.Editor +import com.intellij.openapi.progress.ProgressIndicator +import com.intellij.openapi.project.DumbAware +import com.intellij.openapi.project.Project +import com.intellij.psi.PsiElement +import com.intellij.psi.PsiFile +import com.intellij.psi.PsiRecursiveElementVisitor +import org.jetbrains.kotlin.idea.kdoc.KDocHighlightingVisitor +import org.jetbrains.kotlin.psi.JetFile + +public class KotlinBeforeResolveHighlightingPass( + private val file: JetFile, + document: Document +) : TextEditorHighlightingPass(file.project, document), DumbAware { + + private volatile var annotationHolder: AnnotationHolderImpl? = null + + override fun doCollectInformation(progress: ProgressIndicator) { + val annotationHolder = AnnotationHolderImpl(AnnotationSession(file)) + val visitors = listOf( + SoftKeywordsHighlightingVisitor(annotationHolder), + LabelsHighlightingVisitor(annotationHolder), + KDocHighlightingVisitor(annotationHolder) + ) + file.accept(object : PsiRecursiveElementVisitor(){ + override fun visitElement(element: PsiElement) { + super.visitElement(element) + visitors.forEach { element.accept(it) } + } + }) + this.annotationHolder = annotationHolder + } + + override fun doApplyInformationToEditor() { + if (annotationHolder == null) return + + val infos = annotationHolder!!.map { HighlightInfo.fromAnnotation(it) } + + UpdateHighlightersUtil.setHighlightersToEditor(myProject, myDocument!!, 0, file.textLength, infos, colorsScheme, id) + annotationHolder = null + } + + public class Factory(project: Project, registrar: TextEditorHighlightingPassRegistrar) : AbstractProjectComponent(project), TextEditorHighlightingPassFactory { + init { + registrar.registerTextEditorHighlightingPass(this, TextEditorHighlightingPassRegistrar.Anchor.BEFORE, Pass.UPDATE_FOLDING, false, false) + } + + override fun createHighlightingPass(file: PsiFile, editor: Editor): TextEditorHighlightingPass? { + if (file !is JetFile) return null + return KotlinBeforeResolveHighlightingPass(file, editor.document) + } + } +} diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/LabelsHighlightingVisitor.java b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/LabelsHighlightingVisitor.java index ffc45c0accf..78263d417aa 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/LabelsHighlightingVisitor.java +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/LabelsHighlightingVisitor.java @@ -20,10 +20,13 @@ import com.intellij.lang.annotation.AnnotationHolder; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.psi.JetExpressionWithLabel; import org.jetbrains.kotlin.psi.JetSimpleNameExpression; +import org.jetbrains.kotlin.psi.JetVisitorVoid; + +class LabelsHighlightingVisitor extends JetVisitorVoid { + private final AnnotationHolder holder; -class LabelsHighlightingVisitor extends HighlightingVisitor { LabelsHighlightingVisitor(AnnotationHolder holder) { - super(holder); + this.holder = holder; } @Override diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/SoftKeywordsHighlightingVisitor.java b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/SoftKeywordsHighlightingVisitor.java index f53eab183c6..4f2ef9de49e 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/SoftKeywordsHighlightingVisitor.java +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/highlighter/SoftKeywordsHighlightingVisitor.java @@ -26,10 +26,13 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.lexer.JetTokens; import org.jetbrains.kotlin.psi.JetFunctionLiteral; import org.jetbrains.kotlin.psi.JetFunctionLiteralExpression; +import org.jetbrains.kotlin.psi.JetVisitorVoid; + +class SoftKeywordsHighlightingVisitor extends JetVisitorVoid { + private final AnnotationHolder holder; -class SoftKeywordsHighlightingVisitor extends HighlightingVisitor { SoftKeywordsHighlightingVisitor(AnnotationHolder holder) { - super(holder); + this.holder = holder; } @Override diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/kdoc/KDocHighlightingVisitor.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/kdoc/KDocHighlightingVisitor.kt index e8315ae05a9..dffe27910ad 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/kdoc/KDocHighlightingVisitor.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/kdoc/KDocHighlightingVisitor.kt @@ -16,17 +16,16 @@ package org.jetbrains.kotlin.idea.kdoc -import org.jetbrains.kotlin.idea.highlighter.HighlightingVisitor import com.intellij.lang.annotation.AnnotationHolder import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink +import com.intellij.psi.PsiElementVisitor import org.jetbrains.kotlin.idea.highlighter.JetHighlightingColors +import org.jetbrains.kotlin.kdoc.psi.impl.KDocLink -class KDocHighlightingVisitor(holder: AnnotationHolder): HighlightingVisitor(holder) { +class KDocHighlightingVisitor(private val holder: AnnotationHolder): PsiElementVisitor() { override fun visitElement(element: PsiElement) { if (element is KDocLink) { holder.createInfoAnnotation(element, null).setTextAttributes(JetHighlightingColors.KDOC_LINK) } - super.visitElement(element) } } diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 16ac926fb03..e8a15d80c28 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -33,6 +33,9 @@ org.jetbrains.kotlin.idea.js.KotlinJavaScriptLibraryManager + + org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Factory + org.jetbrains.kotlin.idea.completion.LookupCancelWatcher @@ -484,7 +487,7 @@ - + diff --git a/idea/testData/highlighter/Dynamic.kt b/idea/testData/highlighter/Dynamic.kt index 894922be3b4..afa757c84f8 100644 --- a/idea/testData/highlighter/Dynamic.kt +++ b/idea/testData/highlighter/Dynamic.kt @@ -1,6 +1,6 @@ package testing -fun tst(d: dynamic) { +fun tst(d: dynamic) { d.foo() d.foo d.foo = 1