Moved soft keyword highlighting and other analysis that do not require keywords into separate pass executed before running any resolve

This commit is contained in:
Valentin Kipyatkov
2015-07-23 20:40:52 +03:00
parent f378b9bb75
commit d308c959ff
7 changed files with 99 additions and 20 deletions
@@ -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),
@@ -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)
}
}
}
@@ -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
@@ -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
@@ -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)
}
}
+4 -1
View File
@@ -33,6 +33,9 @@
<component>
<implementation-class>org.jetbrains.kotlin.idea.js.KotlinJavaScriptLibraryManager</implementation-class>
</component>
<component>
<implementation-class>org.jetbrains.kotlin.idea.highlighter.KotlinBeforeResolveHighlightingPass$Factory</implementation-class>
</component>
<component>
<implementation-class>org.jetbrains.kotlin.idea.completion.LookupCancelWatcher</implementation-class>
</component>
@@ -484,7 +487,7 @@
<psi.classFileDecompiler implementation="org.jetbrains.kotlin.idea.decompiler.JetClassFileDecompiler"/>
<psi.classFileDecompiler implementation="org.jetbrains.kotlin.idea.decompiler.KotlinJavaScriptMetaFileDecompiler"/>
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.versions.KotlinAbiVersionIndex"/>
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.versions.KotlinJavaScriptAbiVersionIndex"/>
<fileBasedIndex implementation="org.jetbrains.kotlin.idea.vfilefinder.KotlinClassFileIndex"/>
+1 -1
View File
@@ -1,6 +1,6 @@
package testing
fun <info textAttributesKey="KOTLIN_FUNCTION_DECLARATION">tst</info>(<info textAttributesKey="KOTLIN_PARAMETER">d</info>: <error>dynamic</error>) {
fun <info textAttributesKey="KOTLIN_FUNCTION_DECLARATION">tst</info>(<info textAttributesKey="KOTLIN_PARAMETER">d</info>: <error><info>dynamic</info></error>) {
<info textAttributesKey="KOTLIN_PARAMETER">d</info>.<info textAttributesKey="KOTLIN_DYNAMIC_FUNCTION_CALL">foo</info>()
<info textAttributesKey="KOTLIN_PARAMETER">d</info>.<info textAttributesKey="KOTLIN_DYNAMIC_PROPERTY_CALL">foo</info>
<info textAttributesKey="KOTLIN_PARAMETER">d</info>.<info textAttributesKey="KOTLIN_DYNAMIC_PROPERTY_CALL">foo</info> = 1