KT-738 No kotlin type completion in extend class scope
This commit is contained in:
@@ -9,6 +9,8 @@ import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
|
|||||||
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Stores a number of semantic services. Should be created once for each kotlin project.
|
||||||
|
*
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class JetSemanticServices {
|
public class JetSemanticServices {
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Type reference element.
|
||||||
|
* Underlying token is {@link org.jetbrains.jet.JetNodeTypes#TYPE_REFERENCE}
|
||||||
|
*
|
||||||
* @author max
|
* @author max
|
||||||
*/
|
*/
|
||||||
public class JetTypeReference extends JetElement {
|
public class JetTypeReference extends JetElement {
|
||||||
@@ -36,6 +39,15 @@ public class JetTypeReference extends JetElement {
|
|||||||
return findChildByClass(JetTypeElement.class);
|
return findChildByClass(JetTypeElement.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will return not null for type references with internal user type.
|
||||||
|
* There could be other JetTypeReferences, see parsing of in {@link org.jetbrains.jet.lang.parsing.JetParsing}
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
public JetUserType getUserType() {
|
||||||
|
return findChildByClass(JetUserType.class);
|
||||||
|
}
|
||||||
|
|
||||||
public List<JetAnnotationEntry> getAnnotations() {
|
public List<JetAnnotationEntry> getAnnotations() {
|
||||||
List<JetAnnotationEntry> answer = null;
|
List<JetAnnotationEntry> answer = null;
|
||||||
for (JetAnnotation annotation : getAttributeAnnotations()) {
|
for (JetAnnotation annotation : getAttributeAnnotations()) {
|
||||||
|
|||||||
@@ -41,11 +41,15 @@ public interface BindingContext {
|
|||||||
WritableSlice<JetExpression, ResolvedCall<FunctionDescriptor>> INDEXED_LVALUE_SET = Slices.createSimpleSlice();
|
WritableSlice<JetExpression, ResolvedCall<FunctionDescriptor>> INDEXED_LVALUE_SET = Slices.createSimpleSlice();
|
||||||
|
|
||||||
WritableSlice<JetExpression, JetType> AUTOCAST = Slices.createSimpleSlice();
|
WritableSlice<JetExpression, JetType> AUTOCAST = Slices.createSimpleSlice();
|
||||||
|
|
||||||
|
/** A scope where type of expression has been resolved */
|
||||||
WritableSlice<JetExpression, JetScope> RESOLUTION_SCOPE = Slices.createSimpleSlice();
|
WritableSlice<JetExpression, JetScope> RESOLUTION_SCOPE = Slices.createSimpleSlice();
|
||||||
|
|
||||||
WritableSlice<JetExpression, Boolean> VARIABLE_REASSIGNMENT = Slices.createSimpleSetSlice();
|
WritableSlice<JetExpression, Boolean> VARIABLE_REASSIGNMENT = Slices.createSimpleSetSlice();
|
||||||
WritableSlice<ValueParameterDescriptor, Boolean> AUTO_CREATED_IT = Slices.createSimpleSetSlice();
|
WritableSlice<ValueParameterDescriptor, Boolean> AUTO_CREATED_IT = Slices.createSimpleSetSlice();
|
||||||
WritableSlice<JetExpression, DeclarationDescriptor> VARIABLE_ASSIGNMENT = Slices.createSimpleSlice();
|
WritableSlice<JetExpression, DeclarationDescriptor> VARIABLE_ASSIGNMENT = Slices.createSimpleSlice();
|
||||||
|
|
||||||
|
/** Was type of current expression has been already resolved */
|
||||||
WritableSlice<JetExpression, Boolean> PROCESSED = Slices.createSimpleSetSlice();
|
WritableSlice<JetExpression, Boolean> PROCESSED = Slices.createSimpleSetSlice();
|
||||||
WritableSlice<JetElement, Boolean> STATEMENT = Slices.createRemovableSetSlice();
|
WritableSlice<JetElement, Boolean> STATEMENT = Slices.createRemovableSetSlice();
|
||||||
WritableSlice<CallableMemberDescriptor, Boolean> DELEGATED = Slices.createRemovableSetSlice();
|
WritableSlice<CallableMemberDescriptor, Boolean> DELEGATED = Slices.createRemovableSetSlice();
|
||||||
|
|||||||
@@ -49,11 +49,20 @@ public class TypeResolver {
|
|||||||
JetTypeElement typeElement = typeReference.getTypeElement();
|
JetTypeElement typeElement = typeReference.getTypeElement();
|
||||||
JetType type = resolveTypeElement(scope, annotations, typeElement, false);
|
JetType type = resolveTypeElement(scope, annotations, typeElement, false);
|
||||||
trace.record(BindingContext.TYPE, typeReference, type);
|
trace.record(BindingContext.TYPE, typeReference, type);
|
||||||
|
|
||||||
|
final JetUserType jetUserType = typeReference.getUserType();
|
||||||
|
if (jetUserType != null) {
|
||||||
|
final JetSimpleNameExpression referenceExpression = jetUserType.getReferenceExpression();
|
||||||
|
trace.record(BindingContext.RESOLUTION_SCOPE, referenceExpression, scope);
|
||||||
|
}
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private JetType resolveTypeElement(final JetScope scope, final List<AnnotationDescriptor> annotations, JetTypeElement typeElement, final boolean nullable) {
|
private JetType resolveTypeElement(final JetScope scope, final List<AnnotationDescriptor> annotations,
|
||||||
|
JetTypeElement typeElement, final boolean nullable) {
|
||||||
|
|
||||||
final JetType[] result = new JetType[1];
|
final JetType[] result = new JetType[1];
|
||||||
if (typeElement != null) {
|
if (typeElement != null) {
|
||||||
typeElement.accept(new JetVisitorVoid() {
|
typeElement.accept(new JetVisitorVoid() {
|
||||||
@@ -70,6 +79,7 @@ public class TypeResolver {
|
|||||||
resolveTypeProjections(scope, ErrorUtils.createErrorType("No type").getConstructor(), type.getTypeArguments());
|
resolveTypeProjections(scope, ErrorUtils.createErrorType("No type").getConstructor(), type.getTypeArguments());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classifierDescriptor instanceof TypeParameterDescriptor) {
|
if (classifierDescriptor instanceof TypeParameterDescriptor) {
|
||||||
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) classifierDescriptor;
|
TypeParameterDescriptor typeParameterDescriptor = (TypeParameterDescriptor) classifierDescriptor;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
open class MySecondClass() {
|
||||||
|
}
|
||||||
|
|
||||||
|
open class MyFirstClass<T> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class A() : My<caret> {
|
||||||
|
public fun test() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: MySecondClass, MyFirstClass
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
open class MyClass() {
|
||||||
|
}
|
||||||
|
|
||||||
|
class A() : My<caret> {
|
||||||
|
public fun test() {
|
||||||
|
val a : MyC<caret>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// EXIST: MyClass
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package org.jetbrains.jet.completion;
|
||||||
|
|
||||||
|
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 JetBasicCompletion extends JetCompletionTestBase {
|
||||||
|
private final String myPath;
|
||||||
|
private final String myName;
|
||||||
|
|
||||||
|
public JetBasicCompletion(@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() {
|
||||||
|
doTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getTestDataPath() {
|
||||||
|
return new File(PluginTestCaseBase.getTestDataPathBase(), myPath).getPath() +
|
||||||
|
File.separator;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "test" + myName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static TestSuite suite() {
|
||||||
|
TestSuite suite = new TestSuite();
|
||||||
|
|
||||||
|
JetTestCaseBuilder.appendTestsInDirectory(
|
||||||
|
PluginTestCaseBase.getTestDataPathBase(), "/completion/basic/", false,
|
||||||
|
JetTestCaseBuilder.emptyFilter, new JetTestCaseBuilder.NamedTestFactory() {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public junit.framework.Test createTest(@NotNull String dataPath, @NotNull String name) {
|
||||||
|
return new JetBasicCompletion(dataPath, name);
|
||||||
|
}
|
||||||
|
}, suite);
|
||||||
|
|
||||||
|
return suite;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,10 +22,10 @@ public class KeywordsCompletionTest extends JetCompletionTestBase {
|
|||||||
myName = name;
|
myName = name;
|
||||||
|
|
||||||
// Set name explicitly because otherwise there will be "TestCase.fName cannot be null"
|
// Set name explicitly because otherwise there will be "TestCase.fName cannot be null"
|
||||||
setName("testComletionExecute");
|
setName("testCompletionExecute");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testComletionExecute() {
|
public void testCompletionExecute() {
|
||||||
doTest();
|
doTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user