Working on the type checker
This commit is contained in:
+11
-1
@@ -10,9 +10,19 @@ Foo<Bar<X>, T, Object> // user type
|
||||
*/
|
||||
|
||||
type
|
||||
: attributes (selfType | functionType | userType | tupleType)
|
||||
: attributes typeDescriptor
|
||||
|
||||
typeDescriptor
|
||||
: selfType
|
||||
: functionType
|
||||
: userType
|
||||
: tupleType
|
||||
: nullableType
|
||||
;
|
||||
|
||||
nullableType
|
||||
: typeDescriptor "?"
|
||||
|
||||
selfType
|
||||
: "This"
|
||||
;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.jetbrains.jet.lang.annotations;
|
||||
|
||||
import com.intellij.lang.annotation.AnnotationHolder;
|
||||
import com.intellij.lang.annotation.AnnotationSession;
|
||||
import com.intellij.lang.annotation.Annotator;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -21,7 +20,7 @@ public class JetPsiChecker implements Annotator {
|
||||
// holder.createErrorAnnotation(property.getNameIdentifier(), "Specify either type or value");
|
||||
JetFile file = (JetFile) element;
|
||||
String path = file.getProject().getBaseDir().getPath();
|
||||
System.out.println("Path: " + path);
|
||||
println("Path: " + path);
|
||||
JetNamespace rootNamespace = file.getRootNamespace();
|
||||
List<JetDeclaration> declarations = rootNamespace.getDeclarations();
|
||||
|
||||
@@ -54,10 +53,10 @@ public class JetPsiChecker implements Annotator {
|
||||
}
|
||||
|
||||
private void print(Object o) {
|
||||
System.out.print(o);
|
||||
// System.out.print(o);
|
||||
}
|
||||
|
||||
private void println(Object o) {
|
||||
System.out.println(o);
|
||||
// System.out.println(o);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,6 +141,11 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
* ;
|
||||
*/
|
||||
public void parseExpression() {
|
||||
// TODO: better recovery for expressions
|
||||
if (atSet(RPAR, RBRACE, RBRACKET, GT)) {
|
||||
error("Expecting an expression");
|
||||
return;
|
||||
}
|
||||
parseBinaryExpression(Precedence.ASSIGNMENT);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import com.intellij.lang.PsiBuilder;
|
||||
* @author abreslav
|
||||
*/
|
||||
public interface SemanticWhitespaceAwarePsiBuilder extends PsiBuilder {
|
||||
// TODO: comments go to wrong place when an empty element is created
|
||||
// TODO: comments go to wrong place when an empty element is created, see IElementType.isLeftBound()
|
||||
|
||||
boolean newlineBeforeCurrentToken();
|
||||
void disableNewlines();
|
||||
|
||||
@@ -18,6 +18,11 @@ public class JetChangeUtil {
|
||||
return property.getInitializer();
|
||||
}
|
||||
|
||||
public static JetTypeReference createType(Project project, String type) {
|
||||
JetProperty property = createProperty(project, "val x : " + type);
|
||||
return property.getPropertyTypeRef();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JetFile createFile(Project project, String text) {
|
||||
return (JetFile) PsiFileFactory.getInstance(project).createFileFromText("dummy.jet", JetFileType.INSTANCE, text, LocalTimeCounter.currentTime(), true);
|
||||
|
||||
@@ -48,7 +48,7 @@ public class JetElement extends ASTWrapperPsiElement {
|
||||
}
|
||||
}
|
||||
|
||||
public void accept(JetVisitor visitor) {
|
||||
public void accept(@NotNull JetVisitor visitor) {
|
||||
visitor.visitJetElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,20 @@ public class JetTypeReference extends JetElement {
|
||||
return findChildrenByType(JetNodeTypes.ATTRIBUTE_ANNOTATION);
|
||||
}
|
||||
|
||||
public JetTypeElement getTypeElement() {
|
||||
return findChildByClass(JetTypeElement.class);
|
||||
}
|
||||
|
||||
public JetTypeArgumentList getTypeArgumentList() {
|
||||
return findChildByClass(JetTypeArgumentList.class);
|
||||
}
|
||||
|
||||
public List<JetTypeReference> getTypeArguments() {
|
||||
// TODO: empty elements in PSI
|
||||
JetTypeArgumentList typeArgumentList = getTypeArgumentList();
|
||||
return typeArgumentList == null ? Collections.<JetTypeReference>emptyList() : typeArgumentList.getArguments();
|
||||
}
|
||||
|
||||
public List<JetAttribute> getAttributes() {
|
||||
List<JetAttribute> answer = null;
|
||||
for (JetAttributeAnnotation annotation : getAttributeAnnotations()) {
|
||||
|
||||
@@ -62,4 +62,9 @@ public class JetTypeChecker {
|
||||
public boolean isConvertibleTo(JetExpression expression, Type type) {
|
||||
return false; //To change body of created methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
public boolean isSubtypeOf(Type subtype, Type supertype) {
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class NamespaceDescriptor {
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package org.jetbrains.jet.lang.types;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class ThisType extends TypeImpl {
|
||||
public ThisType(List<Annotation> annotations, ClassDescriptor thisClass) {
|
||||
super(annotations, thisClass.getTypeConstructor(), toArguments(thisClass.getTypeConstructor().getParameters()));
|
||||
}
|
||||
|
||||
private static List<TypeProjection> toArguments(List<TypeParameterDescriptor> parameters) {
|
||||
List<TypeProjection> result = new ArrayList<TypeProjection>();
|
||||
for (TypeParameterDescriptor parameter : parameters) {
|
||||
result.add(new TypeProjection(new TypeVariable(Collections.<Annotation>emptyList(), parameter)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<MemberDescriptor> getMembers() {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,10 @@ public class TypeProjection {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public TypeProjection(Type type) {
|
||||
this(Variance.INVARIANT, type);
|
||||
}
|
||||
|
||||
public Variance getProjection() {
|
||||
return projection;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
type Comparison<in T> = {(T, T) : Int}
|
||||
|
||||
fun naturalOrder<in T : IComparable<T>>(a : T, b : T) : Int = a.compareTo(b)
|
||||
fun naturalOrder<in T : Comparable<T>>(a : T, b : T) : Int = a.compareTo(b)
|
||||
|
||||
fun castingNaturalOrder(a : Object, b : Object) : Int = (a as Comparable<Object>).compareTo(b as Comparable<Object>)
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
interface class IComparable<in T> {
|
||||
virtual class IComparable<in T> {
|
||||
fun compareTo(other : T) : Int
|
||||
}
|
||||
+2
-1
@@ -1,7 +1,8 @@
|
||||
package org.jetbrains.jet.parsing;
|
||||
package org.jetbrains.jet.checkers;
|
||||
|
||||
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import org.jetbrains.jet.parsing.JetParsingTest;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
+65
-4
@@ -1,15 +1,16 @@
|
||||
package org.jetbrains.jet.parsing;
|
||||
package org.jetbrains.jet.types;
|
||||
|
||||
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
|
||||
import com.intellij.openapi.application.PathManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.jet.lang.psi.JetChangeUtil;
|
||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.types.JetStandardTypes;
|
||||
import org.jetbrains.jet.lang.types.Type;
|
||||
import org.jetbrains.jet.lang.types.JetTypeChecker;
|
||||
import org.jetbrains.jet.lang.types.Type;
|
||||
import org.jetbrains.jet.parsing.JetParsingTest;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
@@ -55,6 +56,66 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
||||
assertType("()", JetStandardTypes.getUnit());
|
||||
}
|
||||
|
||||
public void testSubtyping() throws Exception {
|
||||
assertSubtype("Boolean", "Boolean");
|
||||
assertSubtype("Byte", "Byte");
|
||||
assertSubtype("Char", "Char");
|
||||
assertSubtype("Short", "Short");
|
||||
assertSubtype("Int", "Int");
|
||||
assertSubtype("Long", "Long");
|
||||
assertSubtype("Float", "Float");
|
||||
assertSubtype("Double", "Double");
|
||||
assertSubtype("Unit", "Unit");
|
||||
|
||||
assertNotSubtype("Boolean", "Byte");
|
||||
assertNotSubtype("Byte", "Short");
|
||||
assertNotSubtype("Char", "Int");
|
||||
assertNotSubtype("Short", "Int");
|
||||
assertNotSubtype("Int", "Long");
|
||||
assertNotSubtype("Long", "Double");
|
||||
assertNotSubtype("Float", "Double");
|
||||
assertNotSubtype("Double", "Int");
|
||||
assertNotSubtype("Unit", "Unit");
|
||||
|
||||
assertSubtype("(Boolean)", "(Boolean)");
|
||||
assertSubtype("(Byte)", "(Byte)");
|
||||
assertSubtype("(Char)", "(Char)");
|
||||
assertSubtype("(Short)", "(Short)");
|
||||
assertSubtype("(Int)", "(Int)");
|
||||
assertSubtype("(Long)", "(Long)");
|
||||
assertSubtype("(Float)", "(Float)");
|
||||
assertSubtype("(Double)", "(Double)");
|
||||
assertSubtype("(Unit)", "(Unit)");
|
||||
|
||||
}
|
||||
|
||||
private void assertSubtype(String type1, String type2) {
|
||||
assertSubtypingRelation(type1, type2, true);
|
||||
}
|
||||
|
||||
private void assertNotSubtype(String type1, String type2) {
|
||||
assertSubtypingRelation(type1, type2, false);
|
||||
}
|
||||
|
||||
private void assertSubtypingRelation(String type1, String type2, boolean expected) {
|
||||
Type typeNode1 = toType(JetChangeUtil.createType(getProject(), type1));
|
||||
Type typeNode2 = toType(JetChangeUtil.createType(getProject(), type2));
|
||||
boolean result = new JetTypeChecker().isSubtypeOf(
|
||||
typeNode1,
|
||||
typeNode2);
|
||||
assertTrue(typeNode1 + " is not a subtype of " + typeNode2, result == expected);
|
||||
}
|
||||
|
||||
private Type toType(JetTypeReference typeNode) {
|
||||
List<JetAttribute> attributes = typeNode.getAttributes();
|
||||
JetTypeElement typeElement = typeNode.getTypeElement();
|
||||
List<JetTypeReference> typeArguments = typeNode.getTypeArguments();
|
||||
|
||||
typeElement.accept(new JetVisitor());
|
||||
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
|
||||
public void testImplicitConversions() throws Exception {
|
||||
assertConvertibleTo("1", JetStandardTypes.getByte());
|
||||
}
|
||||
Reference in New Issue
Block a user