Working on the type model
This commit is contained in:
@@ -1,10 +1,13 @@
|
|||||||
package org.jetbrains.jet.lang.annotations;
|
package org.jetbrains.jet.lang.annotations;
|
||||||
|
|
||||||
import com.intellij.lang.annotation.AnnotationHolder;
|
import com.intellij.lang.annotation.AnnotationHolder;
|
||||||
|
import com.intellij.lang.annotation.AnnotationSession;
|
||||||
import com.intellij.lang.annotation.Annotator;
|
import com.intellij.lang.annotation.Annotator;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.psi.JetProperty;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
@@ -13,9 +16,48 @@ public class JetPsiChecker implements Annotator {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
|
public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
|
||||||
if (element instanceof JetProperty) {
|
if (element instanceof JetFile) {
|
||||||
JetProperty property = (JetProperty) element;
|
// JetProperty property = (JetProperty) element;
|
||||||
holder.createErrorAnnotation(property.getNameIdentifier(), "Specify either type or value");
|
// holder.createErrorAnnotation(property.getNameIdentifier(), "Specify either type or value");
|
||||||
|
JetFile file = (JetFile) element;
|
||||||
|
String path = file.getProject().getBaseDir().getPath();
|
||||||
|
System.out.println("Path: " + path);
|
||||||
|
JetNamespace rootNamespace = file.getRootNamespace();
|
||||||
|
List<JetDeclaration> declarations = rootNamespace.getDeclarations();
|
||||||
|
|
||||||
|
for (JetDeclaration declaration : declarations) {
|
||||||
|
declaration.accept(new JetVisitor() {
|
||||||
|
@Override
|
||||||
|
public void visitClass(JetClass klass) {
|
||||||
|
print("class ");
|
||||||
|
print(klass.getName());
|
||||||
|
println("{");
|
||||||
|
for (JetDeclaration decl : klass.getDeclarations()) {
|
||||||
|
decl.accept(this);
|
||||||
|
}
|
||||||
|
print("}");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitProperty(JetProperty property) {
|
||||||
|
JetTypeReference propertyTypeRef = property.getPropertyTypeRef();
|
||||||
|
String name = property.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitFunction(JetFunction fun) {
|
||||||
|
super.visitFunction(fun); //To change body of overridden methods use File | Settings | File Templates.
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void print(Object o) {
|
||||||
|
System.out.print(o);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void println(Object o) {
|
||||||
|
System.out.println(o);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,13 +13,23 @@ import java.util.List;
|
|||||||
* @author max
|
* @author max
|
||||||
*/
|
*/
|
||||||
public class JetChangeUtil {
|
public class JetChangeUtil {
|
||||||
|
public static JetExpression createExpression(Project project, String text) {
|
||||||
|
JetProperty property = createProperty(project, "val x = " + text);
|
||||||
|
return property.getInitializer();
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static JetFile createFile(Project project, String text) {
|
public static JetFile createFile(Project project, String text) {
|
||||||
return (JetFile) PsiFileFactory.getInstance(project).createFileFromText("dummy.jet", JetFileType.INSTANCE, text, LocalTimeCounter.currentTime(), true);
|
return (JetFile) PsiFileFactory.getInstance(project).createFileFromText("dummy.jet", JetFileType.INSTANCE, text, LocalTimeCounter.currentTime(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JetProperty createProperty(Project project, String name, String type) {
|
public static JetProperty createProperty(Project project, String name, String type) {
|
||||||
JetFile file = createFile(project, "val " + name + (type != null ? ":" + type : ""));
|
String text = "val " + name + (type != null ? ":" + type : "");
|
||||||
|
return createProperty(project, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JetProperty createProperty(Project project, String text) {
|
||||||
|
JetFile file = createFile(project, text);
|
||||||
JetNamespace rootNamespace = file.getRootNamespace();
|
JetNamespace rootNamespace = file.getRootNamespace();
|
||||||
List<JetDeclaration> dcls = rootNamespace.getDeclarations();
|
List<JetDeclaration> dcls = rootNamespace.getDeclarations();
|
||||||
assert dcls.size() == 1;
|
assert dcls.size() == 1;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package org.jetbrains.jet.lang.psi;
|
package org.jetbrains.jet.lang.psi;
|
||||||
|
|
||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.JetNodeTypes;
|
import org.jetbrains.jet.JetNodeTypes;
|
||||||
@@ -79,4 +81,9 @@ public class JetProperty extends JetNamedDeclaration {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JetExpression getInitializer() {
|
||||||
|
PsiElement eq = findChildByType(JetTokens.EQ);
|
||||||
|
return PsiTreeUtil.getNextSiblingOfType(eq, JetExpression.class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class JetTupleExpression extends JetExpression {
|
|||||||
visitor.visitTupleExpression(this);
|
visitor.visitTupleExpression(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<JetExpression> getComponents() {
|
public List<JetExpression> getEntries() {
|
||||||
return PsiTreeUtil.getChildrenOfTypeAsList(this, JetExpression.class);
|
return PsiTreeUtil.getChildrenOfTypeAsList(this, JetExpression.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import com.intellij.lang.ASTNode;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.JetNodeTypes;
|
import org.jetbrains.jet.JetNodeTypes;
|
||||||
|
import org.jetbrains.jet.lang.types.Variance;
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ public class JetVisitor extends PsiElementVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void visitClass(JetClass klass) {
|
public void visitClass(JetClass klass) {
|
||||||
visitDeclaration(klass);
|
visitNamedDeclaration(klass);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitClassObject(JetClassObject classObject) {
|
public void visitClassObject(JetClassObject classObject) {
|
||||||
@@ -31,19 +31,19 @@ public class JetVisitor extends PsiElementVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void visitExtension(JetExtension extension) {
|
public void visitExtension(JetExtension extension) {
|
||||||
visitDeclaration(extension);
|
visitNamedDeclaration(extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitFunction(JetFunction fun) {
|
public void visitFunction(JetFunction fun) {
|
||||||
visitDeclaration(fun);
|
visitNamedDeclaration(fun);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitProperty(JetProperty property) {
|
public void visitProperty(JetProperty property) {
|
||||||
visitDeclaration(property);
|
visitNamedDeclaration(property);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitTypedef(JetTypedef typedef) {
|
public void visitTypedef(JetTypedef typedef) {
|
||||||
visitDeclaration(typedef);
|
visitNamedDeclaration(typedef);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitJetFile(JetFile file) {
|
public void visitJetFile(JetFile file) {
|
||||||
@@ -79,7 +79,7 @@ public class JetVisitor extends PsiElementVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void visitTypeParameter(JetTypeParameter parameter) {
|
public void visitTypeParameter(JetTypeParameter parameter) {
|
||||||
visitDeclaration(parameter);
|
visitNamedDeclaration(parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitEnumEntry(JetEnumEntry enumEntry) {
|
public void visitEnumEntry(JetEnumEntry enumEntry) {
|
||||||
@@ -91,7 +91,7 @@ public class JetVisitor extends PsiElementVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void visitParameter(JetParameter parameter) {
|
public void visitParameter(JetParameter parameter) {
|
||||||
visitDeclaration(parameter);
|
visitNamedDeclaration(parameter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitDelegationSpecifierList(JetDelegationSpecifierList list) {
|
public void visitDelegationSpecifierList(JetDelegationSpecifierList list) {
|
||||||
@@ -317,4 +317,8 @@ public class JetVisitor extends PsiElementVisitor {
|
|||||||
public void visitMatchBlock(JetMatchBlock block) {
|
public void visitMatchBlock(JetMatchBlock block) {
|
||||||
visitJetElement(block);
|
visitJetElement(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void visitNamedDeclaration(JetNamedDeclaration declaration) {
|
||||||
|
visitJetElement(declaration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
package org.jetbrains.jet.lang.psi;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author max
|
|
||||||
*/
|
|
||||||
public enum Variance {
|
|
||||||
INVARIANT,
|
|
||||||
IN_VARIANCE,
|
|
||||||
OUT_VARIANCE
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public interface Annotated {
|
||||||
|
List<Annotation> getAnnotations();
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public abstract class AnnotatedImpl implements Annotated {
|
||||||
|
private final List<Annotation> annotations;
|
||||||
|
|
||||||
|
public AnnotatedImpl(List<Annotation> annotations) {
|
||||||
|
this.annotations = annotations;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Annotation> getAnnotations() {
|
||||||
|
return annotations;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public interface Annotation {
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class ClassDescriptor extends MemberDescriptorImpl {
|
||||||
|
private final TypeConstructor typeConstructor;
|
||||||
|
|
||||||
|
public ClassDescriptor(
|
||||||
|
List<Annotation> annotations,
|
||||||
|
String name, List<TypeParameterDescriptor> typeParameters, Collection<Type> superclasses) {
|
||||||
|
super(annotations, name);
|
||||||
|
this.typeConstructor = new TypeConstructor(annotations, name, typeParameters, superclasses);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassDescriptor(String name) {
|
||||||
|
this(Collections.<Annotation>emptyList(),
|
||||||
|
name, Collections.<TypeParameterDescriptor>emptyList(),
|
||||||
|
Collections.<Type>singleton(JetStandardTypes.getAny()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeConstructor getTypeConstructor() {
|
||||||
|
return typeConstructor;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class ClassType extends TypeImpl {
|
||||||
|
private final ClassDescriptor classDescriptor;
|
||||||
|
|
||||||
|
public ClassType(List<Annotation> annotations, ClassDescriptor classDescriptor, List<TypeProjection> arguments) {
|
||||||
|
super(annotations, classDescriptor.getTypeConstructor(), arguments);
|
||||||
|
assert classDescriptor.getTypeConstructor().getParameters().size() == arguments.size();
|
||||||
|
|
||||||
|
this.classDescriptor = classDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassType(ClassDescriptor classDescriptor) {
|
||||||
|
this(Collections.<Annotation>emptyList(), classDescriptor, Collections.<TypeProjection>emptyList());
|
||||||
|
assert classDescriptor.getTypeConstructor().getParameters().size() == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassDescriptor getClassDescriptor() {
|
||||||
|
return classDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<MemberDescriptor> getMembers() {
|
||||||
|
throw new UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class JetStandardClasses {
|
||||||
|
private static final ClassDescriptor ANY = new ClassDescriptor(
|
||||||
|
Collections.<Annotation>emptyList(),
|
||||||
|
"Any",
|
||||||
|
Collections.<TypeParameterDescriptor>emptyList(),
|
||||||
|
Collections.<Type>emptySet()
|
||||||
|
);
|
||||||
|
|
||||||
|
private static final ClassDescriptor BYTE = new ClassDescriptor("Byte");
|
||||||
|
private static final ClassDescriptor CHAR = new ClassDescriptor("Char");
|
||||||
|
private static final ClassDescriptor SHORT = new ClassDescriptor("Short");
|
||||||
|
private static final ClassDescriptor INT = new ClassDescriptor("Int");
|
||||||
|
private static final ClassDescriptor LONG = new ClassDescriptor("Long");
|
||||||
|
private static final ClassDescriptor FLOAT = new ClassDescriptor("Float");
|
||||||
|
private static final ClassDescriptor DOUBLE = new ClassDescriptor("Double");
|
||||||
|
private static final ClassDescriptor BOOLEAN = new ClassDescriptor("Boolean");
|
||||||
|
private static final ClassDescriptor STRING = new ClassDescriptor("String");
|
||||||
|
|
||||||
|
public static ClassDescriptor getAny() {
|
||||||
|
return ANY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassDescriptor getByte() {
|
||||||
|
return BYTE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassDescriptor getChar() {
|
||||||
|
return CHAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassDescriptor getShort() {
|
||||||
|
return SHORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassDescriptor getInt() {
|
||||||
|
return INT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassDescriptor getLong() {
|
||||||
|
return LONG;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassDescriptor getFloat() {
|
||||||
|
return FLOAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassDescriptor getDouble() {
|
||||||
|
return DOUBLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassDescriptor getBoolean() {
|
||||||
|
return BOOLEAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassDescriptor getString() {
|
||||||
|
return STRING;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class JetStandardTypes {
|
||||||
|
private static final ClassType ANY_TYPE = new ClassType(JetStandardClasses.getAny());
|
||||||
|
private static final ClassType BYTE = new ClassType(JetStandardClasses.getByte());
|
||||||
|
private static final ClassType CHAR = new ClassType(JetStandardClasses.getChar());
|
||||||
|
private static final ClassType SHORT = new ClassType(JetStandardClasses.getShort());
|
||||||
|
private static final ClassType INT = new ClassType(JetStandardClasses.getInt());
|
||||||
|
private static final ClassType LONG = new ClassType(JetStandardClasses.getLong());
|
||||||
|
private static final ClassType FLOAT = new ClassType(JetStandardClasses.getFloat());
|
||||||
|
private static final ClassType DOUBLE = new ClassType(JetStandardClasses.getDouble());
|
||||||
|
private static final ClassType BOOLEAN = new ClassType(JetStandardClasses.getBoolean());
|
||||||
|
private static final ClassType STRING = new ClassType(JetStandardClasses.getString());
|
||||||
|
private static final TupleType UNIT = TupleType.UNIT;
|
||||||
|
|
||||||
|
public static ClassType getInt() {
|
||||||
|
return INT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassType getLong() {
|
||||||
|
return LONG;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassType getDouble() {
|
||||||
|
return DOUBLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassType getFloat() {
|
||||||
|
return FLOAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassType getChar() {
|
||||||
|
return CHAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassType getBoolean() {
|
||||||
|
return BOOLEAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassType getString() {
|
||||||
|
return STRING;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassType getByte() {
|
||||||
|
return BYTE;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ClassType getShort() {
|
||||||
|
return SHORT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TupleType getUnit() {
|
||||||
|
return UNIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Type getAny() {
|
||||||
|
return ANY_TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import com.intellij.psi.tree.IElementType;
|
||||||
|
import org.jetbrains.jet.JetNodeTypes;
|
||||||
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class JetTypeChecker {
|
||||||
|
public Type getType(JetExpression expression) {
|
||||||
|
final Type[] result = new Type[1];
|
||||||
|
expression.accept(new JetVisitor() {
|
||||||
|
@Override
|
||||||
|
public void visitConstantExpression(JetConstantExpression expression) {
|
||||||
|
IElementType elementType = expression.getNode().getElementType();
|
||||||
|
if (elementType == JetNodeTypes.INTEGER_CONSTANT) {
|
||||||
|
result[0] = JetStandardTypes.getInt();
|
||||||
|
} else if (elementType == JetNodeTypes.LONG_CONSTANT) {
|
||||||
|
result[0] = JetStandardTypes.getLong();
|
||||||
|
} else if (elementType == JetNodeTypes.FLOAT_CONSTANT) {
|
||||||
|
String text = expression.getText();
|
||||||
|
assert text.length() > 0;
|
||||||
|
char lastChar = text.charAt(text.length() - 1);
|
||||||
|
if (lastChar == 'f' || lastChar == 'F') {
|
||||||
|
result[0] = JetStandardTypes.getFloat();
|
||||||
|
} else {
|
||||||
|
result[0] = JetStandardTypes.getDouble();
|
||||||
|
}
|
||||||
|
} else if (elementType == JetNodeTypes.BOOLEAN_CONSTANT) {
|
||||||
|
result[0] = JetStandardTypes.getBoolean();
|
||||||
|
} else if (elementType == JetNodeTypes.CHARACTER_CONSTANT) {
|
||||||
|
result[0] = JetStandardTypes.getChar();
|
||||||
|
} else if (elementType == JetNodeTypes.STRING_CONSTANT) {
|
||||||
|
result[0] = JetStandardTypes.getString();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unsupported constant: " + expression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitTupleExpression(JetTupleExpression expression) {
|
||||||
|
List<JetExpression> entries = expression.getEntries();
|
||||||
|
List<Type> types = new ArrayList<Type>();
|
||||||
|
for (JetExpression entry : entries) {
|
||||||
|
types.add(getType(entry));
|
||||||
|
}
|
||||||
|
result[0] = TupleType.getTupleType(types);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitJetElement(JetElement elem) {
|
||||||
|
throw new IllegalArgumentException("Unsupported element: " + elem);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isConvertibleTo(JetExpression expression, Type type) {
|
||||||
|
return false; //To change body of created methods use File | Settings | File Templates.
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public interface MemberDescriptor {
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public abstract class MemberDescriptorImpl extends NamedAnnotatedImpl {
|
||||||
|
public MemberDescriptorImpl(List<Annotation> annotations, String name) {
|
||||||
|
super(annotations, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public abstract class NamedAnnotatedImpl extends AnnotatedImpl {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public NamedAnnotatedImpl(List<Annotation> annotations, String name) {
|
||||||
|
super(annotations);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class NothingType extends TypeImpl {
|
||||||
|
|
||||||
|
public static final TypeConstructor NOTHING = new TypeConstructor(
|
||||||
|
Collections.<Annotation>emptyList(),
|
||||||
|
"Nothing",
|
||||||
|
Collections.<TypeParameterDescriptor>emptyList(),
|
||||||
|
new AbstractCollection<Type>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean contains(Object o) {
|
||||||
|
return o instanceof Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterator<Type> iterator() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: annotations seem wrong here
|
||||||
|
public NothingType(List<Annotation> annotations) {
|
||||||
|
super(annotations, NOTHING, Collections.<TypeProjection>emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<MemberDescriptor> getMembers() {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class ParameterDescriptor extends AnnotatedImpl {
|
||||||
|
private final Type type;
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
public ParameterDescriptor(List<Annotation> annotations, Type type, String name) {
|
||||||
|
super(annotations);
|
||||||
|
this.type = type;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
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 TupleType extends TypeImpl {
|
||||||
|
|
||||||
|
public static final int TUPLE_COUNT = 22;
|
||||||
|
private static final TypeConstructor[] TUPLE = new TypeConstructor[TUPLE_COUNT];
|
||||||
|
|
||||||
|
public static final TupleType UNIT = new TupleType(Collections.<Annotation>emptyList(), Collections.<Type>emptyList());
|
||||||
|
|
||||||
|
static {
|
||||||
|
for (int i = 0; i < TUPLE_COUNT; i++) {
|
||||||
|
List<TypeParameterDescriptor> parameters = new ArrayList<TypeParameterDescriptor>();
|
||||||
|
for (int j = 0; j < i; j++) {
|
||||||
|
parameters.add(new TypeParameterDescriptor(
|
||||||
|
Collections.<Annotation>emptyList(),
|
||||||
|
"T" + j,
|
||||||
|
Variance.OUT_VARIANCE,
|
||||||
|
Collections.<Type>emptySet()));
|
||||||
|
}
|
||||||
|
TUPLE[i] = new TypeConstructor(
|
||||||
|
Collections.<Annotation>emptyList(),
|
||||||
|
"Tuple" + i,
|
||||||
|
parameters,
|
||||||
|
Collections.singleton(JetStandardTypes.getAny()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TupleType getTupleType(List<Annotation> annotations, List<Type> arguments) {
|
||||||
|
if (annotations.isEmpty() && arguments.isEmpty()) {
|
||||||
|
return UNIT;
|
||||||
|
}
|
||||||
|
return new TupleType(annotations, arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static TupleType getTupleType(List<Type> arguments) {
|
||||||
|
return getTupleType(Collections.<Annotation>emptyList(), arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TupleType getLabeledTupleType(List<Annotation> annotations, List<ParameterDescriptor> arguments) {
|
||||||
|
return getTupleType(annotations, toTypes(arguments));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static TupleType getLabeledTupleType(List<ParameterDescriptor> arguments) {
|
||||||
|
return getLabeledTupleType(Collections.<Annotation>emptyList(), arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private TupleType(List<Annotation> annotations, List<Type> arguments) {
|
||||||
|
super(annotations, TUPLE[arguments.size()], toProjections(arguments));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<MemberDescriptor> getMembers() {
|
||||||
|
throw new UnsupportedOperationException("Not implemented"); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<TypeProjection> toProjections(List<Type> arguments) {
|
||||||
|
List<TypeProjection> result = new ArrayList<TypeProjection>();
|
||||||
|
for (Type argument : arguments) {
|
||||||
|
result.add(new TypeProjection(Variance.OUT_VARIANCE, argument));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Type> toTypes(List<ParameterDescriptor> labeledEntries) {
|
||||||
|
List<Type> result = new ArrayList<Type>();
|
||||||
|
for (ParameterDescriptor entry : labeledEntries) {
|
||||||
|
result.add(entry.getType());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public interface Type extends Annotated {
|
||||||
|
TypeConstructor getConstructor();
|
||||||
|
List<TypeProjection> getArguments();
|
||||||
|
|
||||||
|
Collection<MemberDescriptor> getMembers();
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class TypeConstructor extends AnnotatedImpl {
|
||||||
|
private final List<TypeParameterDescriptor> parameters;
|
||||||
|
private final Collection<Type> supertypes;
|
||||||
|
private final String debugName;
|
||||||
|
|
||||||
|
public TypeConstructor(List<Annotation> annotations, String debugName, List<TypeParameterDescriptor> parameters, Collection<Type> supertypes) {
|
||||||
|
super(annotations);
|
||||||
|
this.debugName = debugName;
|
||||||
|
this.parameters = parameters;
|
||||||
|
this.supertypes = supertypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TypeParameterDescriptor> getParameters() {
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<Type> getSupertypes() {
|
||||||
|
return supertypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return debugName;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public abstract class TypeImpl extends AnnotatedImpl implements Type {
|
||||||
|
|
||||||
|
private final TypeConstructor constructor;
|
||||||
|
private final List<TypeProjection> arguments;
|
||||||
|
|
||||||
|
public TypeImpl(List<Annotation> annotations, TypeConstructor constructor, List<TypeProjection> arguments) {
|
||||||
|
super(annotations);
|
||||||
|
this.constructor = constructor;
|
||||||
|
this.arguments = arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypeConstructor getConstructor() {
|
||||||
|
return constructor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TypeProjection> getArguments() {
|
||||||
|
return arguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return constructor + (arguments.isEmpty() ? "" : "<" + argumentsToString() + ">");
|
||||||
|
}
|
||||||
|
|
||||||
|
private StringBuilder argumentsToString() {
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
for (Iterator<TypeProjection> iterator = arguments.iterator(); iterator.hasNext();) {
|
||||||
|
TypeProjection argument = iterator.next();
|
||||||
|
stringBuilder.append(argument);
|
||||||
|
if (iterator.hasNext()) {
|
||||||
|
stringBuilder.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stringBuilder;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class TypeParameterDescriptor extends NamedAnnotatedImpl {
|
||||||
|
private final Variance variance;
|
||||||
|
private final Collection<Type> upperBounds;
|
||||||
|
private final TypeConstructor typeConstructor;
|
||||||
|
|
||||||
|
public TypeParameterDescriptor(List<Annotation> annotations, String name, Variance variance, Collection<Type> upperBounds) {
|
||||||
|
super(annotations, name);
|
||||||
|
this.variance = variance;
|
||||||
|
this.upperBounds = upperBounds;
|
||||||
|
// TODO: Should we actually pass the annotations on to the type constructor?
|
||||||
|
this.typeConstructor = new TypeConstructor(
|
||||||
|
annotations,
|
||||||
|
name,
|
||||||
|
Collections.<TypeParameterDescriptor>emptyList(),
|
||||||
|
upperBounds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Variance getVariance() {
|
||||||
|
return variance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<Type> getUpperBounds() {
|
||||||
|
return upperBounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeConstructor getTypeConstructor() {
|
||||||
|
return typeConstructor;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class TypeProjection {
|
||||||
|
private final Variance projection;
|
||||||
|
private final Type type;
|
||||||
|
|
||||||
|
public TypeProjection(Variance projection, Type type) {
|
||||||
|
this.projection = projection;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Variance getProjection() {
|
||||||
|
return projection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Type getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return projection + " " + type;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class TypeVariable extends TypeImpl {
|
||||||
|
|
||||||
|
|
||||||
|
public TypeVariable(List<Annotation> annotations, TypeParameterDescriptor typeParameter) {
|
||||||
|
super(annotations, typeParameter.getTypeConstructor(), Collections.<TypeProjection>emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<MemberDescriptor> getMembers() {
|
||||||
|
throw new javax.help.UnsupportedOperationException(); // TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package org.jetbrains.jet.lang.types;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author max
|
||||||
|
*/
|
||||||
|
public enum Variance {
|
||||||
|
INVARIANT(""),
|
||||||
|
IN_VARIANCE("in"),
|
||||||
|
OUT_VARIANCE("out");
|
||||||
|
|
||||||
|
private final String label;
|
||||||
|
|
||||||
|
Variance(String label) {
|
||||||
|
this.label = label;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
package org.jetbrains.jet.parsing;
|
||||||
|
|
||||||
|
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.types.JetStandardTypes;
|
||||||
|
import org.jetbrains.jet.lang.types.Type;
|
||||||
|
import org.jetbrains.jet.lang.types.JetTypeChecker;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author abreslav
|
||||||
|
*/
|
||||||
|
public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getTestDataPath() {
|
||||||
|
return getHomeDirectory() + "/idea/testData";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getHomeDirectory() {
|
||||||
|
return new File(PathManager.getResourceRoot(JetParsingTest.class, "/org/jetbrains/jet/parsing/JetParsingTest.class")).getParentFile().getParentFile().getParent();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testConstants() throws Exception {
|
||||||
|
assertType("1", JetStandardTypes.getInt());
|
||||||
|
assertType("0x1", JetStandardTypes.getInt());
|
||||||
|
assertType("0X1", JetStandardTypes.getInt());
|
||||||
|
assertType("0b1", JetStandardTypes.getInt());
|
||||||
|
assertType("0B1", JetStandardTypes.getInt());
|
||||||
|
|
||||||
|
assertType("1l", JetStandardTypes.getLong());
|
||||||
|
assertType("1L", JetStandardTypes.getLong());
|
||||||
|
|
||||||
|
assertType("1.0", JetStandardTypes.getDouble());
|
||||||
|
assertType("1.0d", JetStandardTypes.getDouble());
|
||||||
|
assertType("1.0D", JetStandardTypes.getDouble());
|
||||||
|
assertType("0x1.fffffffffffffp1023", JetStandardTypes.getDouble());
|
||||||
|
|
||||||
|
assertType("1.0f", JetStandardTypes.getFloat());
|
||||||
|
assertType("1.0F", JetStandardTypes.getFloat());
|
||||||
|
assertType("0x1.fffffffffffffp1023f", JetStandardTypes.getFloat());
|
||||||
|
|
||||||
|
assertType("true", JetStandardTypes.getBoolean());
|
||||||
|
assertType("false", JetStandardTypes.getBoolean());
|
||||||
|
|
||||||
|
assertType("'d'", JetStandardTypes.getChar());
|
||||||
|
|
||||||
|
assertType("\"d\"", JetStandardTypes.getString());
|
||||||
|
assertType("\"\"\"d\"\"\"", JetStandardTypes.getString());
|
||||||
|
|
||||||
|
assertType("()", JetStandardTypes.getUnit());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testImplicitConversions() throws Exception {
|
||||||
|
assertConvertibleTo("1", JetStandardTypes.getByte());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertConvertibleTo(String expression, Type type) {
|
||||||
|
JetExpression jetExpression = JetChangeUtil.createExpression(getProject(), expression);
|
||||||
|
assertTrue(
|
||||||
|
expression + " must be convertible to " + type,
|
||||||
|
new JetTypeChecker().isConvertibleTo(jetExpression, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertNotConvertibleTo(String expression, Type type) {
|
||||||
|
JetExpression jetExpression = JetChangeUtil.createExpression(getProject(), expression);
|
||||||
|
assertFalse(
|
||||||
|
expression + " must not be convertible to " + type,
|
||||||
|
new JetTypeChecker().isConvertibleTo(jetExpression, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertType(String expression, Type expectedType) {
|
||||||
|
Project project = getProject();
|
||||||
|
JetExpression jetExpression = JetChangeUtil.createExpression(project, expression);
|
||||||
|
Type type = new JetTypeChecker().getType(jetExpression);
|
||||||
|
assertEquals(type, expectedType);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user