Working on the type model

This commit is contained in:
Andrey Breslav
2011-01-17 23:06:00 +03:00
parent e40769f45b
commit c7292cee7b
29 changed files with 840 additions and 23 deletions
@@ -1,10 +1,13 @@
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;
import org.jetbrains.jet.lang.psi.JetProperty;
import org.jetbrains.jet.lang.psi.*;
import java.util.List;
/**
* @author abreslav
@@ -13,9 +16,48 @@ public class JetPsiChecker implements Annotator {
@Override
public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
if (element instanceof JetProperty) {
JetProperty property = (JetProperty) element;
holder.createErrorAnnotation(property.getNameIdentifier(), "Specify either type or value");
if (element instanceof JetFile) {
// JetProperty property = (JetProperty) element;
// 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
*/
public class JetChangeUtil {
public static JetExpression createExpression(Project project, String text) {
JetProperty property = createProperty(project, "val x = " + text);
return property.getInitializer();
}
@NotNull
public static JetFile createFile(Project project, String text) {
return (JetFile) PsiFileFactory.getInstance(project).createFileFromText("dummy.jet", JetFileType.INSTANCE, text, LocalTimeCounter.currentTime(), true);
}
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();
List<JetDeclaration> dcls = rootNamespace.getDeclarations();
assert dcls.size() == 1;
@@ -1,7 +1,9 @@
package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetNodeTypes;
@@ -79,4 +81,9 @@ public class JetProperty extends JetNamedDeclaration {
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);
}
public List<JetExpression> getComponents() {
public List<JetExpression> getEntries() {
return PsiTreeUtil.getChildrenOfTypeAsList(this, JetExpression.class);
}
}
@@ -4,6 +4,7 @@ import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetNodeTypes;
import org.jetbrains.jet.lang.types.Variance;
import org.jetbrains.jet.lexer.JetTokens;
/**
@@ -19,7 +19,7 @@ public class JetVisitor extends PsiElementVisitor {
}
public void visitClass(JetClass klass) {
visitDeclaration(klass);
visitNamedDeclaration(klass);
}
public void visitClassObject(JetClassObject classObject) {
@@ -31,19 +31,19 @@ public class JetVisitor extends PsiElementVisitor {
}
public void visitExtension(JetExtension extension) {
visitDeclaration(extension);
visitNamedDeclaration(extension);
}
public void visitFunction(JetFunction fun) {
visitDeclaration(fun);
visitNamedDeclaration(fun);
}
public void visitProperty(JetProperty property) {
visitDeclaration(property);
visitNamedDeclaration(property);
}
public void visitTypedef(JetTypedef typedef) {
visitDeclaration(typedef);
visitNamedDeclaration(typedef);
}
public void visitJetFile(JetFile file) {
@@ -79,7 +79,7 @@ public class JetVisitor extends PsiElementVisitor {
}
public void visitTypeParameter(JetTypeParameter parameter) {
visitDeclaration(parameter);
visitNamedDeclaration(parameter);
}
public void visitEnumEntry(JetEnumEntry enumEntry) {
@@ -91,7 +91,7 @@ public class JetVisitor extends PsiElementVisitor {
}
public void visitParameter(JetParameter parameter) {
visitDeclaration(parameter);
visitNamedDeclaration(parameter);
}
public void visitDelegationSpecifierList(JetDelegationSpecifierList list) {
@@ -317,4 +317,8 @@ public class JetVisitor extends PsiElementVisitor {
public void visitMatchBlock(JetMatchBlock 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);
}
}