diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/AutoCastUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/AutoCastUtils.java index 4991d3c4785..2f6a7c0a84d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/AutoCastUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/AutoCastUtils.java @@ -44,6 +44,7 @@ public class AutoCastUtils { private AutoCastUtils() {} + @NotNull public static List getAutoCastVariants( @NotNull ReceiverValue receiverToCast, @NotNull ResolutionContext context @@ -51,6 +52,7 @@ public class AutoCastUtils { return getAutoCastVariants(receiverToCast, context.trace.getBindingContext(), context.dataFlowInfo); } + @NotNull public static List getAutoCastVariants( @NotNull ReceiverValue receiverToCast, @NotNull BindingContext bindingContext, diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeUtils.java index 6a5f9136b10..4156794b958 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/JetScopeUtils.java @@ -36,6 +36,7 @@ import java.util.Set; public final class JetScopeUtils { private JetScopeUtils() {} + @NotNull public static List getImplicitReceiversHierarchyValues(@NotNull JetScope scope) { Collection hierarchy = scope.getImplicitReceiversHierarchy(); @@ -56,6 +57,7 @@ public final class JetScopeUtils { * @param scope Scope for query extensions. * @return extension descriptors. */ + @NotNull public static Collection getAllExtensions(@NotNull JetScope scope) { Set result = Sets.newHashSet(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/Qualifier.kt b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/Qualifier.kt index 198bc316a39..409b37a2d3f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/Qualifier.kt +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/Qualifier.kt @@ -37,19 +37,19 @@ import kotlin.properties.Delegates public trait Qualifier { - val expression: JetExpression + public val expression: JetExpression - val packageView: PackageViewDescriptor? + public val packageView: PackageViewDescriptor? - val classifier: ClassifierDescriptor? + public val classifier: ClassifierDescriptor? - val name: Name + public val name: Name get() = classifier?.getName() ?: packageView!!.getName() // package, classifier or class object descriptor - val resultingDescriptor: DeclarationDescriptor + public val resultingDescriptor: DeclarationDescriptor - val scope: JetScope + public val scope: JetScope } class QualifierReceiver ( diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/TipsManager.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/TipsManager.java deleted file mode 100644 index 33dcc443275..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/TipsManager.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright 2010-2013 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 com.google.common.base.Predicate; -import com.google.common.collect.Collections2; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import com.intellij.psi.PsiElement; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.psi.psiUtil.PsiUtilPackage; -import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastUtils; -import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; -import org.jetbrains.jet.lang.resolve.scopes.JetScope; -import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils; -import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; -import org.jetbrains.jet.lang.resolve.scopes.receivers.Qualifier; -import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; -import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils; - -import java.util.*; - -import static org.jetbrains.jet.lang.resolve.bindingContextUtil.BindingContextUtilPackage.getDataFlowInfo; - -public final class TipsManager { - - private TipsManager() { - } - - @NotNull - public static Collection getReferenceVariants( - @NotNull JetSimpleNameExpression expression, - @NotNull BindingContext context - ) { - JetExpression receiverExpression = PsiUtilPackage.getReceiverExpression(expression); - PsiElement parent = expression.getParent(); - boolean inPositionForCompletionWithReceiver = parent instanceof JetCallExpression || parent instanceof JetQualifiedExpression; - if (receiverExpression != null && inPositionForCompletionWithReceiver) { - Set descriptors = new HashSet(); - // Process as call expression - JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression); - if (resolutionScope == null) return descriptors; - - Qualifier qualifier = context.get(BindingContext.QUALIFIER, receiverExpression); - if (qualifier != null) { - // It's impossible to add extension function for package or class (if it's class object, expression type is not null) - descriptors.addAll(excludePrivateDescriptors(qualifier.getScope().getAllDescriptors())); - } - - JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression); - if (expressionType != null && !expressionType.isError()) { - ExpressionReceiver receiverValue = new ExpressionReceiver(receiverExpression, expressionType); - - DataFlowInfo info = getDataFlowInfo(context, expression); - - List variantsForExplicitReceiver = AutoCastUtils.getAutoCastVariants(receiverValue, context, info); - - for (JetType variant : variantsForExplicitReceiver) { - descriptors.addAll(excludePrivateDescriptors(variant.getMemberScope().getAllDescriptors())); - } - - descriptors.addAll(externalCallableExtensions(resolutionScope, receiverValue, context, info)); - } - - return descriptors; - } - else { - return getVariantsNoReceiver(expression, context); - } - } - - public static Collection getVariantsNoReceiver(JetExpression expression, BindingContext context) { - JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression); - if (resolutionScope != null) { - if (expression.getParent() instanceof JetImportDirective || expression.getParent() instanceof JetPackageDirective) { - return excludeNonPackageDescriptors(resolutionScope.getAllDescriptors()); - } - else { - Collection descriptorsSet = Sets.newHashSet(); - - List result = resolutionScope.getImplicitReceiversHierarchy(); - - for (ReceiverParameterDescriptor receiverDescriptor : result) { - JetType receiverType = receiverDescriptor.getType(); - for (DeclarationDescriptor member : receiverType.getMemberScope().getAllDescriptors()) { - // skip member extension functions&properties - if (member instanceof CallableDescriptor && ((CallableDescriptor) member).getReceiverParameter() != null) continue; - - descriptorsSet.add(member); - } - } - - descriptorsSet.addAll(resolutionScope.getAllDescriptors()); - - DataFlowInfo info = getDataFlowInfo(context, expression); - - return excludeNotCallableExtensions(excludePrivateDescriptors(descriptorsSet), resolutionScope, context, info); - } - } - return Collections.emptyList(); - } - - @NotNull - public static Collection getPackageReferenceVariants( - JetSimpleNameExpression expression, - BindingContext context - ) { - JetScope resolutionScope = context.get(BindingContext.RESOLUTION_SCOPE, expression); - if (resolutionScope != null) { - return excludeNonPackageDescriptors(resolutionScope.getAllDescriptors()); - } - - return Collections.emptyList(); - } - - private static Collection excludePrivateDescriptors( - @NotNull Collection descriptors - ) { - - return Collections2.filter(descriptors, new Predicate() { - @Override - public boolean apply(@Nullable DeclarationDescriptor descriptor) { - if (descriptor == null) { - return false; - } - - return true; - } - }); - } - - public static Collection excludeNotCallableExtensions( - @NotNull Collection descriptors, - @NotNull JetScope scope, - @NotNull final BindingContext context, - @NotNull final DataFlowInfo dataFlowInfo - ) { - Set descriptorsSet = Sets.newHashSet(descriptors); - - final List result = scope.getImplicitReceiversHierarchy(); - - descriptorsSet.removeAll( - Collections2.filter(JetScopeUtils.getAllExtensions(scope), new Predicate() { - @Override - public boolean apply(CallableDescriptor callableDescriptor) { - if (callableDescriptor.getReceiverParameter() == null) { - return false; - } - for (ReceiverParameterDescriptor receiverDescriptor : result) { - if (ExpressionTypingUtils.checkIsExtensionCallable(receiverDescriptor.getValue(), callableDescriptor, context, dataFlowInfo)) { - return false; - } - } - return true; - } - })); - - return Lists.newArrayList(descriptorsSet); - } - - private static Collection excludeNonPackageDescriptors( - @NotNull Collection descriptors - ) { - return Collections2.filter(descriptors, new Predicate() { - @Override - public boolean apply(DeclarationDescriptor declarationDescriptor) { - if (declarationDescriptor instanceof PackageViewDescriptor) { - // Heuristic: we don't want to complete "System" in "package java.lang.Sys", - // so we find class of the same name as package, we exclude this package - PackageViewDescriptor parent = ((PackageViewDescriptor) declarationDescriptor).getContainingDeclaration(); - if (parent != null) { - JetScope parentScope = parent.getMemberScope(); - return parentScope.getClassifier(declarationDescriptor.getName()) == null; - } - return true; - } - return false; - } - }); - } - - private static Collection externalCallableExtensions( - @NotNull JetScope externalScope, - @NotNull final ReceiverValue receiverValue, - @NotNull final BindingContext context, - @NotNull final DataFlowInfo dataFlowInfo - ) { - return Collections2.filter(JetScopeUtils.getAllExtensions(externalScope), - new Predicate() { - @Override - public boolean apply(CallableDescriptor callableDescriptor) { - return ExpressionTypingUtils.checkIsExtensionCallable(receiverValue, callableDescriptor, context, dataFlowInfo); - } - }); - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/TipsManager.kt b/idea/src/org/jetbrains/jet/plugin/codeInsight/TipsManager.kt new file mode 100644 index 00000000000..4924629feeb --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/TipsManager.kt @@ -0,0 +1,133 @@ +/* + * 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 com.google.common.base.Predicate +import org.jetbrains.jet.lang.descriptors.* +import org.jetbrains.jet.lang.psi.* +import org.jetbrains.jet.lang.psi.psiUtil.* +import org.jetbrains.jet.lang.resolve.BindingContext +import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastUtils +import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo +import org.jetbrains.jet.lang.resolve.scopes.JetScope +import org.jetbrains.jet.lang.resolve.scopes.JetScopeUtils +import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver +import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils + +import java.util.* +import org.jetbrains.jet.lang.resolve.bindingContextUtil.getDataFlowInfo + +public object TipsManager{ + + public fun getReferenceVariants(expression: JetSimpleNameExpression, context: BindingContext): Collection { + val receiverExpression = expression.getReceiverExpression() + val parent = expression.getParent() + val inPositionForCompletionWithReceiver = parent is JetCallExpression || parent is JetQualifiedExpression + if (receiverExpression != null && inPositionForCompletionWithReceiver) { + // Process as call expression + val resolutionScope = context[BindingContext.RESOLUTION_SCOPE, expression] ?: return listOf() + + val descriptors = HashSet() + + val qualifier = context[BindingContext.QUALIFIER, receiverExpression] + if (qualifier != null) { + // It's impossible to add extension function for package or class (if it's class object, expression type is not null) + descriptors.addAll(qualifier.scope.getAllDescriptors()) + } + + val expressionType = context[BindingContext.EXPRESSION_TYPE, receiverExpression] + if (expressionType != null && !expressionType.isError()) { + val receiverValue = ExpressionReceiver(receiverExpression, expressionType) + + val info = context.getDataFlowInfo(expression) + + val variantsForExplicitReceiver = AutoCastUtils.getAutoCastVariants(receiverValue, context, info) + + for (variant in variantsForExplicitReceiver) { + descriptors.addAll(variant.getMemberScope().getAllDescriptors()) + } + + descriptors.addAll(externalCallableExtensions(resolutionScope, receiverValue, context, info)) + } + + return descriptors + } + else { + return getVariantsNoReceiver(expression, context) + } + } + + public fun getVariantsNoReceiver(expression: JetExpression, context: BindingContext): Collection { + val resolutionScope = context[BindingContext.RESOLUTION_SCOPE, expression] ?: return listOf() + val parent = expression.getParent() + if (parent is JetImportDirective || parent is JetPackageDirective) { + return excludeNonPackageDescriptors(resolutionScope.getAllDescriptors()) + } + else { + val descriptorsSet = HashSet() + + for (receiverDescriptor in resolutionScope.getImplicitReceiversHierarchy()) { + receiverDescriptor.getType().getMemberScope().getAllDescriptors().filterTo(descriptorsSet) { + it !is CallableDescriptor || it.getReceiverParameter() == null/*skip member extension functions and properties*/ + } + } + + descriptorsSet.addAll(resolutionScope.getAllDescriptors()) + + return excludeNotCallableExtensions(descriptorsSet, resolutionScope, context, context.getDataFlowInfo(expression)) + } + } + + public fun getPackageReferenceVariants(expression: JetSimpleNameExpression, context: BindingContext): Collection { + val resolutionScope = context[BindingContext.RESOLUTION_SCOPE, expression] ?: return listOf() + return excludeNonPackageDescriptors(resolutionScope.getAllDescriptors()) + } + + public fun excludeNotCallableExtensions(descriptors: Collection, scope: JetScope, context: BindingContext, dataFlowInfo: DataFlowInfo): Collection { + val implicitReceivers = scope.getImplicitReceiversHierarchy() + + val descriptorsSet = HashSet(descriptors) + descriptorsSet.removeAll(JetScopeUtils.getAllExtensions(scope).filter { callable -> + if (callable.getReceiverParameter() == null) + false + else + implicitReceivers.none { ExpressionTypingUtils.checkIsExtensionCallable(it.getValue(), callable, context, dataFlowInfo) } + }) + return descriptorsSet + } + + private fun excludeNonPackageDescriptors(descriptors: Collection): Collection { + return descriptors.filter{ + if (it is PackageViewDescriptor) { + // Heuristic: we don't want to complete "System" in "package java.lang.Sys", + // so we find class of the same name as package, we exclude this package + val parent = it.getContainingDeclaration() + parent == null || parent.getMemberScope().getClassifier(it.getName()) == null + } + else { + false + } + } + } + + private fun externalCallableExtensions(externalScope: JetScope, receiverValue: ReceiverValue, context: BindingContext, dataFlowInfo: DataFlowInfo): Collection { + return JetScopeUtils.getAllExtensions(externalScope).filter { + ExpressionTypingUtils.checkIsExtensionCallable(receiverValue, it, context, dataFlowInfo) + } + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/BaseJetVariableMacro.java b/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/BaseJetVariableMacro.java index 0a4394e480a..386f03d5fc4 100644 --- a/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/BaseJetVariableMacro.java +++ b/idea/src/org/jetbrains/jet/plugin/liveTemplates/macro/BaseJetVariableMacro.java @@ -87,7 +87,7 @@ public abstract class BaseJetVariableMacro extends Macro { DataFlowInfo dataFlowInfo = getDataFlowInfo(bindingContext, contextExpression); List declarations = new ArrayList(); - for (DeclarationDescriptor declarationDescriptor : TipsManager.excludeNotCallableExtensions(filteredDescriptors, scope, bindingContext, dataFlowInfo)) { + for (DeclarationDescriptor declarationDescriptor : TipsManager.INSTANCE$.excludeNotCallableExtensions(filteredDescriptors, scope, bindingContext, dataFlowInfo)) { PsiElement declaration = DescriptorToSourceUtils.descriptorToDeclaration(declarationDescriptor); assert declaration == null || declaration instanceof PsiNamedElement; diff --git a/idea/src/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoHandler.java b/idea/src/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoHandler.java index 673974c6ba6..6978ff698f0 100644 --- a/idea/src/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoHandler.java +++ b/idea/src/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoHandler.java @@ -389,7 +389,7 @@ public class JetFunctionParameterInfoHandler implements ParameterInfoHandlerWith placeDescriptor = scope.getContainingDeclaration(); } - Collection variants = TipsManager.getReferenceVariants(callNameExpression, bindingContext); + Collection variants = TipsManager.INSTANCE$.getReferenceVariants(callNameExpression, bindingContext); Name refName = callNameExpression.getReferencedNameAsName();