KT-768 Code completion for extension functions
This commit is contained in:
@@ -104,6 +104,4 @@ public class JavaPackageScope extends JetScopeImpl {
|
|||||||
private String getQualifiedName(String name) {
|
private String getQualifiedName(String name) {
|
||||||
return (packageFQN.isEmpty() ? "" : packageFQN + ".") + name;
|
return (packageFQN.isEmpty() ? "" : packageFQN + ".") + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.jet.lang.descriptors;
|
package org.jetbrains.jet.lang.descriptors;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||||
@@ -24,6 +25,7 @@ public interface CallableDescriptor extends DeclarationDescriptor {
|
|||||||
/**
|
/**
|
||||||
* Method may return null for not yet fully initialized object or if error occurred.
|
* Method may return null for not yet fully initialized object or if error occurred.
|
||||||
*/
|
*/
|
||||||
|
@Nullable
|
||||||
JetType getReturnType();
|
JetType getReturnType();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ public interface DeclarationDescriptor extends Annotated, Named {
|
|||||||
@Nullable
|
@Nullable
|
||||||
DeclarationDescriptor getContainingDeclaration();
|
DeclarationDescriptor getContainingDeclaration();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
DeclarationDescriptor substitute(TypeSubstitutor substitutor);
|
DeclarationDescriptor substitute(TypeSubstitutor substitutor);
|
||||||
|
|
||||||
<R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data);
|
<R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data);
|
||||||
|
|||||||
@@ -2,14 +2,16 @@ package org.jetbrains.jet.lang.resolve;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Introduces a simple wrapper for internal scope.
|
||||||
|
*
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractScopeAdapter implements JetScope {
|
public abstract class AbstractScopeAdapter implements JetScope {
|
||||||
|
|||||||
@@ -92,7 +92,8 @@ public class CallResolver {
|
|||||||
@NotNull final JetReferenceExpression functionReference,
|
@NotNull final JetReferenceExpression functionReference,
|
||||||
@NotNull String name,
|
@NotNull String name,
|
||||||
@NotNull JetType expectedType) {
|
@NotNull JetType expectedType) {
|
||||||
List<ResolutionTask<FunctionDescriptor>> tasks = TaskPrioritizers.FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(scope, call, name, trace.getBindingContext(), dataFlowInfo);
|
List<ResolutionTask<FunctionDescriptor>> tasks = TaskPrioritizers.FUNCTION_TASK_PRIORITIZER.computePrioritizedTasks(
|
||||||
|
scope, call, name, trace.getBindingContext(), dataFlowInfo);
|
||||||
return doResolveCall(trace, scope, call, expectedType, tasks, functionReference);
|
return doResolveCall(trace, scope, call, expectedType, tasks, functionReference);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,7 +404,11 @@ public class CallResolver {
|
|||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private <D extends CallableDescriptor> OverloadResolutionResults<D> performResolution(@NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull JetType expectedType, @NotNull ResolutionTask<D> task, @NotNull TracingStrategy tracing) {
|
private <D extends CallableDescriptor> OverloadResolutionResults<D> performResolution(
|
||||||
|
@NotNull BindingTrace trace,
|
||||||
|
@NotNull JetScope scope, @NotNull JetType expectedType,
|
||||||
|
@NotNull ResolutionTask<D> task, @NotNull TracingStrategy tracing
|
||||||
|
) {
|
||||||
for (ResolvedCallImpl<D> candidateCall : task.getCandidates()) {
|
for (ResolvedCallImpl<D> candidateCall : task.getCandidates()) {
|
||||||
D candidate = candidateCall.getCandidateDescriptor();
|
D candidate = candidateCall.getCandidateDescriptor();
|
||||||
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace);
|
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace);
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Stores candidates for call resolution.
|
||||||
|
*
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
/*package*/ class ResolutionTask<D extends CallableDescriptor> {
|
/*package*/ class ResolutionTask<D extends CallableDescriptor> {
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
|||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
|
||||||
import org.jetbrains.jet.lang.types.NamespaceType;
|
import org.jetbrains.jet.lang.types.NamespaceType;
|
||||||
|
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -32,8 +32,11 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
|||||||
/*package*/ abstract class TaskPrioritizer<D extends CallableDescriptor> {
|
/*package*/ abstract class TaskPrioritizer<D extends CallableDescriptor> {
|
||||||
|
|
||||||
public static <D extends CallableDescriptor> void splitLexicallyLocalDescriptors(
|
public static <D extends CallableDescriptor> void splitLexicallyLocalDescriptors(
|
||||||
Collection<ResolvedCallImpl<D>> allDescriptors, DeclarationDescriptor containerOfTheCurrentLocality, Collection<ResolvedCallImpl<D>> local, Collection<ResolvedCallImpl<D>> nonlocal) {
|
@NotNull Collection<ResolvedCallImpl<D>> allDescriptors,
|
||||||
|
@NotNull DeclarationDescriptor containerOfTheCurrentLocality,
|
||||||
|
@NotNull Collection<ResolvedCallImpl<D>> local,
|
||||||
|
@NotNull Collection<ResolvedCallImpl<D>> nonlocal
|
||||||
|
) {
|
||||||
for (ResolvedCallImpl<D> resolvedCall : allDescriptors) {
|
for (ResolvedCallImpl<D> resolvedCall : allDescriptors) {
|
||||||
if (DescriptorUtils.isLocal(containerOfTheCurrentLocality, resolvedCall.getCandidateDescriptor())) {
|
if (DescriptorUtils.isLocal(containerOfTheCurrentLocality, resolvedCall.getCandidateDescriptor())) {
|
||||||
local.add(resolvedCall);
|
local.add(resolvedCall);
|
||||||
@@ -56,7 +59,9 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ResolutionTask<D>> computePrioritizedTasks(@NotNull JetScope scope, @NotNull Call call, @NotNull String name, @NotNull BindingContext bindingContext, @NotNull DataFlowInfo dataFlowInfo) {
|
@NotNull
|
||||||
|
public List<ResolutionTask<D>> computePrioritizedTasks(@NotNull JetScope scope, @NotNull Call call, @NotNull String name,
|
||||||
|
@NotNull BindingContext bindingContext, @NotNull DataFlowInfo dataFlowInfo) {
|
||||||
List<ResolutionTask<D>> result = Lists.newArrayList();
|
List<ResolutionTask<D>> result = Lists.newArrayList();
|
||||||
|
|
||||||
ReceiverDescriptor explicitReceiver = call.getExplicitReceiver();
|
ReceiverDescriptor explicitReceiver = call.getExplicitReceiver();
|
||||||
|
|||||||
+2
-15
@@ -50,20 +50,17 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
|||||||
JetReferenceExpression nameReference = valueArgument.getArgumentName().getReferenceExpression();
|
JetReferenceExpression nameReference = valueArgument.getArgumentName().getReferenceExpression();
|
||||||
ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(valueArgument.getArgumentName().getReferenceExpression().getReferencedName());
|
ValueParameterDescriptor valueParameterDescriptor = parameterByName.get(valueArgument.getArgumentName().getReferenceExpression().getReferencedName());
|
||||||
if (valueParameterDescriptor == null) {
|
if (valueParameterDescriptor == null) {
|
||||||
// temporaryTrace.getErrorHandler().genericError(nameNode, "Cannot find a parameter with this name");
|
|
||||||
temporaryTrace.report(NAMED_PARAMETER_NOT_FOUND.on(nameReference));
|
temporaryTrace.report(NAMED_PARAMETER_NOT_FOUND.on(nameReference));
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!usedParameters.add(valueParameterDescriptor)) {
|
if (!usedParameters.add(valueParameterDescriptor)) {
|
||||||
// temporaryTrace.getErrorHandler().genericError(nameNode, "An argument is already passed for this parameter");
|
|
||||||
temporaryTrace.report(ARGUMENT_PASSED_TWICE.on(nameReference));
|
temporaryTrace.report(ARGUMENT_PASSED_TWICE.on(nameReference));
|
||||||
}
|
}
|
||||||
temporaryTrace.record(REFERENCE_TARGET, nameReference, valueParameterDescriptor);
|
temporaryTrace.record(REFERENCE_TARGET, nameReference, valueParameterDescriptor);
|
||||||
put(candidateCall, valueParameterDescriptor, valueArgument, varargs);
|
put(candidateCall, valueParameterDescriptor, valueArgument, varargs);
|
||||||
}
|
}
|
||||||
if (somePositioned) {
|
if (somePositioned) {
|
||||||
// temporaryTrace.getErrorHandler().genericError(nameNode, "Mixing named and positioned arguments in not allowed");
|
|
||||||
temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(nameReference));
|
temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(nameReference));
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
@@ -71,7 +68,6 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
|||||||
else {
|
else {
|
||||||
somePositioned = true;
|
somePositioned = true;
|
||||||
if (someNamed) {
|
if (someNamed) {
|
||||||
// temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), "Mixing named and positioned arguments in not allowed");
|
|
||||||
temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(valueArgument.asElement()));
|
temporaryTrace.report(MIXING_NAMED_AND_POSITIONED_ARGUMENTS.on(valueArgument.asElement()));
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
@@ -89,13 +85,11 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
|||||||
usedParameters.add(valueParameterDescriptor);
|
usedParameters.add(valueParameterDescriptor);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), getTooManyArgumentsMessage(candidate));
|
|
||||||
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate));
|
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate));
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// temporaryTrace.getErrorHandler().genericError(valueArgument.asElement().getNode(), getTooManyArgumentsMessage(candidate));
|
|
||||||
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate));
|
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(valueArgument.asElement(), candidate));
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
@@ -108,7 +102,6 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
|||||||
JetExpression possiblyLabeledFunctionLiteral = functionLiteralArguments.get(0);
|
JetExpression possiblyLabeledFunctionLiteral = functionLiteralArguments.get(0);
|
||||||
|
|
||||||
if (valueParameters.isEmpty()) {
|
if (valueParameters.isEmpty()) {
|
||||||
// temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), getTooManyArgumentsMessage(candidate));
|
|
||||||
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate));
|
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate));
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
@@ -124,13 +117,11 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
|||||||
|
|
||||||
ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(valueParameters.size() - 1);
|
ValueParameterDescriptor valueParameterDescriptor = valueParameters.get(valueParameters.size() - 1);
|
||||||
if (valueParameterDescriptor.getVarargElementType() != null) {
|
if (valueParameterDescriptor.getVarargElementType() != null) {
|
||||||
// temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), "Passing value as a vararg is only allowed inside a parenthesized argument list");
|
|
||||||
temporaryTrace.report(VARARG_OUTSIDE_PARENTHESES.on(possiblyLabeledFunctionLiteral));
|
temporaryTrace.report(VARARG_OUTSIDE_PARENTHESES.on(possiblyLabeledFunctionLiteral));
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!usedParameters.add(valueParameterDescriptor)) {
|
if (!usedParameters.add(valueParameterDescriptor)) {
|
||||||
// temporaryTrace.getErrorHandler().genericError(possiblyLabeledFunctionLiteral.getNode(), getTooManyArgumentsMessage(candidate));
|
|
||||||
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate));
|
temporaryTrace.report(TOO_MANY_ARGUMENTS.on(possiblyLabeledFunctionLiteral, candidate));
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
@@ -142,7 +133,6 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
|||||||
|
|
||||||
for (int i = 1; i < functionLiteralArguments.size(); i++) {
|
for (int i = 1; i < functionLiteralArguments.size(); i++) {
|
||||||
JetExpression argument = functionLiteralArguments.get(i);
|
JetExpression argument = functionLiteralArguments.get(i);
|
||||||
// temporaryTrace.getErrorHandler().genericError(argument.getNode(), "Only one function literal is allowed outside a parenthesized argument list");
|
|
||||||
temporaryTrace.report(MANY_FUNCTION_LITERAL_ARGUMENTS.on(argument));
|
temporaryTrace.report(MANY_FUNCTION_LITERAL_ARGUMENTS.on(argument));
|
||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
@@ -176,7 +166,8 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
|||||||
error = true;
|
error = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert candidateCall.getThisObject().exists() == candidateCall.getResultingDescriptor().getExpectedThisObject().exists() : "Shouldn't happen because of TaskPrioritizer: " + candidateCall.getCandidateDescriptor();
|
assert candidateCall.getThisObject().exists() == candidateCall.getResultingDescriptor().getExpectedThisObject().exists() :
|
||||||
|
"Shouldn't happen because of TaskPrioritizer: " + candidateCall.getCandidateDescriptor();
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@@ -196,8 +187,4 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
|||||||
candidateCall.recordValueArgument(valueParameterDescriptor, argument);
|
candidateCall.recordValueArgument(valueParameterDescriptor, argument);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private static <Descriptor extends CallableDescriptor> String getTooManyArgumentsMessage(Descriptor candidate) {
|
|
||||||
// return "Too many arguments for " + DescriptorRenderer.TEXT.render(candidate);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|||||||
+22
@@ -10,6 +10,28 @@ import java.util.Set;
|
|||||||
*/
|
*/
|
||||||
public interface ConstraintResolutionListener {
|
public interface ConstraintResolutionListener {
|
||||||
|
|
||||||
|
public static final ConstraintResolutionListener DO_NOTHING = new ConstraintResolutionListener() {
|
||||||
|
@Override
|
||||||
|
public void constraintsForUnknown(TypeParameterDescriptor typeParameterDescriptor, ConstraintSystemImpl.TypeValue typeValue) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void constraintsForKnownType(JetType type, ConstraintSystemImpl.TypeValue typeValue) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void done(ConstraintSystemSolution solution, Set<TypeParameterDescriptor> typeParameterDescriptors) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(Object message) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(Object message) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
void constraintsForUnknown(TypeParameterDescriptor typeParameterDescriptor, ConstraintSystemImpl.TypeValue typeValue);
|
void constraintsForUnknown(TypeParameterDescriptor typeParameterDescriptor, ConstraintSystemImpl.TypeValue typeValue);
|
||||||
void constraintsForKnownType(JetType type, ConstraintSystemImpl.TypeValue typeValue);
|
void constraintsForKnownType(JetType type, ConstraintSystemImpl.TypeValue typeValue);
|
||||||
void done(ConstraintSystemSolution solution, Set<TypeParameterDescriptor> typeParameterDescriptors);
|
void done(ConstraintSystemSolution solution, Set<TypeParameterDescriptor> typeParameterDescriptors);
|
||||||
|
|||||||
@@ -51,6 +51,11 @@ public interface JetScope {
|
|||||||
@Nullable
|
@Nullable
|
||||||
PropertyDescriptor getPropertyByFieldReference(@NotNull String fieldName);
|
PropertyDescriptor getPropertyByFieldReference(@NotNull String fieldName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All visible descriptors from current scope.
|
||||||
|
*
|
||||||
|
* @return All visible descriptors from current scope.
|
||||||
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
Collection<DeclarationDescriptor> getAllDescriptors();
|
Collection<DeclarationDescriptor> getAllDescriptors();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package org.jetbrains.jet.lang.resolve.scopes;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Nikolay Krasko
|
||||||
|
*/
|
||||||
|
public final class JetScopeUtils {
|
||||||
|
private JetScopeUtils() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get receivers in order of locality, so that the closest (the most local) receiver goes first
|
||||||
|
* A wrapper for {@link JetScope#getImplicitReceiversHierarchy(java.util.List)}
|
||||||
|
*
|
||||||
|
* @param scope Scope for getting receivers hierarchy.
|
||||||
|
* @return receivers hierarchy.
|
||||||
|
*/
|
||||||
|
@NotNull
|
||||||
|
public static Collection<ReceiverDescriptor> getImplicitReceiversHierarchy(@NotNull JetScope scope) {
|
||||||
|
List<ReceiverDescriptor> descriptors = Lists.newArrayList();
|
||||||
|
scope.getImplicitReceiversHierarchy(descriptors);
|
||||||
|
return descriptors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all extension descriptors among visible descriptors for current scope.
|
||||||
|
*
|
||||||
|
* @param scope Scope for query extensions.
|
||||||
|
* @return extension descriptors.
|
||||||
|
*/
|
||||||
|
public static Collection<CallableDescriptor> getAllExtensions(@NotNull JetScope scope) {
|
||||||
|
final Set<CallableDescriptor> result = Sets.newHashSet();
|
||||||
|
|
||||||
|
for (DeclarationDescriptor descriptor : scope.getAllDescriptors()) {
|
||||||
|
if (descriptor instanceof CallableDescriptor) {
|
||||||
|
CallableDescriptor callDescriptor = (CallableDescriptor) descriptor;
|
||||||
|
if (callDescriptor.getReceiverParameter().exists()) {
|
||||||
|
result.add(callDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
-2
@@ -12,9 +12,9 @@ import org.jetbrains.jet.lang.resolve.DescriptorResolver;
|
|||||||
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
|
|
||||||
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver;
|
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
@@ -40,7 +40,8 @@ import java.util.Map;
|
|||||||
@NotNull JetType expectedType,
|
@NotNull JetType expectedType,
|
||||||
@NotNull JetType expectedReturnType,
|
@NotNull JetType expectedReturnType,
|
||||||
boolean namespacesAllowed) {
|
boolean namespacesAllowed) {
|
||||||
return new ExpressionTypingContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, dataFlowInfo, expectedType, expectedReturnType, namespacesAllowed);
|
return new ExpressionTypingContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists,
|
||||||
|
labelResolver, trace, scope, dataFlowInfo, expectedType, expectedReturnType, namespacesAllowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @NotNull
|
// @NotNull
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
package org.jetbrains.jet.plugin.references;
|
package org.jetbrains.jet.plugin.references;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.Collections2;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import com.intellij.codeInsight.lookup.LookupElement;
|
import com.intellij.codeInsight.lookup.LookupElement;
|
||||||
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
import com.intellij.codeInsight.lookup.LookupElementBuilder;
|
||||||
import com.intellij.openapi.util.Iconable;
|
import com.intellij.openapi.util.Iconable;
|
||||||
@@ -14,12 +17,21 @@ import org.jetbrains.jet.lang.descriptors.*;
|
|||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintResolutionListener;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemImpl;
|
||||||
|
import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemSolution;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
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.ReceiverDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
import org.jetbrains.jet.lang.types.Variance;
|
||||||
import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade;
|
import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade;
|
||||||
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
import org.jetbrains.jet.resolve.DescriptorRenderer;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yole
|
* @author yole
|
||||||
@@ -53,9 +65,14 @@ class JetSimpleNameReference extends JetPsiReference {
|
|||||||
JetExpression receiverExpression = qualifiedExpression.getReceiverExpression();
|
JetExpression receiverExpression = qualifiedExpression.getReceiverExpression();
|
||||||
JetFile file = (JetFile) myExpression.getContainingFile();
|
JetFile file = (JetFile) myExpression.getContainingFile();
|
||||||
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file);
|
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file);
|
||||||
|
|
||||||
final JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
|
final JetType expressionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, receiverExpression);
|
||||||
if (expressionType != null) {
|
final JetScope resolutionScope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, receiverExpression);
|
||||||
return collectLookupElements(bindingContext, expressionType.getMemberScope());
|
|
||||||
|
if (expressionType != null && resolutionScope != null) {
|
||||||
|
return collectLookupElements(bindingContext,
|
||||||
|
includeExternalCallableExtensions(expressionType.getMemberScope().getAllDescriptors(),
|
||||||
|
resolutionScope, new ExpressionReceiver(receiverExpression, expressionType)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -63,7 +80,8 @@ class JetSimpleNameReference extends JetPsiReference {
|
|||||||
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file);
|
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile(file);
|
||||||
JetScope resolutionScope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, myExpression);
|
JetScope resolutionScope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, myExpression);
|
||||||
if (resolutionScope != null) {
|
if (resolutionScope != null) {
|
||||||
return collectLookupElements(bindingContext, resolutionScope);
|
return collectLookupElements(bindingContext,
|
||||||
|
excludeNotCallableExtensions(resolutionScope.getAllDescriptors(), resolutionScope));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,9 +94,43 @@ class JetSimpleNameReference extends JetPsiReference {
|
|||||||
return myExpression.getReferencedNameElement().replace(element);
|
return myExpression.getReferencedNameElement().replace(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object[] collectLookupElements(BindingContext bindingContext, JetScope scope) {
|
private Iterable<DeclarationDescriptor> excludeNotCallableExtensions(
|
||||||
|
@NotNull Iterable<DeclarationDescriptor> descriptors, @NotNull final JetScope scope
|
||||||
|
) {
|
||||||
|
final Set<DeclarationDescriptor> descriptorsSet = Sets.newHashSet(descriptors);
|
||||||
|
descriptorsSet.removeAll(
|
||||||
|
Collections2.filter(JetScopeUtils.getAllExtensions(scope), new Predicate<CallableDescriptor>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(CallableDescriptor callableDescriptor) {
|
||||||
|
return !checkReceiverResolution(scope.getImplicitReceiver(), callableDescriptor);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
return descriptorsSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Iterable<DeclarationDescriptor> includeExternalCallableExtensions(
|
||||||
|
@NotNull Iterable<DeclarationDescriptor> descriptors,
|
||||||
|
@NotNull final JetScope externalScope,
|
||||||
|
@NotNull final ReceiverDescriptor receiverDescriptor
|
||||||
|
) {
|
||||||
|
Set<DeclarationDescriptor> descriptorsSet = Sets.newHashSet(descriptors);
|
||||||
|
|
||||||
|
descriptorsSet.addAll(Collections2.filter(JetScopeUtils.getAllExtensions(externalScope),
|
||||||
|
new Predicate<CallableDescriptor>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(CallableDescriptor callableDescriptor) {
|
||||||
|
return checkReceiverResolution(receiverDescriptor, callableDescriptor);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
return descriptorsSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object[] collectLookupElements(BindingContext bindingContext, Iterable<DeclarationDescriptor> descriptors) {
|
||||||
List<LookupElement> result = Lists.newArrayList();
|
List<LookupElement> result = Lists.newArrayList();
|
||||||
for (final DeclarationDescriptor descriptor : scope.getAllDescriptors()) {
|
|
||||||
|
for (final DeclarationDescriptor descriptor : descriptors) {
|
||||||
LookupElementBuilder element = LookupElementBuilder.create(descriptor.getName());
|
LookupElementBuilder element = LookupElementBuilder.create(descriptor.getName());
|
||||||
String typeText = "";
|
String typeText = "";
|
||||||
String tailText = "";
|
String tailText = "";
|
||||||
@@ -117,4 +169,29 @@ class JetSimpleNameReference extends JetPsiReference {
|
|||||||
}
|
}
|
||||||
return result.toArray();
|
return result.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks that receiver declaration could be resolved to call expected receiver.
|
||||||
|
*/
|
||||||
|
private static boolean checkReceiverResolution (
|
||||||
|
@NotNull ReceiverDescriptor expectedReceiver,
|
||||||
|
@NotNull CallableDescriptor receiverArgument
|
||||||
|
) {
|
||||||
|
ConstraintSystem constraintSystem = new ConstraintSystemImpl(ConstraintResolutionListener.DO_NOTHING);
|
||||||
|
for (TypeParameterDescriptor typeParameterDescriptor : receiverArgument.getTypeParameters()) {
|
||||||
|
constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT);
|
||||||
|
}
|
||||||
|
|
||||||
|
ReceiverDescriptor receiverParameter = receiverArgument.getReceiverParameter();
|
||||||
|
if (expectedReceiver.exists() && receiverParameter.exists()) {
|
||||||
|
constraintSystem.addSubtypingConstraint(expectedReceiver.getType(), receiverParameter.getType());
|
||||||
|
}
|
||||||
|
else if (expectedReceiver.exists() || receiverParameter.exists()) {
|
||||||
|
// Only one of receivers exist
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConstraintSystemSolution solution = constraintSystem.solve();
|
||||||
|
return solution.getStatus().isSuccessful();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
namespace Test
|
||||||
|
|
||||||
|
class Some() {
|
||||||
|
fun methodName() {
|
||||||
|
<caret>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Some.first() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: first
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
class Some() {
|
||||||
|
fun methodName() {
|
||||||
|
this.<caret>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Some.first() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: first
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fun Some.first() {
|
||||||
|
}
|
||||||
|
|
||||||
|
class Some() {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Some.second() {
|
||||||
|
<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: first, second
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fun Some.first() {
|
||||||
|
}
|
||||||
|
|
||||||
|
class Some() {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Some.second() {
|
||||||
|
this.<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: first, second
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
class SomeObject<T, U>() {
|
||||||
|
var field : T? = null
|
||||||
|
}
|
||||||
|
|
||||||
|
class A {}
|
||||||
|
class C {}
|
||||||
|
|
||||||
|
fun <T: Comparable<T>, U> SomeObject<T, U>.compareTo(other : SomeObject<T, U>) : Int {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fun some() {
|
||||||
|
val test = SomeObject<A, A>
|
||||||
|
test.<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ABSENT: compareTo
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
fun Some.simpleKotlinExtension() {
|
||||||
|
}
|
||||||
|
|
||||||
|
class Some() {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// ABSENT: simpleKotlinExtension
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
fun <T> java.lang.Iterable<T>.first() : T? {
|
||||||
|
return this.iterator()?.next()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args : Array<String>) {
|
||||||
|
val test = java.util.HashSet<Int>()
|
||||||
|
test.<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: first
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
fun <T> Some<T>.close() {
|
||||||
|
}
|
||||||
|
|
||||||
|
class Some<T>() {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val s = Some<String>()
|
||||||
|
s.<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: close
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
fun Some.simpleKotlinExtension() {
|
||||||
|
}
|
||||||
|
|
||||||
|
class Some() {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val s = Some()
|
||||||
|
s.<caret>
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: simpleKotlinExtension
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package org.jetbrains.jet.completion;
|
||||||
|
|
||||||
|
import junit.framework.Test;
|
||||||
|
import junit.framework.TestSuite;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||||
|
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Nikolay Krasko
|
||||||
|
*/
|
||||||
|
public class ExtensionsCompletionTest extends JetCompletionTestBase {
|
||||||
|
|
||||||
|
// public ExtensionsCompletionTest() {
|
||||||
|
// this("/completion/basic/extensions", "IrrelevantExtension");
|
||||||
|
// // this("/completion/basic/extensions", "InvalidTypeParameters");
|
||||||
|
// // this("/completion/basic/extensions", "ExtensionInExtensionThis");
|
||||||
|
// }
|
||||||
|
|
||||||
|
protected ExtensionsCompletionTest(@NotNull String path, @NotNull String name) {
|
||||||
|
super(path, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static TestSuite suite() {
|
||||||
|
TestSuite suite = new TestSuite();
|
||||||
|
|
||||||
|
JetTestCaseBuilder.appendTestsInDirectory(
|
||||||
|
PluginTestCaseBase.getTestDataPathBase(), "/completion/basic/extensions", false,
|
||||||
|
JetTestCaseBuilder.emptyFilter, new JetTestCaseBuilder.NamedTestFactory() {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) {
|
||||||
|
return new ExtensionsCompletionTest(dataPath, name);
|
||||||
|
}
|
||||||
|
}, suite);
|
||||||
|
|
||||||
|
return suite;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,31 +12,9 @@ import java.io.File;
|
|||||||
* @author Nikolay.Krasko
|
* @author Nikolay.Krasko
|
||||||
*/
|
*/
|
||||||
public class JetBasicCompletionTest extends JetCompletionTestBase {
|
public class JetBasicCompletionTest extends JetCompletionTestBase {
|
||||||
private final String myPath;
|
|
||||||
private final String myName;
|
|
||||||
|
|
||||||
public JetBasicCompletionTest(@NotNull String path, @NotNull String name) {
|
protected JetBasicCompletionTest(@NotNull String path, @NotNull String name) {
|
||||||
myPath = path;
|
super(path, name);
|
||||||
myName = name;
|
|
||||||
|
|
||||||
// Set name explicitly because otherwise there will be "TestCase.fName cannot be null"
|
|
||||||
setName("testCompletionExecute");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testCompletionExecute() throws Exception {
|
|
||||||
doTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getTestDataPath() {
|
|
||||||
return new File(PluginTestCaseBase.getTestDataPathBase(), myPath).getPath() +
|
|
||||||
File.separator;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "test" + myName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
import org.jetbrains.jet.plugin.PluginTestCaseBase;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -20,6 +21,32 @@ import java.util.List;
|
|||||||
* @author Nikolay.Krasko
|
* @author Nikolay.Krasko
|
||||||
*/
|
*/
|
||||||
public abstract class JetCompletionTestBase extends LightCompletionTestCase {
|
public abstract class JetCompletionTestBase extends LightCompletionTestCase {
|
||||||
|
private final String myPath;
|
||||||
|
private final String myName;
|
||||||
|
|
||||||
|
protected JetCompletionTestBase(@NotNull String path, @NotNull String name) {
|
||||||
|
myPath = path;
|
||||||
|
myName = name;
|
||||||
|
|
||||||
|
// Set name explicitly because otherwise there will be "TestCase.fName cannot be null"
|
||||||
|
setName("testCompletionExecute");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testCompletionExecute() throws Exception {
|
||||||
|
doTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getTestDataPath() {
|
||||||
|
return new File(PluginTestCaseBase.getTestDataPathBase(), myPath).getPath() +
|
||||||
|
File.separator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "test" + myName;
|
||||||
|
}
|
||||||
|
|
||||||
private CompletionType type;
|
private CompletionType type;
|
||||||
|
|
||||||
|
|||||||
@@ -15,31 +15,8 @@ import java.io.File;
|
|||||||
*/
|
*/
|
||||||
public class KeywordsCompletionTest extends JetCompletionTestBase {
|
public class KeywordsCompletionTest extends JetCompletionTestBase {
|
||||||
|
|
||||||
private final String myPath;
|
protected KeywordsCompletionTest(@NotNull String path, @NotNull String name) {
|
||||||
private final String myName;
|
super(path, name);
|
||||||
|
|
||||||
public KeywordsCompletionTest(@NotNull String path, @NotNull String name) {
|
|
||||||
myPath = path;
|
|
||||||
myName = name;
|
|
||||||
|
|
||||||
// Set name explicitly because otherwise there will be "TestCase.fName cannot be null"
|
|
||||||
setName("testCompletionExecute");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testCompletionExecute() throws Exception {
|
|
||||||
doTest();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getTestDataPath() {
|
|
||||||
return new File(PluginTestCaseBase.getTestDataPathBase(), myPath).getPath() +
|
|
||||||
File.separator;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return "test" + myName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
Reference in New Issue
Block a user