diff --git a/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java b/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java index 669ea8171ab..d6ec63276ca 100644 --- a/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java +++ b/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java @@ -1412,8 +1412,10 @@ public class JetParsing extends AbstractJetParsing { } if (isFunctionTypeContents) { if (!tryParseValueParameter()) { - parseModifierList(); // lazy, out, ref - parseTypeRef(); + PsiBuilder.Marker valueParameter = mark(); + parseModifierList(); // lazy, out, ref + parseTypeRef(); + valueParameter.done(VALUE_PARAMETER); } } else { parseValueParameter(); diff --git a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java index c05759145a0..ec87ecf28c9 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java @@ -2,14 +2,8 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.psi.JetClass; -import org.jetbrains.jet.lang.psi.JetDelegationSpecifier; -import org.jetbrains.jet.lang.psi.JetTypeParameter; -import org.jetbrains.jet.lang.psi.JetTypeReference; -import org.jetbrains.jet.lang.types.ClassDescriptor; -import org.jetbrains.jet.lang.types.JetStandardClasses; -import org.jetbrains.jet.lang.types.Type; -import org.jetbrains.jet.lang.types.TypeParameterDescriptor; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lexer.JetTokens; import java.util.*; @@ -106,4 +100,12 @@ public class ClassDescriptorResolver { return super.getTypeParameterDescriptor(name); } } + + @NotNull + public PropertyDescriptor resolvePropertyDescriptor(@NotNull JetScope scope, @NotNull JetParameter parameter) { + return new PropertyDescriptor( + AttributeResolver.INSTANCE.resolveAttributes(parameter.getModifierList()), + parameter.getName(), + TypeResolver.INSTANCE.resolveType(scope, parameter.getTypeReference())); + } } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java index 805c9e6ea1a..07dd6c642f5 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/TypeResolver.java @@ -70,6 +70,21 @@ public class TypeResolver { result[0] = JetStandardClasses.getTupleType(resolveTypes(scope, type.getComponentTypeRefs())); } + @Override + public void visitFunctionType(JetFunctionType type) { + JetTypeReference receiverTypeRef = type.getReceiverTypeRef(); + Type receiverType = receiverTypeRef == null ? null : resolveType(scope, receiverTypeRef); + + List parameterTypes = new ArrayList(); + for (JetParameter parameter : type.getParameters()) { + parameterTypes.add(resolveType(scope, parameter.getTypeReference())); + } + + Type returnType = resolveType(scope, type.getReturnTypeRef()); + + result[0] = JetStandardClasses.getFunctionType(attributes, receiverType, parameterTypes, returnType); + } + @Override public void visitJetElement(JetElement elem) { throw new IllegalArgumentException("Unsupported type: " + elem); diff --git a/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java b/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java index 6bf9eacfe5b..5ec30be0607 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetStandardClasses.java @@ -1,6 +1,7 @@ package org.jetbrains.jet.lang.types; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -62,7 +63,7 @@ public class JetStandardClasses { parameters.add(new TypeParameterDescriptor( Collections.emptyList(), Variance.OUT_VARIANCE, "T" + j, - Collections.emptySet())); + Collections.singleton(getNullableAnyType()))); } TUPLE[i] = new ClassDescriptor( Collections.emptyList(), @@ -73,6 +74,42 @@ public class JetStandardClasses { } } + public static final int FUNCTION_COUNT = 22; + private static final ClassDescriptor[] FUNCTION = new ClassDescriptor[FUNCTION_COUNT]; + private static final ClassDescriptor[] RECEIVER_FUNCTION = new ClassDescriptor[FUNCTION_COUNT]; + static { + for (int i = 0; i < FUNCTION_COUNT; i++) { + List parameters = new ArrayList(); + for (int j = 0; j < i; j++) { + parameters.add(new TypeParameterDescriptor( + Collections.emptyList(), + Variance.IN_VARIANCE, "P" + j, + Collections.singleton(getNullableAnyType()))); + } + parameters.add(new TypeParameterDescriptor( + Collections.emptyList(), + Variance.OUT_VARIANCE, "R", + Collections.singleton(getNullableAnyType()))); + FUNCTION[i] = new ClassDescriptor( + Collections.emptyList(), + false, + "Function" + i, + parameters, + Collections.singleton(JetStandardClasses.getAnyType())); + parameters.add(0, new TypeParameterDescriptor( + Collections.emptyList(), + Variance.IN_VARIANCE, "T", + Collections.singleton(getNullableAnyType()))); + RECEIVER_FUNCTION[i] = new ClassDescriptor( + Collections.emptyList(), + false, + "ReceiverFunction" + i, + parameters, + Collections.singleton(JetStandardClasses.getAnyType())); + } + } + + public static final TypeMemberDomain STUB = new TypeMemberDomain() { @Override public ClassDescriptor getClassDescriptor(@NotNull Type type) { @@ -259,4 +296,23 @@ public class JetStandardClasses { } return result; } + + // TODO : labeled version? + public static Type getFunctionType(List attributes, @Nullable Type receiverType, @NotNull List parameterTypes, @NotNull Type returnType) { + List arguments = new ArrayList(); + if (receiverType != null) { + arguments.add(defaultProjection(receiverType)); + } + for (Type parameterType : parameterTypes) { + arguments.add(defaultProjection(parameterType)); + } + arguments.add(defaultProjection(returnType)); + int size = parameterTypes.size(); + TypeConstructor constructor = receiverType == null ? FUNCTION[size].getTypeConstructor() : RECEIVER_FUNCTION[size].getTypeConstructor(); + return new TypeImpl(attributes, constructor, false, arguments, STUB); + } + + private static TypeProjection defaultProjection(Type returnType) { + return new TypeProjection(Variance.INVARIANT, returnType); + } } diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java index f5ceb45ac05..5cfb87342b2 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java @@ -5,7 +5,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.JetNodeTypes; import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.ClassDescriptorResolver; import org.jetbrains.jet.lang.resolve.JetScope; +import org.jetbrains.jet.lang.resolve.JetScopeAdapter; import org.jetbrains.jet.lang.resolve.TypeResolver; import org.jetbrains.jet.lexer.JetTokens; @@ -34,6 +36,65 @@ public class JetTypeChecker { public Type getType(@NotNull final JetScope scope, @NotNull JetExpression expression) { final Type[] result = new Type[1]; expression.accept(new JetVisitor() { + @Override + public void visitReferenceExpression(JetReferenceExpression expression) { + // TODO : other members + // TODO : type substitutions??? + PropertyDescriptor property = scope.getProperty(expression.getReferencedName()); + if (property != null) { + result[0] = property.getType(); + } + } + + @Override + public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) { + JetTypeReference returnTypeRef = expression.getReturnTypeRef(); + + JetTypeReference receiverTypeRef = expression.getReceiverTypeRef(); + final Type thisType; + if (receiverTypeRef != null) { + thisType = TypeResolver.INSTANCE.resolveType(scope, receiverTypeRef); + } else { + thisType = scope.getThisType(); + } + + List body = expression.getBody(); + final Map parameterDescriptors = new HashMap(); + List parameterTypes = new ArrayList(); + for (JetParameter parameter : expression.getParameters()) { + JetTypeReference typeReference = parameter.getTypeReference(); + if (typeReference == null) { + throw new UnsupportedOperationException("Type inference for parameters is not implemented yet"); + } + PropertyDescriptor propertyDescriptor = ClassDescriptorResolver.INSTANCE.resolvePropertyDescriptor(scope, parameter); + parameterDescriptors.put(parameter.getName(), propertyDescriptor); + parameterTypes.add(propertyDescriptor.getType()); + } + Type returnType; + if (returnTypeRef != null) { + returnType = TypeResolver.INSTANCE.resolveType(scope, returnTypeRef); + } else if (body.isEmpty()) { + returnType = JetStandardClasses.getUnitType(); + } else { + returnType = getType(new JetScopeAdapter(scope) { + @Override + public Type getThisType() { + return thisType; + } + + @Override + public PropertyDescriptor getProperty(String name) { + PropertyDescriptor propertyDescriptor = parameterDescriptors.get(name); + if (propertyDescriptor == null) { + return super.getProperty(name); + } + return propertyDescriptor; + } + }, body.get(body.size() - 1)); + } + result[0] = JetStandardClasses.getFunctionType(null, receiverTypeRef == null ? null : thisType, parameterTypes, returnType); + } + @Override public void visitParenthesizedExpression(JetParenthesizedExpression expression) { result[0] = getType(scope, expression.getExpression()); diff --git a/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptor.java index de10e3328bf..eddcd3d6b04 100644 --- a/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptor.java @@ -1,7 +1,23 @@ package org.jetbrains.jet.lang.types; +import java.util.List; + /** * @author abreslav */ -public class PropertyDescriptor { +public class PropertyDescriptor extends MemberDescriptorImpl { + private Type type; + + public PropertyDescriptor(List attributes, String name, Type type) { + super(attributes, name); + this.type = type; + } + + public PropertyDescriptor(List attributes, String name) { + this(attributes, name, null); + } + + public Type getType() { + return type; + } } diff --git a/idea/src/org/jetbrains/jet/lang/types/TypeConstructor.java b/idea/src/org/jetbrains/jet/lang/types/TypeConstructor.java index 2ca7a263396..d4d5408f66a 100644 --- a/idea/src/org/jetbrains/jet/lang/types/TypeConstructor.java +++ b/idea/src/org/jetbrains/jet/lang/types/TypeConstructor.java @@ -1,5 +1,6 @@ package org.jetbrains.jet.lang.types; +import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -16,7 +17,7 @@ public class TypeConstructor extends AnnotatedImpl { super(attributes); this.sealed = sealed; this.debugName = debugName; - this.parameters = parameters; + this.parameters = new ArrayList(parameters); this.supertypes = supertypes; } diff --git a/idea/testData/psi/FunctionTypes.txt b/idea/testData/psi/FunctionTypes.txt index 90237c3bf3a..c65245e55b8 100644 --- a/idea/testData/psi/FunctionTypes.txt +++ b/idea/testData/psi/FunctionTypes.txt @@ -14,20 +14,21 @@ JetFile: FunctionTypes.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - MODIFIER_LIST - ATTRIBUTE_ANNOTATION - PsiElement(LBRACKET)('[') - ATTRIBUTE - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('a') - PsiElement(RBRACKET)(']') - PsiWhiteSpace(' ') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('a') + VALUE_PARAMETER + MODIFIER_LIST + ATTRIBUTE_ANNOTATION + PsiElement(LBRACKET)('[') + ATTRIBUTE + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') + PsiElement(RBRACKET)(']') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -52,10 +53,11 @@ JetFile: FunctionTypes.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('a') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -280,10 +282,11 @@ JetFile: FunctionTypes.jet PsiElement(IDENTIFIER)('a') PsiElement(COMMA)(',') PsiWhiteSpace(' ') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('foo') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') PsiElement(COMMA)(',') PsiWhiteSpace(' ') VALUE_PARAMETER @@ -319,10 +322,11 @@ JetFile: FunctionTypes.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('foo') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') PsiElement(COMMA)(',') PsiWhiteSpace(' ') VALUE_PARAMETER @@ -358,10 +362,11 @@ JetFile: FunctionTypes.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('foo') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') PsiElement(COMMA)(',') PsiWhiteSpace(' ') VALUE_PARAMETER @@ -374,10 +379,11 @@ JetFile: FunctionTypes.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('a') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -411,10 +417,11 @@ JetFile: FunctionTypes.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('foo') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') PsiElement(COMMA)(',') PsiWhiteSpace(' ') VALUE_PARAMETER @@ -427,10 +434,11 @@ JetFile: FunctionTypes.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('a') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -474,13 +482,14 @@ JetFile: FunctionTypes.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - MODIFIER_LIST - PsiElement(ref)('ref') - PsiWhiteSpace(' ') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('foo') + VALUE_PARAMETER + MODIFIER_LIST + PsiElement(ref)('ref') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') PsiElement(COMMA)(',') PsiWhiteSpace(' ') VALUE_PARAMETER @@ -496,13 +505,14 @@ JetFile: FunctionTypes.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - MODIFIER_LIST - PsiElement(ref)('ref') - PsiWhiteSpace(' ') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('a') + VALUE_PARAMETER + MODIFIER_LIST + PsiElement(ref)('ref') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') diff --git a/idea/testData/psi/FunctionTypes_ERR.txt b/idea/testData/psi/FunctionTypes_ERR.txt index 7837897e8fb..454009ee99d 100644 --- a/idea/testData/psi/FunctionTypes_ERR.txt +++ b/idea/testData/psi/FunctionTypes_ERR.txt @@ -14,20 +14,21 @@ JetFile: FunctionTypes_ERR.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - MODIFIER_LIST - ATTRIBUTE_ANNOTATION - PsiElement(LBRACKET)('[') - ATTRIBUTE - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('a') - PsiElement(RBRACKET)(']') - PsiWhiteSpace(' ') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('a') + VALUE_PARAMETER + MODIFIER_LIST + ATTRIBUTE_ANNOTATION + PsiElement(LBRACKET)('[') + ATTRIBUTE + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') + PsiElement(RBRACKET)(']') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') PsiElement(RPAR)(')') PsiErrorElement:Expecting ':' followed by a return type @@ -52,10 +53,11 @@ JetFile: FunctionTypes_ERR.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('a') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') PsiElement(COMMA)(',') PsiErrorElement:Expecting a parameter declaration diff --git a/idea/testData/psi/Functions.txt b/idea/testData/psi/Functions.txt index a7d98faf586..e114ec07777 100644 --- a/idea/testData/psi/Functions.txt +++ b/idea/testData/psi/Functions.txt @@ -83,18 +83,19 @@ JetFile: Functions.jet PsiElement(DOT)('.') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('A') - TYPE_ARGUMENT_LIST - PsiElement(LT)('<') - TYPE_PROJECTION - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('B') - PsiElement(GT)('>') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('A') + TYPE_ARGUMENT_LIST + PsiElement(LT)('<') + TYPE_PROJECTION + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('B') + PsiElement(GT)('>') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -185,10 +186,11 @@ JetFile: Functions.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('a') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -305,18 +307,19 @@ JetFile: Functions.jet PsiElement(DOT)('.') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('A') - TYPE_ARGUMENT_LIST - PsiElement(LT)('<') - TYPE_PROJECTION - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('B') - PsiElement(GT)('>') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('A') + TYPE_ARGUMENT_LIST + PsiElement(LT)('<') + TYPE_PROJECTION + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('B') + PsiElement(GT)('>') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -409,10 +412,11 @@ JetFile: Functions.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('a') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -539,18 +543,19 @@ JetFile: Functions.jet PsiElement(DOT)('.') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('A') - TYPE_ARGUMENT_LIST - PsiElement(LT)('<') - TYPE_PROJECTION - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('B') - PsiElement(GT)('>') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('A') + TYPE_ARGUMENT_LIST + PsiElement(LT)('<') + TYPE_PROJECTION + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('B') + PsiElement(GT)('>') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -649,10 +654,11 @@ JetFile: Functions.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('a') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -726,18 +732,19 @@ JetFile: Functions.jet PsiElement(DOT)('.') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('A') - TYPE_ARGUMENT_LIST - PsiElement(LT)('<') - TYPE_PROJECTION - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('B') - PsiElement(GT)('>') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('A') + TYPE_ARGUMENT_LIST + PsiElement(LT)('<') + TYPE_PROJECTION + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('B') + PsiElement(GT)('>') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -801,10 +808,11 @@ JetFile: Functions.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('a') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') diff --git a/idea/testData/psi/Functions_ERR.txt b/idea/testData/psi/Functions_ERR.txt index a036db94587..7846fa530be 100644 --- a/idea/testData/psi/Functions_ERR.txt +++ b/idea/testData/psi/Functions_ERR.txt @@ -109,10 +109,11 @@ JetFile: Functions_ERR.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('a') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -416,18 +417,19 @@ JetFile: Functions_ERR.jet PsiElement(DOT)('.') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('A') - TYPE_ARGUMENT_LIST - PsiElement(LT)('<') - TYPE_PROJECTION - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('B') - PsiElement(GT)('>') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('A') + TYPE_ARGUMENT_LIST + PsiElement(LT)('<') + TYPE_PROJECTION + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('B') + PsiElement(GT)('>') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') diff --git a/idea/testData/psi/When.txt b/idea/testData/psi/When.txt index ad3df326c9b..e75b2d4e637 100644 --- a/idea/testData/psi/When.txt +++ b/idea/testData/psi/When.txt @@ -746,10 +746,11 @@ JetFile: When.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('foo') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') diff --git a/idea/testData/psi/examples/FunctionsAndTypes.txt b/idea/testData/psi/examples/FunctionsAndTypes.txt index c18937fb4f3..04d65ce6475 100644 --- a/idea/testData/psi/examples/FunctionsAndTypes.txt +++ b/idea/testData/psi/examples/FunctionsAndTypes.txt @@ -14,10 +14,11 @@ JetFile: FunctionsAndTypes.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('T') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -44,16 +45,18 @@ JetFile: FunctionsAndTypes.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('T') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') PsiElement(COMMA)(',') PsiWhiteSpace(' ') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('E') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('E') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -80,20 +83,21 @@ JetFile: FunctionsAndTypes.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - TUPLE_TYPE - PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('T') - PsiElement(COMMA)(',') - PsiWhiteSpace(' ') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('E') - PsiElement(RPAR)(')') + VALUE_PARAMETER + TYPE_REFERENCE + TUPLE_TYPE + PsiElement(LPAR)('(') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('E') + PsiElement(RPAR)(')') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -121,10 +125,11 @@ JetFile: FunctionsAndTypes.jet PsiWhiteSpace(' ') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('X') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('X') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -134,10 +139,11 @@ JetFile: FunctionsAndTypes.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('T') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -167,24 +173,26 @@ JetFile: FunctionsAndTypes.jet PsiWhiteSpace(' ') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - FUNCTION_TYPE - PsiElement(LBRACE)('{') - VALUE_PARAMETER_LIST - PsiElement(LPAR)('(') + VALUE_PARAMETER + TYPE_REFERENCE + FUNCTION_TYPE + PsiElement(LBRACE)('{') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('X') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') TYPE_REFERENCE USER_TYPE REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('X') - PsiElement(RPAR)(')') - PsiWhiteSpace(' ') - PsiElement(COLON)(':') - PsiWhiteSpace(' ') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('Y') - PsiElement(RBRACE)('}') + PsiElement(IDENTIFIER)('Y') + PsiElement(RBRACE)('}') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -194,10 +202,11 @@ JetFile: FunctionsAndTypes.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('Y') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Y') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -643,10 +652,11 @@ JetFile: FunctionsAndTypes.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('T') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') diff --git a/idea/testData/psi/examples/Graph.txt b/idea/testData/psi/examples/Graph.txt index b93472549d9..a49150b0b73 100644 --- a/idea/testData/psi/examples/Graph.txt +++ b/idea/testData/psi/examples/Graph.txt @@ -494,10 +494,11 @@ JetFile: Graph.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('V') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('V') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -641,10 +642,11 @@ JetFile: Graph.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('V') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('V') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -812,10 +814,11 @@ JetFile: Graph.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('V') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('V') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') diff --git a/idea/testData/psi/examples/PolymorphicClassObjects.txt b/idea/testData/psi/examples/PolymorphicClassObjects.txt index 69b20bb7424..4b3ed00c572 100644 --- a/idea/testData/psi/examples/PolymorphicClassObjects.txt +++ b/idea/testData/psi/examples/PolymorphicClassObjects.txt @@ -299,10 +299,11 @@ JetFile: PolymorphicClassObjects.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('E') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('E') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') diff --git a/idea/testData/psi/examples/util/Comparison.txt b/idea/testData/psi/examples/util/Comparison.txt index 1cf766c984d..17b612fe76f 100644 --- a/idea/testData/psi/examples/util/Comparison.txt +++ b/idea/testData/psi/examples/util/Comparison.txt @@ -20,16 +20,18 @@ JetFile: Comparison.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('T') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') PsiElement(COMMA)(',') PsiWhiteSpace(' ') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('T') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -254,16 +256,18 @@ JetFile: Comparison.jet PsiElement(LBRACE)('{') VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('T') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') PsiElement(COMMA)(',') PsiWhiteSpace(' ') - TYPE_REFERENCE - USER_TYPE - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('T') + VALUE_PARAMETER + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(COLON)(':') diff --git a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java index 94010565f52..7d32f7033da 100644 --- a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java +++ b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java @@ -274,6 +274,28 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase { assertType("for (i in 1) {1}", "Unit"); } + public void testFunctionLiterals() throws Exception { + assertType("{() => }", "{() : Unit}"); + assertType("{() : Int => }", "{() : Int}"); + assertType("{() => 1}", "{() : Int}"); + + assertType("{(a : Int) => 1}", "{(a : Int) : Int}"); + assertType("{(a : Int, b : String) => 1}", "{(a : Int, b : String) : Int}"); + + assertType("{(a : Int) => 1}", "{(Int) : Int}"); + assertType("{(a : Int, b : String) => 1}", "{(Int, String) : Int}"); + + assertType("{Any.() => 1}", "{Any.() : Int}"); + + assertType("{Any.(a : Int) => 1}", "{Any.(a : Int) : Int}"); + assertType("{Any.(a : Int, b : String) => 1}", "{Any.(a : Int, b : String) : Int}"); + + assertType("{Any.(a : Int) => 1}", "{Any.(Int) : Int}"); + assertType("{Any.(a : Int, b : String) => 1}", "{Any.(Int, String) : Int}"); + + assertType("{Any.(a : Int, b : String) => b}", "{Any.(Int, String) : String}"); + } + public void testImplicitConversions() throws Exception { assertConvertibleTo("1", JetStandardClasses.getByteType()); }