Working on the type checker

This commit is contained in:
Andrey Breslav
2011-01-20 19:28:36 +03:00
parent 04aa370fa6
commit 113a066e48
15 changed files with 153 additions and 14 deletions
+11 -1
View File
@@ -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
}
@@ -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;
@@ -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());
}