Unresolved references highlighted in the editor. Resolve test added
This commit is contained in:
@@ -1,10 +1,19 @@
|
|||||||
package org.jetbrains.jet.lang;
|
package org.jetbrains.jet.lang;
|
||||||
|
|
||||||
|
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class ErrorHandler {
|
public class ErrorHandler {
|
||||||
public static final ErrorHandler DO_NOTHING = new ErrorHandler();
|
public static final ErrorHandler DO_NOTHING = new ErrorHandler();
|
||||||
public static final ErrorHandler THROW_EXCEPTION = new ErrorHandler();
|
public static final ErrorHandler THROW_EXCEPTION = new ErrorHandler() {
|
||||||
|
@Override
|
||||||
|
public void unresolvedReference(JetReferenceExpression referenceExpression) {
|
||||||
|
throw new IllegalStateException("Unresolved reference: " + referenceExpression.getReferencedName());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public void unresolvedReference(JetReferenceExpression referenceExpression) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,4 +44,8 @@ public class JetSemanticServices {
|
|||||||
public JetTypeInferrer getTypeInferrer(BindingTrace trace) {
|
public JetTypeInferrer getTypeInferrer(BindingTrace trace) {
|
||||||
return new JetTypeInferrer(trace, this);
|
return new JetTypeInferrer(trace, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ErrorHandler getErrorHandler() {
|
||||||
|
return errorHandler;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ public class JetPsiChecker implements Annotator {
|
|||||||
if (element instanceof JetFile) {
|
if (element instanceof JetFile) {
|
||||||
JetFile file = (JetFile) element;
|
JetFile file = (JetFile) element;
|
||||||
JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(element.getProject(), new ErrorHandler() {
|
JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(element.getProject(), new ErrorHandler() {
|
||||||
|
@Override
|
||||||
|
public void unresolvedReference(JetReferenceExpression referenceExpression) {
|
||||||
|
holder.createErrorAnnotation(referenceExpression, "Unresolved");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
final BindingContext bindingContext = new TopDownAnalyzer(semanticServices).process(semanticServices.getStandardLibrary().getLibraryScope(), file.getRootNamespace().getDeclarations());
|
final BindingContext bindingContext = new TopDownAnalyzer(semanticServices).process(semanticServices.getStandardLibrary().getLibraryScope(), file.getRootNamespace().getDeclarations());
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public class ClassDescriptorResolver {
|
|||||||
|
|
||||||
public ClassDescriptorResolver(JetSemanticServices semanticServices, BindingTrace trace) {
|
public ClassDescriptorResolver(JetSemanticServices semanticServices, BindingTrace trace) {
|
||||||
this.semanticServices = semanticServices;
|
this.semanticServices = semanticServices;
|
||||||
this.typeResolver = new TypeResolver(trace);
|
this.typeResolver = new TypeResolver(trace, semanticServices.getErrorHandler());
|
||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,19 +11,19 @@ public interface JetScope {
|
|||||||
JetScope EMPTY = new JetScopeImpl() {};
|
JetScope EMPTY = new JetScopeImpl() {};
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
ClassDescriptor getClass(String name);
|
ClassDescriptor getClass(@NotNull String name);
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
PropertyDescriptor getProperty(String name);
|
PropertyDescriptor getProperty(@NotNull String name);
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
ExtensionDescriptor getExtension(String name);
|
ExtensionDescriptor getExtension(@NotNull String name);
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
NamespaceDescriptor getNamespace(String name);
|
NamespaceDescriptor getNamespace(@NotNull String name);
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
TypeParameterDescriptor getTypeParameter(String name);
|
TypeParameterDescriptor getTypeParameter(@NotNull String name);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
Type getThisType();
|
Type getThisType();
|
||||||
|
|||||||
@@ -26,27 +26,27 @@ public class JetScopeAdapter implements JetScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeParameterDescriptor getTypeParameter(String name) {
|
public TypeParameterDescriptor getTypeParameter(@NotNull String name) {
|
||||||
return scope.getTypeParameter(name);
|
return scope.getTypeParameter(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NamespaceDescriptor getNamespace(String name) {
|
public NamespaceDescriptor getNamespace(@NotNull String name) {
|
||||||
return scope.getNamespace(name);
|
return scope.getNamespace(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassDescriptor getClass(String name) {
|
public ClassDescriptor getClass(@NotNull String name) {
|
||||||
return scope.getClass(name);
|
return scope.getClass(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PropertyDescriptor getProperty(String name) {
|
public PropertyDescriptor getProperty(@NotNull String name) {
|
||||||
return scope.getProperty(name);
|
return scope.getProperty(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExtensionDescriptor getExtension(String name) {
|
public ExtensionDescriptor getExtension(@NotNull String name) {
|
||||||
return scope.getExtension(name);
|
return scope.getExtension(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,27 +8,27 @@ import org.jetbrains.jet.lang.types.*;
|
|||||||
*/
|
*/
|
||||||
public abstract class JetScopeImpl implements JetScope {
|
public abstract class JetScopeImpl implements JetScope {
|
||||||
@Override
|
@Override
|
||||||
public ClassDescriptor getClass(String name) {
|
public ClassDescriptor getClass(@NotNull String name) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PropertyDescriptor getProperty(String name) {
|
public PropertyDescriptor getProperty(@NotNull String name) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExtensionDescriptor getExtension(String name) {
|
public ExtensionDescriptor getExtension(@NotNull String name) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NamespaceDescriptor getNamespace(String name) {
|
public NamespaceDescriptor getNamespace(@NotNull String name) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeParameterDescriptor getTypeParameter(String name) {
|
public TypeParameterDescriptor getTypeParameter(@NotNull String name) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,28 +17,28 @@ public class ScopeWithReceiver extends JetScopeImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassDescriptor getClass(String name) {
|
public ClassDescriptor getClass(@NotNull String name) {
|
||||||
return super.getClass(name); // TODO
|
return super.getClass(name); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PropertyDescriptor getProperty(String name) {
|
public PropertyDescriptor getProperty(@NotNull String name) {
|
||||||
return receiverTypeScope.getProperty(name);
|
return receiverTypeScope.getProperty(name);
|
||||||
// TODO : extension properties
|
// TODO : extension properties
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExtensionDescriptor getExtension(String name) {
|
public ExtensionDescriptor getExtension(@NotNull String name) {
|
||||||
return super.getExtension(name); // TODO
|
return super.getExtension(name); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NamespaceDescriptor getNamespace(String name) {
|
public NamespaceDescriptor getNamespace(@NotNull String name) {
|
||||||
return outerScope.getNamespace(name);
|
return outerScope.getNamespace(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeParameterDescriptor getTypeParameter(String name) {
|
public TypeParameterDescriptor getTypeParameter(@NotNull String name) {
|
||||||
return outerScope.getTypeParameter(name);
|
return outerScope.getTypeParameter(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class SubstitutingScope implements JetScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PropertyDescriptor getProperty(String name) {
|
public PropertyDescriptor getProperty(@NotNull String name) {
|
||||||
PropertyDescriptor property = workerScope.getProperty(name);
|
PropertyDescriptor property = workerScope.getProperty(name);
|
||||||
if (property == null || substitutionContext.isEmpty()) {
|
if (property == null || substitutionContext.isEmpty()) {
|
||||||
return property;
|
return property;
|
||||||
@@ -28,7 +28,7 @@ public class SubstitutingScope implements JetScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassDescriptor getClass(String name) {
|
public ClassDescriptor getClass(@NotNull String name) {
|
||||||
ClassDescriptor descriptor = workerScope.getClass(name);
|
ClassDescriptor descriptor = workerScope.getClass(name);
|
||||||
if (descriptor == null) {
|
if (descriptor == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -37,17 +37,17 @@ public class SubstitutingScope implements JetScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExtensionDescriptor getExtension(String name) {
|
public ExtensionDescriptor getExtension(@NotNull String name) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NamespaceDescriptor getNamespace(String name) {
|
public NamespaceDescriptor getNamespace(@NotNull String name) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeParameterDescriptor getTypeParameter(String name) {
|
public TypeParameterDescriptor getTypeParameter(@NotNull String name) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.jetbrains.jet.lang.resolve;
|
|||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.jet.lang.ErrorHandler;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
@@ -16,9 +17,11 @@ import java.util.Set;
|
|||||||
public class TypeResolver {
|
public class TypeResolver {
|
||||||
|
|
||||||
private final BindingTrace trace;
|
private final BindingTrace trace;
|
||||||
|
private final ErrorHandler errorHandler;
|
||||||
|
|
||||||
public TypeResolver(BindingTrace trace) {
|
public TypeResolver(BindingTrace trace, ErrorHandler errorHandler) {
|
||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
|
this.errorHandler = errorHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -52,6 +55,7 @@ public class TypeResolver {
|
|||||||
else if (type.getTypeArguments().isEmpty()) {
|
else if (type.getTypeArguments().isEmpty()) {
|
||||||
TypeParameterDescriptor typeParameterDescriptor = scope.getTypeParameter(type.getReferencedName());
|
TypeParameterDescriptor typeParameterDescriptor = scope.getTypeParameter(type.getReferencedName());
|
||||||
if (typeParameterDescriptor != null) {
|
if (typeParameterDescriptor != null) {
|
||||||
|
trace.recordReferenceResolution(type.getReferenceExpression(), typeParameterDescriptor);
|
||||||
result[0] = new TypeImpl(
|
result[0] = new TypeImpl(
|
||||||
attributes,
|
attributes,
|
||||||
typeParameterDescriptor.getTypeConstructor(),
|
typeParameterDescriptor.getTypeConstructor(),
|
||||||
@@ -60,8 +64,13 @@ public class TypeResolver {
|
|||||||
// TODO : joint domain
|
// TODO : joint domain
|
||||||
JetStandardClasses.STUB
|
JetStandardClasses.STUB
|
||||||
);
|
);
|
||||||
|
} else {
|
||||||
|
errorHandler.unresolvedReference(type.getReferenceExpression());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
errorHandler.unresolvedReference(type.getReferenceExpression());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class WritableScope extends JetScopeAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PropertyDescriptor getProperty(String name) {
|
public PropertyDescriptor getProperty(@NotNull String name) {
|
||||||
@NotNull
|
@NotNull
|
||||||
Map<String, PropertyDescriptor> propertyDescriptors = getPropertyDescriptors();
|
Map<String, PropertyDescriptor> propertyDescriptors = getPropertyDescriptors();
|
||||||
PropertyDescriptor propertyDescriptor = propertyDescriptors.get(name);
|
PropertyDescriptor propertyDescriptor = propertyDescriptors.get(name);
|
||||||
@@ -102,7 +102,7 @@ public class WritableScope extends JetScopeAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeParameterDescriptor getTypeParameter(String name) {
|
public TypeParameterDescriptor getTypeParameter(@NotNull String name) {
|
||||||
TypeParameterDescriptor typeParameterDescriptor = getTypeParameterDescriptors().get(name);
|
TypeParameterDescriptor typeParameterDescriptor = getTypeParameterDescriptors().get(name);
|
||||||
if (typeParameterDescriptor != null) {
|
if (typeParameterDescriptor != null) {
|
||||||
return typeParameterDescriptor;
|
return typeParameterDescriptor;
|
||||||
@@ -130,7 +130,7 @@ public class WritableScope extends JetScopeAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassDescriptor getClass(String name) {
|
public ClassDescriptor getClass(@NotNull String name) {
|
||||||
ClassDescriptor classDescriptor = getClassDescriptors().get(name);
|
ClassDescriptor classDescriptor = getClassDescriptors().get(name);
|
||||||
if (classDescriptor != null) {
|
if (classDescriptor != null) {
|
||||||
return classDescriptor;
|
return classDescriptor;
|
||||||
@@ -148,12 +148,12 @@ public class WritableScope extends JetScopeAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NamespaceDescriptor getNamespace(String name) {
|
public NamespaceDescriptor getNamespace(@NotNull String name) {
|
||||||
return super.getNamespace(name); // TODO
|
return super.getNamespace(name); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExtensionDescriptor getExtension(String name) {
|
public ExtensionDescriptor getExtension(@NotNull String name) {
|
||||||
return super.getExtension(name); // TODO
|
return super.getExtension(name); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,27 +12,27 @@ import java.util.List;
|
|||||||
public class ErrorType {
|
public class ErrorType {
|
||||||
private static final JetScope ERROR_SCOPE = new JetScope() {
|
private static final JetScope ERROR_SCOPE = new JetScope() {
|
||||||
@Override
|
@Override
|
||||||
public ClassDescriptor getClass(String name) {
|
public ClassDescriptor getClass(@NotNull String name) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PropertyDescriptor getProperty(String name) {
|
public PropertyDescriptor getProperty(@NotNull String name) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExtensionDescriptor getExtension(String name) {
|
public ExtensionDescriptor getExtension(@NotNull String name) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NamespaceDescriptor getNamespace(String name) {
|
public NamespaceDescriptor getNamespace(@NotNull String name) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TypeParameterDescriptor getTypeParameter(String name) {
|
public TypeParameterDescriptor getTypeParameter(@NotNull String name) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class JetTypeInferrer {
|
|||||||
public JetTypeInferrer(BindingTrace trace, JetSemanticServices semanticServices) {
|
public JetTypeInferrer(BindingTrace trace, JetSemanticServices semanticServices) {
|
||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
this.semanticServices = semanticServices;
|
this.semanticServices = semanticServices;
|
||||||
this.typeResolver = new TypeResolver(trace);
|
this.typeResolver = new TypeResolver(trace, semanticServices.getErrorHandler());
|
||||||
this.classDescriptorResolver = new ClassDescriptorResolver(semanticServices, trace);
|
this.classDescriptorResolver = new ClassDescriptorResolver(semanticServices, trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,9 +50,11 @@ public class JetTypeInferrer {
|
|||||||
// TODO : other members
|
// TODO : other members
|
||||||
// TODO : type substitutions???
|
// TODO : type substitutions???
|
||||||
PropertyDescriptor property = scope.getProperty(expression.getReferencedName());
|
PropertyDescriptor property = scope.getProperty(expression.getReferencedName());
|
||||||
trace.recordReferenceResolution(expression, property);
|
|
||||||
if (property != null) {
|
if (property != null) {
|
||||||
|
trace.recordReferenceResolution(expression, property);
|
||||||
result[0] = property.getType();
|
result[0] = property.getType();
|
||||||
|
} else {
|
||||||
|
semanticServices.getErrorHandler().unresolvedReference(expression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,6 +402,8 @@ public class JetTypeInferrer {
|
|||||||
FunctionDescriptor descriptor = result[0].getFunctionDescriptorForNamedArguments(typeArguments, valueArgumentTypes, functionLiteralArgumentType);
|
FunctionDescriptor descriptor = result[0].getFunctionDescriptorForNamedArguments(typeArguments, valueArgumentTypes, functionLiteralArgumentType);
|
||||||
if (descriptor != null) {
|
if (descriptor != null) {
|
||||||
trace.recordReferenceResolution(reference[0], descriptor);
|
trace.recordReferenceResolution(reference[0], descriptor);
|
||||||
|
} else {
|
||||||
|
semanticServices.getErrorHandler().unresolvedReference(reference[0]);
|
||||||
}
|
}
|
||||||
return descriptor;
|
return descriptor;
|
||||||
}
|
}
|
||||||
@@ -409,6 +413,8 @@ public class JetTypeInferrer {
|
|||||||
FunctionDescriptor descriptor = result[0].getFunctionDescriptorForPositionedArguments(typeArguments, positionedValueArgumentTypes);
|
FunctionDescriptor descriptor = result[0].getFunctionDescriptorForPositionedArguments(typeArguments, positionedValueArgumentTypes);
|
||||||
if (descriptor != null) {
|
if (descriptor != null) {
|
||||||
trace.recordReferenceResolution(reference[0], descriptor);
|
trace.recordReferenceResolution(reference[0], descriptor);
|
||||||
|
} else {
|
||||||
|
semanticServices.getErrorHandler().unresolvedReference(reference[0]);
|
||||||
}
|
}
|
||||||
return descriptor;
|
return descriptor;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,2 +1 @@
|
|||||||
val foo = 1
|
val x : Int
|
||||||
|
|
||||||
@@ -1,17 +1,19 @@
|
|||||||
class A {
|
~A~class A {
|
||||||
class B {
|
~B~class B {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun foo(a : Int) = a
|
~foo~fun foo(~foo.a~a : `std::Char`Char) = `foo.a`a
|
||||||
fun fooB() = foo(1)
|
~fooB~fun fooB() = `foo`foo('1')
|
||||||
fun foo() : Int = 1.plus(1)
|
~foo.1~fun foo() : Int = 1.`std::Int.plus(Int)`plus(1)
|
||||||
fun foo1() : B = new B()
|
~foo1~fun foo1() : `B`B = new `B`B()
|
||||||
val a : Int
|
~A.a~val a : `std::Int`Int
|
||||||
}
|
}
|
||||||
|
|
||||||
class C : A {
|
~C~class C : `A`A {
|
||||||
class B : C {
|
~C.B~class B : `C`C {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val x : `C.B`B
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,109 +0,0 @@
|
|||||||
package org.jetbrains.jet.checkers;
|
|
||||||
|
|
||||||
import com.intellij.codeHighlighting.Pass;
|
|
||||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
|
|
||||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings;
|
|
||||||
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
|
|
||||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
|
||||||
import com.intellij.injected.editor.EditorWindow;
|
|
||||||
import com.intellij.openapi.command.CommandProcessor;
|
|
||||||
import com.intellij.openapi.editor.Editor;
|
|
||||||
import com.intellij.openapi.vfs.VirtualFileFilter;
|
|
||||||
import com.intellij.psi.PsiDocumentManager;
|
|
||||||
import com.intellij.psi.PsiFile;
|
|
||||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
|
|
||||||
import com.intellij.testFramework.ExpectedHighlightingData;
|
|
||||||
import com.intellij.testFramework.FileTreeAccessFilter;
|
|
||||||
import com.intellij.testFramework.LightCodeInsightTestCase;
|
|
||||||
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
|
|
||||||
import com.intellij.util.ArrayUtil;
|
|
||||||
import org.jetbrains.annotations.NonNls;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author abreslav
|
|
||||||
*/
|
|
||||||
public abstract class ExtensibleHighlightingTestCase extends LightCodeInsightTestCase {
|
|
||||||
private final FileTreeAccessFilter myJavaFilesFilter = new FileTreeAccessFilter();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void setUp() throws Exception {
|
|
||||||
super.setUp();
|
|
||||||
((DaemonCodeAnalyzerImpl) DaemonCodeAnalyzer.getInstance(getProject())).prepareForTest(true);
|
|
||||||
DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void tearDown() throws Exception {
|
|
||||||
((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject())).cleanupAfterTest(true); // has to cleanup by hand since light project does not get disposed any time soon
|
|
||||||
super.tearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void runTest() throws Throwable {
|
|
||||||
final Throwable[] throwable = {null};
|
|
||||||
CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
doRunTest();
|
|
||||||
}
|
|
||||||
catch (Throwable t) {
|
|
||||||
throwable[0] = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, "", null);
|
|
||||||
if (throwable[0] != null) {
|
|
||||||
throw throwable[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doTest(@NonNls String filePath, boolean checkWarnings, boolean checkInfos) throws Exception {
|
|
||||||
configureByFile(filePath);
|
|
||||||
doTestConfiguredFile(checkWarnings, checkInfos);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void doTestConfiguredFile(boolean checkWarnings, boolean checkInfos) {
|
|
||||||
getJavaFacade().setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
|
|
||||||
|
|
||||||
ExpectedHighlightingData expectedData = new ExpectedHighlightingData(getEditor().getDocument(),checkWarnings, checkInfos) {
|
|
||||||
@Override
|
|
||||||
protected void initAdditionalHighlightingTypes() {
|
|
||||||
// this.this.put();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
|
|
||||||
getFile().getText(); //to load text
|
|
||||||
myJavaFilesFilter.allowTreeAccessForFile(getVFile());
|
|
||||||
getJavaFacade().setAssertOnFileLoadingFilter(myJavaFilesFilter); // check repository work
|
|
||||||
|
|
||||||
Collection<HighlightInfo> infos = doHighlighting();
|
|
||||||
|
|
||||||
getJavaFacade().setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
|
|
||||||
|
|
||||||
expectedData.checkResult(infos, getEditor().getDocument().getText());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
protected List<HighlightInfo> doHighlighting() {
|
|
||||||
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
|
|
||||||
|
|
||||||
int[] toIgnore = doFolding() ? ArrayUtil.EMPTY_INT_ARRAY : new int[]{Pass.UPDATE_FOLDING};
|
|
||||||
Editor editor = getEditor();
|
|
||||||
PsiFile file = getFile();
|
|
||||||
if (editor instanceof EditorWindow) {
|
|
||||||
editor = ((EditorWindow)editor).getDelegate();
|
|
||||||
file = InjectedLanguageUtil.getTopLevelFile(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
return CodeInsightTestFixtureImpl.instantiateAndRun(file, editor, toIgnore, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean doFolding() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,150 @@
|
|||||||
|
package org.jetbrains.jet.resolve;
|
||||||
|
|
||||||
|
import com.intellij.openapi.command.WriteCommandAction;
|
||||||
|
import com.intellij.openapi.editor.Document;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import org.jetbrains.jet.lang.ErrorHandler;
|
||||||
|
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetTypeReference;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
|
||||||
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.assertNotNull;
|
||||||
|
import static junit.framework.Assert.assertSame;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class ExpectedResolveData {
|
||||||
|
|
||||||
|
private final Map<String, Integer> declarationToPosition = new HashMap<String, Integer>();
|
||||||
|
private final Map<Integer, String> positionToReference = new HashMap<Integer, String>();
|
||||||
|
|
||||||
|
public ExpectedResolveData(final Document document) {
|
||||||
|
new WriteCommandAction.Simple(null) {
|
||||||
|
public void run() {
|
||||||
|
extractData(document);
|
||||||
|
}
|
||||||
|
}.execute().throwException();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void extractData(Document document) {
|
||||||
|
String text = document.getText();
|
||||||
|
|
||||||
|
Pattern pattern = Pattern.compile("(~[^~]+~)|(`[^`]+`)");
|
||||||
|
while (true) {
|
||||||
|
Matcher matcher = pattern.matcher(text);
|
||||||
|
if (!matcher.find()) break;
|
||||||
|
|
||||||
|
String group = matcher.group();
|
||||||
|
String name = group.substring(1, group.length() - 1);
|
||||||
|
if (group.startsWith("~")) {
|
||||||
|
if (declarationToPosition.put(name, matcher.start()) != null) {
|
||||||
|
throw new IllegalArgumentException("Redeclaration: " + name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (group.startsWith("`")) {
|
||||||
|
positionToReference.put(matcher.start(), name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IllegalStateException();
|
||||||
|
}
|
||||||
|
|
||||||
|
document.replaceString(matcher.start(), matcher.end(), "");
|
||||||
|
text = document.getText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkResult(JetFile file) {
|
||||||
|
JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(file.getProject(), ErrorHandler.THROW_EXCEPTION);
|
||||||
|
JetStandardLibrary lib = semanticServices.getStandardLibrary();
|
||||||
|
Map<String, DeclarationDescriptor> nameToDescriptor = new HashMap<String, DeclarationDescriptor>();
|
||||||
|
nameToDescriptor.put("std::Int.plus(Int)", standardFunction(lib.getInt(), "plus", lib.getIntType()));
|
||||||
|
|
||||||
|
TopDownAnalyzer topDownAnalyzer = new TopDownAnalyzer(semanticServices);
|
||||||
|
BindingContext bindingContext = topDownAnalyzer.process(lib.getLibraryScope(), file.getRootNamespace().getDeclarations());
|
||||||
|
|
||||||
|
Map<String, JetDeclaration> nameToDeclaration = new HashMap<String, JetDeclaration>();
|
||||||
|
|
||||||
|
Map<JetDeclaration, String> declarationToName = new HashMap<JetDeclaration, String>();
|
||||||
|
for (Map.Entry<String, Integer> entry : declarationToPosition.entrySet()) {
|
||||||
|
String name = entry.getKey();
|
||||||
|
Integer position = entry.getValue();
|
||||||
|
PsiElement element = file.findElementAt(position);
|
||||||
|
|
||||||
|
JetDeclaration ancestorOfType = getAncestorOfType(JetDeclaration.class, element);
|
||||||
|
nameToDeclaration.put(name, ancestorOfType);
|
||||||
|
declarationToName.put(ancestorOfType, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<Integer, String> entry : positionToReference.entrySet()) {
|
||||||
|
Integer position = entry.getKey();
|
||||||
|
String name = entry.getValue();
|
||||||
|
PsiElement element = file.findElementAt(position);
|
||||||
|
|
||||||
|
JetDeclaration expected = nameToDeclaration.get(name);
|
||||||
|
|
||||||
|
JetReferenceExpression reference = getAncestorOfType(JetReferenceExpression.class, element);
|
||||||
|
if (expected == null && name.startsWith("std::")) {
|
||||||
|
DeclarationDescriptor expectedDescriptor = nameToDescriptor.get(name);
|
||||||
|
JetTypeReference typeReference = getAncestorOfType(JetTypeReference.class, element);
|
||||||
|
if (expectedDescriptor != null) {
|
||||||
|
DeclarationDescriptor actual = bindingContext.resolveReferenceExpression(reference);
|
||||||
|
assertSame(expectedDescriptor, actual);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Type actualType = bindingContext.resolveTypeReference(typeReference);
|
||||||
|
assertNotNull("Type " + name + " not resolved for reference " + name, actualType);
|
||||||
|
ClassDescriptor expectedClass = lib.getLibraryScope().getClass(name.substring(5));
|
||||||
|
assertNotNull("Expected class not found: " + name);
|
||||||
|
assertSame("Type resolution mismatch: ", expectedClass.getTypeConstructor(), actualType.getConstructor());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
assert expected != null : "No declaration for " + name;
|
||||||
|
|
||||||
|
PsiElement actual = bindingContext.resolveToDeclarationPsiElement(reference);
|
||||||
|
String actualName = null;
|
||||||
|
if (actual != null) {
|
||||||
|
actualName = declarationToName.get(actual);
|
||||||
|
if (actualName == null) {
|
||||||
|
actualName = actual.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertSame(
|
||||||
|
"Reference `" + name + "`" + reference.getReferencedName() + " at " + reference.getTextOffset() + " is resolved into " + actualName + ".",
|
||||||
|
expected, actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeclarationDescriptor standardFunction(ClassDescriptor classDescriptor, String name, Type parameterType) {
|
||||||
|
FunctionGroup functionGroup = classDescriptor.getMemberScope(Collections.<TypeProjection>emptyList()).getFunctionGroup(name);
|
||||||
|
Collection<FunctionDescriptor> functions = functionGroup.getPossiblyApplicableFunctions(Collections.<Type>emptyList(), Collections.singletonList(parameterType));
|
||||||
|
for (FunctionDescriptor function : functions) {
|
||||||
|
if (function.getUnsubstitutedValueParameters().get(0).getType().equals(parameterType)) {
|
||||||
|
return function;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Not found: std::" + classDescriptor.getName() + "." + name + "(" + parameterType + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T getAncestorOfType(Class<T> type, PsiElement element) {
|
||||||
|
while (element != null && !type.isInstance(element)) {
|
||||||
|
element = element.getParent();
|
||||||
|
}
|
||||||
|
@SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"})
|
||||||
|
T result = (T) element;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,104 @@
|
|||||||
|
package org.jetbrains.jet.resolve;
|
||||||
|
|
||||||
|
import com.intellij.codeHighlighting.Pass;
|
||||||
|
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
|
||||||
|
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings;
|
||||||
|
import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
|
||||||
|
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||||
|
import com.intellij.injected.editor.EditorWindow;
|
||||||
|
import com.intellij.openapi.command.CommandProcessor;
|
||||||
|
import com.intellij.openapi.editor.Editor;
|
||||||
|
import com.intellij.openapi.vfs.VirtualFileFilter;
|
||||||
|
import com.intellij.psi.PsiDocumentManager;
|
||||||
|
import com.intellij.psi.PsiFile;
|
||||||
|
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
|
||||||
|
import com.intellij.testFramework.FileTreeAccessFilter;
|
||||||
|
import com.intellij.testFramework.LightCodeInsightTestCase;
|
||||||
|
import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
|
||||||
|
import com.intellij.util.ArrayUtil;
|
||||||
|
import org.jetbrains.annotations.NonNls;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public abstract class ExtensibleResolveTestCase extends LightCodeInsightTestCase {
|
||||||
|
private final FileTreeAccessFilter myJavaFilesFilter = new FileTreeAccessFilter();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
((DaemonCodeAnalyzerImpl) DaemonCodeAnalyzer.getInstance(getProject())).prepareForTest(true);
|
||||||
|
DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void tearDown() throws Exception {
|
||||||
|
((DaemonCodeAnalyzerImpl) DaemonCodeAnalyzer.getInstance(getProject())).cleanupAfterTest(true); // has to cleanup by hand since light project does not get disposed any time soon
|
||||||
|
super.tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void runTest() throws Throwable {
|
||||||
|
final Throwable[] throwable = {null};
|
||||||
|
CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
doRunTest();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
throwable[0] = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, "", null);
|
||||||
|
if (throwable[0] != null) {
|
||||||
|
throw throwable[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void doTest(@NonNls String filePath, boolean checkWarnings, boolean checkInfos) throws Exception {
|
||||||
|
configureByFile(filePath);
|
||||||
|
doTestConfiguredFile(checkWarnings, checkInfos);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void doTestConfiguredFile(boolean checkWarnings, boolean checkInfos) {
|
||||||
|
getJavaFacade().setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
|
||||||
|
|
||||||
|
// ExpectedHighlightingData expectedData = new ExpectedHighlightingData(getEditor().getDocument(), checkWarnings, checkInfos);
|
||||||
|
ExpectedResolveData expectedData = new ExpectedResolveData(getEditor().getDocument());
|
||||||
|
|
||||||
|
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
|
||||||
|
getFile().getText(); //to load text
|
||||||
|
myJavaFilesFilter.allowTreeAccessForFile(getVFile());
|
||||||
|
getJavaFacade().setAssertOnFileLoadingFilter(myJavaFilesFilter); // check repository work
|
||||||
|
|
||||||
|
Collection<HighlightInfo> infos = doHighlighting();
|
||||||
|
|
||||||
|
getJavaFacade().setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
|
||||||
|
|
||||||
|
expectedData.checkResult((JetFile) getFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
protected List<HighlightInfo> doHighlighting() {
|
||||||
|
PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
|
||||||
|
|
||||||
|
int[] toIgnore = doFolding() ? ArrayUtil.EMPTY_INT_ARRAY : new int[]{Pass.UPDATE_FOLDING};
|
||||||
|
Editor editor = getEditor();
|
||||||
|
PsiFile file = getFile();
|
||||||
|
if (editor instanceof EditorWindow) {
|
||||||
|
editor = ((EditorWindow) editor).getDelegate();
|
||||||
|
file = InjectedLanguageUtil.getTopLevelFile(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CodeInsightTestFixtureImpl.instantiateAndRun(file, editor, toIgnore, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean doFolding() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,25 +1,21 @@
|
|||||||
package org.jetbrains.jet.resolve;
|
package org.jetbrains.jet.resolve;
|
||||||
|
|
||||||
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
|
|
||||||
import com.intellij.openapi.application.PathManager;
|
import com.intellij.openapi.application.PathManager;
|
||||||
import com.intellij.openapi.util.io.FileUtil;
|
import org.jetbrains.jet.lang.resolve.JetScope;
|
||||||
import org.jetbrains.jet.lang.ErrorHandler;
|
import org.jetbrains.jet.lang.resolve.OverloadDomain;
|
||||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
import org.jetbrains.jet.lang.resolve.OverloadResolver;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.types.FunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.resolve.*;
|
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.Type;
|
||||||
import org.jetbrains.jet.parsing.JetParsingTest;
|
import org.jetbrains.jet.parsing.JetParsingTest;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileReader;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class JetResolveTest extends LightDaemonAnalyzerTestCase {
|
public class JetResolveTest extends ExtensibleResolveTestCase {
|
||||||
private JetStandardLibrary library;
|
private JetStandardLibrary library;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -38,81 +34,82 @@ public class JetResolveTest extends LightDaemonAnalyzerTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testBasic() throws Exception {
|
public void testBasic() throws Exception {
|
||||||
JetFile jetFile = JetChangeUtil.createFile(getProject(), FileUtil.loadTextAndClose(new FileReader(getTestDataPath() + "/resolve/Basic.jet")));
|
doTest("/resolve/Basic.jet", true, true);
|
||||||
List<JetDeclaration> declarations = jetFile.getRootNamespace().getDeclarations();
|
// JetFile jetFile = JetChangeUtil.createFile(getProject(), FileUtil.loadTextAndClose(new FileReader(getTestDataPath() + "/resolve/Basic.jet")));
|
||||||
BindingContext bindingContext = new TopDownAnalyzer(JetSemanticServices.createSemanticServices(library, ErrorHandler.THROW_EXCEPTION)).process(library.getLibraryScope(), declarations);
|
// List<JetDeclaration> declarations = jetFile.getRootNamespace().getDeclarations();
|
||||||
|
// BindingContext bindingContext = new TopDownAnalyzer(JetSemanticServices.createSemanticServices(library, ErrorHandler.THROW_EXCEPTION)).process(library.getLibraryScope(), declarations);
|
||||||
JetClass classADecl = (JetClass) declarations.get(0);
|
//
|
||||||
ClassDescriptor classA = bindingContext.getClassDescriptor(classADecl);
|
// JetClass classADecl = (JetClass) declarations.get(0);
|
||||||
assertNotNull(classA);
|
// ClassDescriptor classA = bindingContext.getClassDescriptor(classADecl);
|
||||||
|
// assertNotNull(classA);
|
||||||
JetScope membersOfA = classA.getMemberScope(Collections.<TypeProjection>emptyList());
|
//
|
||||||
ClassDescriptor classB = membersOfA.getClass("B");
|
// JetScope membersOfA = classA.getMemberScope(Collections.<TypeProjection>emptyList());
|
||||||
assertNotNull(classB);
|
// ClassDescriptor classB = membersOfA.getClass("B");
|
||||||
|
// assertNotNull(classB);
|
||||||
{
|
//
|
||||||
FunctionGroup fooFG = membersOfA.getFunctionGroup("foo");
|
// {
|
||||||
assertFalse(fooFG.isEmpty());
|
// FunctionGroup fooFG = membersOfA.getFunctionGroup("foo");
|
||||||
}
|
// assertFalse(fooFG.isEmpty());
|
||||||
|
// }
|
||||||
assertReturnType(membersOfA, "foo", library.getIntType());
|
//
|
||||||
assertReturnType(membersOfA, "foo1", new TypeImpl(classB));
|
// assertReturnType(membersOfA, "foo", library.getIntType());
|
||||||
assertReturnType(membersOfA, "fooB", library.getIntType());
|
// assertReturnType(membersOfA, "foo1", new TypeImpl(classB));
|
||||||
|
// assertReturnType(membersOfA, "fooB", library.getIntType());
|
||||||
JetFunction fooDecl = (JetFunction) classADecl.getDeclarations().get(1);
|
//
|
||||||
Type expressionType = bindingContext.getExpressionType(fooDecl.getBodyExpression());
|
// JetFunction fooDecl = (JetFunction) classADecl.getDeclarations().get(1);
|
||||||
assertEquals(library.getIntType(), expressionType);
|
// Type expressionType = bindingContext.getExpressionType(fooDecl.getBodyExpression());
|
||||||
|
// assertEquals(library.getIntType(), expressionType);
|
||||||
{
|
//
|
||||||
DeclarationDescriptor resolve = bindingContext.resolveReferenceExpression((JetReferenceExpression) fooDecl.getBodyExpression());
|
// {
|
||||||
assertSame(bindingContext.getFunctionDescriptor(fooDecl).getUnsubstitutedValueParameters().get(0), resolve);
|
// DeclarationDescriptor resolve = bindingContext.resolveReferenceExpression((JetReferenceExpression) fooDecl.getBodyExpression());
|
||||||
}
|
// assertSame(bindingContext.getFunctionDescriptor(fooDecl).getUnsubstitutedValueParameters().get(0), resolve);
|
||||||
|
// }
|
||||||
{
|
//
|
||||||
JetFunction fooBDecl = (JetFunction) classADecl.getDeclarations().get(2);
|
// {
|
||||||
JetCallExpression fooBBody = (JetCallExpression) fooBDecl.getBodyExpression();
|
// JetFunction fooBDecl = (JetFunction) classADecl.getDeclarations().get(2);
|
||||||
JetReferenceExpression refToFoo = (JetReferenceExpression) fooBBody.getCalleeExpression();
|
// JetCallExpression fooBBody = (JetCallExpression) fooBDecl.getBodyExpression();
|
||||||
FunctionDescriptor mustBeFoo = (FunctionDescriptor) bindingContext.resolveReferenceExpression(refToFoo);
|
// JetReferenceExpression refToFoo = (JetReferenceExpression) fooBBody.getCalleeExpression();
|
||||||
assertSame(bindingContext.getFunctionDescriptor(fooDecl), FunctionDescriptorUtil.getOriginal(mustBeFoo));
|
// FunctionDescriptor mustBeFoo = (FunctionDescriptor) bindingContext.resolveReferenceExpression(refToFoo);
|
||||||
}
|
// assertSame(bindingContext.getFunctionDescriptor(fooDecl), FunctionDescriptorUtil.getOriginal(mustBeFoo));
|
||||||
|
// }
|
||||||
{
|
//
|
||||||
JetFunction fooIntDecl = (JetFunction) classADecl.getDeclarations().get(3);
|
// {
|
||||||
JetCallExpression fooIntBody = (JetCallExpression) fooIntDecl.getBodyExpression();
|
// JetFunction fooIntDecl = (JetFunction) classADecl.getDeclarations().get(3);
|
||||||
JetDotQualifiedExpression qualifiedPlus = (JetDotQualifiedExpression) fooIntBody.getCalleeExpression();
|
// JetCallExpression fooIntBody = (JetCallExpression) fooIntDecl.getBodyExpression();
|
||||||
JetReferenceExpression refToPlus = (JetReferenceExpression) qualifiedPlus.getSelectorExpression();
|
// JetDotQualifiedExpression qualifiedPlus = (JetDotQualifiedExpression) fooIntBody.getCalleeExpression();
|
||||||
FunctionDescriptor mustBePlus = (FunctionDescriptor) bindingContext.resolveReferenceExpression(refToPlus);
|
// JetReferenceExpression refToPlus = (JetReferenceExpression) qualifiedPlus.getSelectorExpression();
|
||||||
FunctionGroup plusGroup = library.getInt().getMemberScope(Collections.<TypeProjection>emptyList()).getFunctionGroup("plus");
|
// FunctionDescriptor mustBePlus = (FunctionDescriptor) bindingContext.resolveReferenceExpression(refToPlus);
|
||||||
Collection<FunctionDescriptor> pluses = plusGroup.getPossiblyApplicableFunctions(Collections.<Type>emptyList(), Collections.singletonList(library.getIntType()));
|
// FunctionGroup plusGroup = library.getInt().getMemberScope(Collections.<TypeProjection>emptyList()).getFunctionGroup("plus");
|
||||||
FunctionDescriptor intPlus = null;
|
// Collection<FunctionDescriptor> pluses = plusGroup.getPossiblyApplicableFunctions(Collections.<Type>emptyList(), Collections.singletonList(library.getIntType()));
|
||||||
for (FunctionDescriptor plus : pluses) {
|
// FunctionDescriptor intPlus = null;
|
||||||
intPlus = plus;
|
// for (FunctionDescriptor plus : pluses) {
|
||||||
}
|
// intPlus = plus;
|
||||||
assertSame(intPlus, FunctionDescriptorUtil.getOriginal(mustBePlus));
|
// }
|
||||||
}
|
// assertSame(intPlus, FunctionDescriptorUtil.getOriginal(mustBePlus));
|
||||||
|
// }
|
||||||
{
|
//
|
||||||
PropertyDescriptor a = classA.getMemberScope(Collections.<TypeProjection>emptyList()).getProperty("a");
|
// {
|
||||||
JetProperty aDecl = (JetProperty) classADecl.getDeclarations().get(5);
|
// PropertyDescriptor a = classA.getMemberScope(Collections.<TypeProjection>emptyList()).getProperty("a");
|
||||||
PropertyDescriptor mustBeA = bindingContext.getPropertyDescriptor(aDecl);
|
// JetProperty aDecl = (JetProperty) classADecl.getDeclarations().get(5);
|
||||||
assertSame(a, mustBeA);
|
// PropertyDescriptor mustBeA = bindingContext.getPropertyDescriptor(aDecl);
|
||||||
|
// assertSame(a, mustBeA);
|
||||||
JetTypeReference propertyTypeRef = aDecl.getPropertyTypeRef();
|
//
|
||||||
Type type = bindingContext.resolveTypeReference(propertyTypeRef);
|
// JetTypeReference propertyTypeRef = aDecl.getPropertyTypeRef();
|
||||||
assertEquals(library.getIntType(), type);
|
// Type type = bindingContext.resolveTypeReference(propertyTypeRef);
|
||||||
}
|
// assertEquals(library.getIntType(), type);
|
||||||
|
// }
|
||||||
JetClass classCDecl = (JetClass) declarations.get(1);
|
//
|
||||||
ClassDescriptor classC = bindingContext.getClassDescriptor(classCDecl);
|
// JetClass classCDecl = (JetClass) declarations.get(1);
|
||||||
assertNotNull(classC);
|
// ClassDescriptor classC = bindingContext.getClassDescriptor(classCDecl);
|
||||||
assertEquals(1, classC.getTypeConstructor().getSupertypes().size());
|
// assertNotNull(classC);
|
||||||
assertEquals(classA.getTypeConstructor(), classC.getTypeConstructor().getSupertypes().iterator().next().getConstructor());
|
// assertEquals(1, classC.getTypeConstructor().getSupertypes().size());
|
||||||
|
// assertEquals(classA.getTypeConstructor(), classC.getTypeConstructor().getSupertypes().iterator().next().getConstructor());
|
||||||
JetScope cScope = classC.getMemberScope(Collections.<TypeProjection>emptyList());
|
//
|
||||||
ClassDescriptor classC_B = cScope.getClass("B");
|
// JetScope cScope = classC.getMemberScope(Collections.<TypeProjection>emptyList());
|
||||||
assertNotNull(classC_B);
|
// ClassDescriptor classC_B = cScope.getClass("B");
|
||||||
assertNotSame(classC_B, classB);
|
// assertNotNull(classC_B);
|
||||||
assertEquals(classC.getTypeConstructor(), classC_B.getTypeConstructor().getSupertypes().iterator().next().getConstructor());
|
// assertNotSame(classC_B, classB);
|
||||||
|
// assertEquals(classC.getTypeConstructor(), classC_B.getTypeConstructor().getSupertypes().iterator().next().getConstructor());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertReturnType(JetScope membersOfA, String foo, Type returnType) {
|
private void assertReturnType(JetScope membersOfA, String foo, Type returnType) {
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
library = new JetStandardLibrary(getProject());
|
library = new JetStandardLibrary(getProject());
|
||||||
semanticServices = JetSemanticServices.createSemanticServices(library, ErrorHandler.THROW_EXCEPTION);
|
semanticServices = JetSemanticServices.createSemanticServices(library, ErrorHandler.DO_NOTHING);
|
||||||
classDefinitions = new ClassDefinitions();
|
classDefinitions = new ClassDefinitions();
|
||||||
classDescriptorResolver = semanticServices.getClassDescriptorResolver(BindingTrace.DUMMY);
|
classDescriptorResolver = semanticServices.getClassDescriptorResolver(BindingTrace.DUMMY);
|
||||||
}
|
}
|
||||||
@@ -489,7 +489,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Type makeType(JetScope scope, String typeStr) {
|
private static Type makeType(JetScope scope, String typeStr) {
|
||||||
return new TypeResolver(BindingTrace.DUMMY).resolveType(scope, JetChangeUtil.createType(getProject(), typeStr));
|
return new TypeResolver(BindingTrace.DUMMY, ErrorHandler.THROW_EXCEPTION).resolveType(scope, JetChangeUtil.createType(getProject(), typeStr));
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ClassDefinitions {
|
private class ClassDefinitions {
|
||||||
@@ -522,7 +522,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
|||||||
|
|
||||||
public JetScope BASIC_SCOPE = new JetScopeAdapter(library.getLibraryScope()) {
|
public JetScope BASIC_SCOPE = new JetScopeAdapter(library.getLibraryScope()) {
|
||||||
@Override
|
@Override
|
||||||
public ClassDescriptor getClass(String name) {
|
public ClassDescriptor getClass(@NotNull String name) {
|
||||||
if (CLASSES.isEmpty()) {
|
if (CLASSES.isEmpty()) {
|
||||||
for (String classDeclaration : CLASS_DECLARATIONS) {
|
for (String classDeclaration : CLASS_DECLARATIONS) {
|
||||||
JetClass classElement = JetChangeUtil.createClass(getProject(), classDeclaration);
|
JetClass classElement = JetChangeUtil.createClass(getProject(), classDeclaration);
|
||||||
|
|||||||
Reference in New Issue
Block a user