Extract reference resolver from ShortenReferences
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright 2010-2014 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 org.jetbrains.jet.lang.psi.JetReferenceExpression
|
||||
import org.jetbrains.jet.lang.psi.JetElement
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext
|
||||
import org.jetbrains.jet.lang.psi.JetFile
|
||||
import org.jetbrains.jet.lang.psi.JetTreeVisitorVoid
|
||||
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
|
||||
import com.intellij.util.containers.HashMap
|
||||
import org.jetbrains.jet.lang.psi.JetUserType
|
||||
import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression
|
||||
import org.jetbrains.jet.lang.psi.JetExpression
|
||||
import org.jetbrains.jet.lang.psi.JetCallExpression
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
|
||||
|
||||
object JetFileReferencesResolver {
|
||||
fun resolve(
|
||||
file: JetFile,
|
||||
elements: Iterable<JetElement>? = null,
|
||||
visitReceivers: Boolean = true,
|
||||
visitShortNames: Boolean = true
|
||||
): Map<JetReferenceExpression, BindingContext> {
|
||||
val visitor = ResolveAllReferencesVisitor(file, visitReceivers, visitShortNames)
|
||||
if (elements != null) {
|
||||
elements.forEach { it.accept(visitor) }
|
||||
}
|
||||
else {
|
||||
file.accept(visitor)
|
||||
}
|
||||
return visitor.result
|
||||
}
|
||||
|
||||
private class ResolveAllReferencesVisitor(file: JetFile, val visitReceivers: Boolean, val visitShortNames: Boolean) : JetTreeVisitorVoid() {
|
||||
private val resolveSession = AnalyzerFacadeWithCache.getLazyResolveSessionForFile(file)
|
||||
private val resolveMap = HashMap<JetReferenceExpression, BindingContext>()
|
||||
|
||||
public val result: Map<JetReferenceExpression, BindingContext> = resolveMap
|
||||
|
||||
[suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")]
|
||||
override fun visitUserType(userType: JetUserType) {
|
||||
if (visitReceivers) {
|
||||
userType.acceptChildren(this)
|
||||
}
|
||||
|
||||
if (visitShortNames || userType.getQualifier() != null) {
|
||||
val referenceExpression = userType.getReferenceExpression()
|
||||
if (referenceExpression != null) {
|
||||
resolveMap[referenceExpression] = resolveSession.resolveToElement(referenceExpression)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitDotQualifiedExpression(expression: JetDotQualifiedExpression) {
|
||||
if (visitReceivers) {
|
||||
expression.acceptChildren(this)
|
||||
}
|
||||
|
||||
val referenceExpression = expression.getSelectorExpression()?.referenceExpression()
|
||||
if (referenceExpression != null) {
|
||||
resolveMap[referenceExpression] = resolveSession.resolveToElement(referenceExpression)
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitSimpleNameExpression(expression: JetSimpleNameExpression) {
|
||||
if (visitShortNames) {
|
||||
resolveMap[expression] = resolveSession.resolveToElement(expression)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun JetExpression.referenceExpression(): JetReferenceExpression? =
|
||||
(if (this is JetCallExpression) getCalleeExpression() else this) as? JetReferenceExpression
|
||||
@@ -29,14 +29,13 @@ public object ShortenReferences {
|
||||
public fun process(elements: Iterable<JetElement>) {
|
||||
for ((file, fileElements) in elements.groupBy { element -> element.getContainingFile() as JetFile }) {
|
||||
// first resolve all qualified references - optimization
|
||||
val resolveAllVisitor = ResolveAllReferencesVisitor(file)
|
||||
processElements(fileElements, resolveAllVisitor)
|
||||
val referenceToContext = JetFileReferencesResolver.resolve(file, fileElements, visitShortNames = false)
|
||||
|
||||
val shortenTypesVisitor = ShortenTypesVisitor(file, resolveAllVisitor.result)
|
||||
val shortenTypesVisitor = ShortenTypesVisitor(file, referenceToContext)
|
||||
processElements(fileElements, shortenTypesVisitor)
|
||||
shortenTypesVisitor.finish()
|
||||
|
||||
processElements(fileElements, ShortenQualifiedExpressionsVisitor(file, resolveAllVisitor.result))
|
||||
processElements(fileElements, ShortenQualifiedExpressionsVisitor(file, referenceToContext))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,33 +45,6 @@ public object ShortenReferences {
|
||||
}
|
||||
}
|
||||
|
||||
private class ResolveAllReferencesVisitor(file: JetFile) : JetTreeVisitorVoid() {
|
||||
private val resolveSession = AnalyzerFacadeWithCache.getLazyResolveSessionForFile(file)
|
||||
private val resolveMap = HashMap<JetReferenceExpression, BindingContext>()
|
||||
|
||||
public val result: Map<JetReferenceExpression, BindingContext> = resolveMap
|
||||
|
||||
override fun visitUserType(userType: JetUserType) {
|
||||
userType.acceptChildren(this)
|
||||
|
||||
if (userType.getQualifier() != null) {
|
||||
val referenceExpression = userType.getReferenceExpression()
|
||||
if (referenceExpression != null) {
|
||||
resolveMap[referenceExpression] = resolveSession.resolveToElement(referenceExpression)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitDotQualifiedExpression(expression: JetDotQualifiedExpression) {
|
||||
expression.acceptChildren(this)
|
||||
|
||||
val referenceExpression = referenceExpression(expression.getSelectorExpression())
|
||||
if (referenceExpression != null) {
|
||||
resolveMap[referenceExpression] = resolveSession.resolveToElement(referenceExpression)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class ShortenTypesVisitor(val file: JetFile, val resolveMap: Map<JetReferenceExpression, BindingContext>) : JetTreeVisitorVoid() {
|
||||
private val resolveSession : ResolveSessionForBodies
|
||||
get() = AnalyzerFacadeWithCache.getLazyResolveSessionForFile(file)
|
||||
@@ -223,14 +195,14 @@ public object ShortenReferences {
|
||||
val isUsageInImport = qualifiedExpression.getParentByType(javaClass<JetImportDirective>()) != null
|
||||
val isClassOrPackage = targetDescriptor is ClassDescriptor || targetDescriptor is PackageViewDescriptor
|
||||
|
||||
val referenceExpression = referenceExpression(qualifiedExpression.getSelectorExpression())!!
|
||||
val referenceExpression = qualifiedExpression.getSelectorExpression()!!.referenceExpression()!!
|
||||
val resolveBefore = resolveState(referenceExpression, bindingContext)
|
||||
|
||||
val copy = qualifiedExpression.copy()
|
||||
|
||||
val selectorExpression = qualifiedExpression.getSelectorExpression()!!
|
||||
val newExpression = qualifiedExpression.replace(selectorExpression) as JetExpression
|
||||
val newReferenceExpression = referenceExpression(newExpression)!!
|
||||
val newReferenceExpression = newExpression.referenceExpression()!!
|
||||
|
||||
val newBindingContext = resolveSession.resolveToElement(newReferenceExpression)
|
||||
val resolveAfter = resolveState(newReferenceExpression, newBindingContext)
|
||||
@@ -266,12 +238,6 @@ public object ShortenReferences {
|
||||
}
|
||||
}
|
||||
|
||||
private fun referenceExpression(selectorExpression: JetExpression?): JetReferenceExpression?
|
||||
= if (selectorExpression is JetCallExpression)
|
||||
selectorExpression.getCalleeExpression() as? JetReferenceExpression
|
||||
else
|
||||
selectorExpression as? JetReferenceExpression
|
||||
|
||||
private fun DeclarationDescriptor.asString() = DescriptorRenderer.TEXT.render(this)
|
||||
|
||||
//TODO: do we need this "IfNeeded" check?
|
||||
|
||||
Reference in New Issue
Block a user