Typechecker tests added
This commit is contained in:
@@ -3,10 +3,10 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~foo~fun foo(~foo.a~a : `std::Char`Char) = `foo.a`a
|
~foo~fun foo(~foo.a~a : `std::Char`Char) = `foo.a`a`:std::Char`
|
||||||
~fooB~fun fooB() = `foo`foo('1')
|
~fooB~fun fooB() = `foo`foo('1')`:std::Char`
|
||||||
~foo.1~fun foo() : Int = 1.`std::Int.plus(Int)`plus(1)
|
~foo.1~fun foo() : Int = 1.`std::Int.plus(Int)`plus(1)`:std::Int`
|
||||||
~foo1~fun foo1() : `B`B = new `B`B()
|
~foo1~fun foo1() : `B`B = new `B`B()`:B`
|
||||||
~A.a~val a : `std::Int`Int
|
~A.a~val a : `std::Int`Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,10 +5,7 @@ import com.intellij.openapi.editor.Document;
|
|||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.jet.lang.ErrorHandler;
|
import org.jetbrains.jet.lang.ErrorHandler;
|
||||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
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.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
|
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
@@ -30,6 +27,7 @@ public class ExpectedResolveData {
|
|||||||
|
|
||||||
private final Map<String, Integer> declarationToPosition = new HashMap<String, Integer>();
|
private final Map<String, Integer> declarationToPosition = new HashMap<String, Integer>();
|
||||||
private final Map<Integer, String> positionToReference = new HashMap<Integer, String>();
|
private final Map<Integer, String> positionToReference = new HashMap<Integer, String>();
|
||||||
|
private final Map<Integer, String> positionToType = new HashMap<Integer, String>();
|
||||||
|
|
||||||
public ExpectedResolveData(final Document document) {
|
public ExpectedResolveData(final Document document) {
|
||||||
new WriteCommandAction.Simple(null) {
|
new WriteCommandAction.Simple(null) {
|
||||||
@@ -49,19 +47,25 @@ public class ExpectedResolveData {
|
|||||||
|
|
||||||
String group = matcher.group();
|
String group = matcher.group();
|
||||||
String name = group.substring(1, group.length() - 1);
|
String name = group.substring(1, group.length() - 1);
|
||||||
|
int start = matcher.start();
|
||||||
if (group.startsWith("~")) {
|
if (group.startsWith("~")) {
|
||||||
if (declarationToPosition.put(name, matcher.start()) != null) {
|
if (declarationToPosition.put(name, start) != null) {
|
||||||
throw new IllegalArgumentException("Redeclaration: " + name);
|
throw new IllegalArgumentException("Redeclaration: " + name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (group.startsWith("`")) {
|
else if (group.startsWith("`")) {
|
||||||
positionToReference.put(matcher.start(), name);
|
if (name.startsWith(":")) {
|
||||||
|
positionToType.put(start - 1, name.substring(1));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
positionToReference.put(start, name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
|
|
||||||
document.replaceString(matcher.start(), matcher.end(), "");
|
document.replaceString(start, matcher.end(), "");
|
||||||
text = document.getText();
|
text = document.getText();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,6 +130,33 @@ public class ExpectedResolveData {
|
|||||||
"Reference `" + name + "`" + reference.getReferencedName() + " at " + reference.getTextOffset() + " is resolved into " + actualName + ".",
|
"Reference `" + name + "`" + reference.getReferencedName() + " at " + reference.getTextOffset() + " is resolved into " + actualName + ".",
|
||||||
expected, actual);
|
expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<Integer, String> entry : positionToType.entrySet()) {
|
||||||
|
Integer position = entry.getKey();
|
||||||
|
String typeName = entry.getValue();
|
||||||
|
|
||||||
|
PsiElement element = file.findElementAt(position);
|
||||||
|
JetExpression expression = getAncestorOfType(JetExpression.class, element);
|
||||||
|
|
||||||
|
Type expressionType = bindingContext.getExpressionType(expression);
|
||||||
|
TypeConstructor expectedTypeConstructor;
|
||||||
|
if (typeName.startsWith("std::")) {
|
||||||
|
ClassDescriptor expectedClass = lib.getLibraryScope().getClass(typeName.substring(5));
|
||||||
|
assertNotNull("Expected class not found: " + typeName);
|
||||||
|
expectedTypeConstructor = expectedClass.getTypeConstructor();
|
||||||
|
} else {
|
||||||
|
Integer declarationPosition = declarationToPosition.get(typeName);
|
||||||
|
assertNotNull("Undeclared: " + typeName, declarationPosition);
|
||||||
|
PsiElement declElement = file.findElementAt(declarationPosition);
|
||||||
|
assertNotNull(declarationPosition);
|
||||||
|
JetDeclaration declaration = getAncestorOfType(JetDeclaration.class, declElement);
|
||||||
|
assertNotNull(declaration);
|
||||||
|
ClassDescriptor classDescriptor = bindingContext.getClassDescriptor((JetClass) declaration);
|
||||||
|
expectedTypeConstructor = classDescriptor.getTypeConstructor();
|
||||||
|
}
|
||||||
|
|
||||||
|
assertSame("At " + position + ": ", expectedTypeConstructor, expressionType.getConstructor());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private DeclarationDescriptor standardFunction(ClassDescriptor classDescriptor, String name, Type parameterType) {
|
private DeclarationDescriptor standardFunction(ClassDescriptor classDescriptor, String name, Type parameterType) {
|
||||||
|
|||||||
@@ -1,27 +1,18 @@
|
|||||||
package org.jetbrains.jet.resolve;
|
package org.jetbrains.jet.resolve;
|
||||||
|
|
||||||
import com.intellij.openapi.application.PathManager;
|
import com.intellij.openapi.application.PathManager;
|
||||||
import org.jetbrains.jet.lang.resolve.JetScope;
|
|
||||||
import org.jetbrains.jet.lang.resolve.OverloadDomain;
|
|
||||||
import org.jetbrains.jet.lang.resolve.OverloadResolver;
|
|
||||||
import org.jetbrains.jet.lang.types.FunctionDescriptor;
|
|
||||||
import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
|
||||||
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.util.Collections;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class JetResolveTest extends ExtensibleResolveTestCase {
|
public class JetResolveTest extends ExtensibleResolveTestCase {
|
||||||
private JetStandardLibrary library;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
library = new JetStandardLibrary(getProject());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -35,88 +26,6 @@ public class JetResolveTest extends ExtensibleResolveTestCase {
|
|||||||
|
|
||||||
public void testBasic() throws Exception {
|
public void testBasic() throws Exception {
|
||||||
doTest("/resolve/Basic.jet", true, true);
|
doTest("/resolve/Basic.jet", true, true);
|
||||||
// JetFile jetFile = JetChangeUtil.createFile(getProject(), FileUtil.loadTextAndClose(new FileReader(getTestDataPath() + "/resolve/Basic.jet")));
|
|
||||||
// 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);
|
|
||||||
// assertNotNull(classA);
|
|
||||||
//
|
|
||||||
// JetScope membersOfA = classA.getMemberScope(Collections.<TypeProjection>emptyList());
|
|
||||||
// ClassDescriptor classB = membersOfA.getClass("B");
|
|
||||||
// assertNotNull(classB);
|
|
||||||
//
|
|
||||||
// {
|
|
||||||
// FunctionGroup fooFG = membersOfA.getFunctionGroup("foo");
|
|
||||||
// assertFalse(fooFG.isEmpty());
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// assertReturnType(membersOfA, "foo", 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());
|
|
||||||
// assertEquals(library.getIntType(), expressionType);
|
|
||||||
//
|
|
||||||
// {
|
|
||||||
// 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();
|
|
||||||
// JetReferenceExpression refToFoo = (JetReferenceExpression) fooBBody.getCalleeExpression();
|
|
||||||
// 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();
|
|
||||||
// JetDotQualifiedExpression qualifiedPlus = (JetDotQualifiedExpression) fooIntBody.getCalleeExpression();
|
|
||||||
// JetReferenceExpression refToPlus = (JetReferenceExpression) qualifiedPlus.getSelectorExpression();
|
|
||||||
// FunctionDescriptor mustBePlus = (FunctionDescriptor) bindingContext.resolveReferenceExpression(refToPlus);
|
|
||||||
// FunctionGroup plusGroup = library.getInt().getMemberScope(Collections.<TypeProjection>emptyList()).getFunctionGroup("plus");
|
|
||||||
// Collection<FunctionDescriptor> pluses = plusGroup.getPossiblyApplicableFunctions(Collections.<Type>emptyList(), Collections.singletonList(library.getIntType()));
|
|
||||||
// FunctionDescriptor intPlus = null;
|
|
||||||
// for (FunctionDescriptor plus : pluses) {
|
|
||||||
// intPlus = plus;
|
|
||||||
// }
|
|
||||||
// assertSame(intPlus, FunctionDescriptorUtil.getOriginal(mustBePlus));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// {
|
|
||||||
// PropertyDescriptor a = classA.getMemberScope(Collections.<TypeProjection>emptyList()).getProperty("a");
|
|
||||||
// JetProperty aDecl = (JetProperty) classADecl.getDeclarations().get(5);
|
|
||||||
// PropertyDescriptor mustBeA = bindingContext.getPropertyDescriptor(aDecl);
|
|
||||||
// assertSame(a, mustBeA);
|
|
||||||
//
|
|
||||||
// JetTypeReference propertyTypeRef = aDecl.getPropertyTypeRef();
|
|
||||||
// Type type = bindingContext.resolveTypeReference(propertyTypeRef);
|
|
||||||
// assertEquals(library.getIntType(), type);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// JetClass classCDecl = (JetClass) declarations.get(1);
|
|
||||||
// ClassDescriptor classC = bindingContext.getClassDescriptor(classCDecl);
|
|
||||||
// assertNotNull(classC);
|
|
||||||
// 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");
|
|
||||||
// assertNotNull(classC_B);
|
|
||||||
// assertNotSame(classC_B, classB);
|
|
||||||
// assertEquals(classC.getTypeConstructor(), classC_B.getTypeConstructor().getSupertypes().iterator().next().getConstructor());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertReturnType(JetScope membersOfA, String foo, Type returnType) {
|
|
||||||
OverloadDomain overloadsForFoo = OverloadResolver.INSTANCE.getOverloadDomain(null, membersOfA, foo);
|
|
||||||
FunctionDescriptor descriptorForFoo = overloadsForFoo.getFunctionDescriptorForPositionedArguments(Collections.<Type>emptyList(), Collections.<Type>emptyList());
|
|
||||||
assertNotNull(descriptorForFoo);
|
|
||||||
Type fooType = descriptorForFoo.getUnsubstitutedReturnType();
|
|
||||||
assertEquals(returnType, fooType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user