Partial body resolve: to take source Kotlin callables with Nothing type from caches

This commit is contained in:
Valentin Kipyatkov
2014-11-19 18:41:58 +03:00
parent 992cdd9fe2
commit e5579bcf32
23 changed files with 301 additions and 13 deletions
@@ -69,6 +69,11 @@ public abstract class ElementResolver {
return resolveToElement(jetElement, false);
}
@NotNull
protected PossiblyNothingCallableNamesService possiblyNothingCallableNamesService() {
return DefaultNothingCallableNamesService.INSTANCE$;
}
@NotNull
public BindingContext resolveToElement(@NotNull JetElement jetElement, boolean partialBodyResolve) {
@SuppressWarnings("unchecked") JetElement elementOfAdditionalResolve = (JetElement) JetPsiUtil.getTopmostParentOfTypes(
@@ -96,7 +101,7 @@ public abstract class ElementResolver {
boolean inBody = body != null && PsiTreeUtil.isAncestor(body, jetElement, false);
Function1<JetElement, Boolean> filter;
if (inBody) {
filter = new PartialBodyResolveFilter(jetElement, body);
filter = new PartialBodyResolveFilter(jetElement, body, possiblyNothingCallableNamesService());
}
else { // do as less as possible body-resolve
filter = new Function1<JetElement, Boolean>() {
@@ -27,10 +27,16 @@ import com.intellij.psi.PsiElement
import org.jetbrains.jet.JetNodeTypes
import org.jetbrains.jet.lang.psi.psiUtil.isAncestor
class PartialBodyResolveFilter(elementToResolve: JetElement, private val body: JetExpression) : (JetElement) -> Boolean {
class PartialBodyResolveFilter(
elementToResolve: JetElement,
private val body: JetExpression,
possiblyNothingCallableNamesService: PossiblyNothingCallableNamesService
) : (JetElement) -> Boolean {
private val statementsToResolve = HashSet<JetExpression>()
private val processedBlocks = HashSet<JetBlockExpression>()
private val possiblyNothingFunctionNames = possiblyNothingCallableNamesService.functionNames()
private val possiblyNothingPropertyNames = possiblyNothingCallableNamesService.propertyNames()
;{
assert(body.isAncestor(elementToResolve, strict = false))
@@ -286,6 +292,13 @@ class PartialBodyResolveFilter(elementToResolve: JetElement, private val body: J
super.visitCallExpression(expression)
}
override fun visitSimpleNameExpression(expression: JetSimpleNameExpression) {
val name = expression.getReferencedName()
if (name in possiblyNothingPropertyNames) {
result.add(expression)
}
}
override fun visitBinaryExpression(expression: JetBinaryExpression) {
if (expression.getOperationToken() == JetTokens.ELVIS) {
// do not search exits after "?:"
@@ -368,9 +381,5 @@ class PartialBodyResolveFilter(elementToResolve: JetElement, private val body: J
private fun JetBlockExpression.lastStatement(): JetExpression?
= getLastChild().siblings(forward = false).filterIsInstance<JetExpression>().firstOrNull()
class object {
private val possiblyNothingFunctionNames = setOf("error") // currently hard-coded
}
}
@@ -0,0 +1,29 @@
/*
* 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.lang.resolve.lazy
public trait PossiblyNothingCallableNamesService {
public fun functionNames(): Set<String>
public fun propertyNames(): Set<String>
}
public object DefaultNothingCallableNamesService : PossiblyNothingCallableNamesService {
private val hardcodedNames = setOf("error")
override fun functionNames() = hardcodedNames
override fun propertyNames(): Set<String> = setOf()
}