diff --git a/grammar/src/class.grm b/grammar/src/class.grm index 2559c40e02e..e94fdfecd12 100644 --- a/grammar/src/class.grm +++ b/grammar/src/class.grm @@ -14,14 +14,11 @@ class : modifiers "class" SimpleName typeParameters? "wraps"? - primaryConstructorParameters? + valueParameters? (":" attributes delegationSpecifier{","})? (classBody? | enumClassBody) ; -primaryConstructorParameters - : "(" primaryConstructorParameter{","} ")" - ; typeParameters : "<" typeParameter{","} ">" @@ -48,8 +45,4 @@ typeParameter typeConstraint : userType ":" type : "class" "object" userType ":" type - ; - -primaryConstructorParameter - : modifiers ("val" | "var")? functionParameterRest ; \ No newline at end of file diff --git a/grammar/src/class_members.grm b/grammar/src/class_members.grm index b3dc38fe885..7f8bdabc1e0 100644 --- a/grammar/src/class_members.grm +++ b/grammar/src/class_members.grm @@ -54,11 +54,7 @@ functionParameters ; functionParameter - : modifiers functionParameterRest - ; - -functionParameterRest - : parameter ("=" expression)? + : modifiers ("val" | "var")? parameter ("=" expression)? ; initializer diff --git a/idea/src/org/jetbrains/jet/JetNodeTypes.java b/idea/src/org/jetbrains/jet/JetNodeTypes.java index 46ac6280193..18565905b46 100644 --- a/idea/src/org/jetbrains/jet/JetNodeTypes.java +++ b/idea/src/org/jetbrains/jet/JetNodeTypes.java @@ -30,9 +30,6 @@ public interface JetNodeTypes { JetNodeType DELEGATOR_SUPER_CLASS = new JetNodeType("DELEGATOR_SUPER_CLASS", JetDelegatorToSuperClass.class); JetNodeType VALUE_PARAMETER_LIST = new JetNodeType("VALUE_PARAMETER_LIST", JetParameterList.class); JetNodeType VALUE_PARAMETER = new JetNodeType("VALUE_PARAMETER", JetParameter.class); - // TODO: Not sure if we really need separate PSI nodes for the class parameters? - JetNodeType PRIMARY_CONSTRUCTOR_PARAMETERS_LIST = new JetNodeType("PRIMARY_CONSTRUCTOR_PARAMETERS_LIST", JetParameterList.class); - JetNodeType PRIMARY_CONSTRUCTOR_PARAMETER = new JetNodeType("PRIMARY_CONSTRUCTOR_PARAMETER", JetParameter.class); JetNodeType CLASS_BODY = new JetNodeType("CLASS_BODY", JetClassBody.class); JetNodeType IMPORT_DIRECTIVE = new JetNodeType("IMPORT_DIRECTIVE", JetImportDirective.class); diff --git a/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java b/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java index e789d8d5e32..4d2ae02a97c 100644 --- a/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java +++ b/idea/src/org/jetbrains/jet/lang/parsing/JetParsing.java @@ -386,7 +386,7 @@ public class JetParsing extends AbstractJetParsing { consumeIf(WRAPS_KEYWORD); if (at(LPAR)) { - parsePrimaryConstructorParameterList(); + parseValueParameterList(false, TokenSet.EMPTY); } if (at(COLON)) { @@ -464,8 +464,7 @@ public class JetParsing extends AbstractJetParsing { parseTypeParameterList(TokenSet.create(COLON, LPAR, SEMICOLON, LBRACE)); if (at(LPAR)) { - parsePrimaryConstructorParameterList(); -// parseValueParameterList(false, TokenSet.create(COLON, SEMICOLON, LBRACE)); + parseValueParameterList(false, TokenSet.create(COLON, SEMICOLON, LBRACE)); } if (at(COLON)) { @@ -1008,72 +1007,6 @@ public class JetParsing extends AbstractJetParsing { while (at(LBRACKET)) parseAttributeAnnotation(); } - /* - * ("(" primaryConstructorParameter{","} ")") - */ - private void parsePrimaryConstructorParameterList() { - assert _at(LPAR); - PsiBuilder.Marker cons = mark(); - - myBuilder.disableNewlines(); - advance(); // LPAR - - while (true) { - parsePrimaryConstructorParameter(); - if (!at(COMMA)) break; - advance(); // COMMA - } - - expect(RPAR, "')' expected"); - myBuilder.restoreNewlinesState(); - - cons.done(PRIMARY_CONSTRUCTOR_PARAMETERS_LIST); - } - - /* - * primaryConstructorParameter - * : modifiers ("val" | "var")? functionParameterRest - * ; - */ - private void parsePrimaryConstructorParameter() { - PsiBuilder.Marker param = mark(); - - int lastId = findLastBefore(TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, RPAR, COLON), false); - createTruncatedBuilder(lastId).parseModifierList(); - - if (at(VAR_KEYWORD) || at(VAL_KEYWORD)) { - advance(); // VAR_KEYWORD | VAL_KEYWORD - } - - parseFunctionParameterRest(); - - param.done(PRIMARY_CONSTRUCTOR_PARAMETER); - } - - /* - * functionParameterRest - * : parameter ("=" expression)? - * ; - */ - private boolean parseFunctionParameterRest() { - expect(IDENTIFIER, "Parameter name expected", PARAMETER_NAME_RECOVERY_SET); - - if (at(COLON)) { - advance(); // COLON - parseTypeRef(); - } - else { - error("Parameters must have type annotation"); - return false; - } - - if (at(EQ)) { - advance(); // EQ - myExpressionParsing.parseExpression(); - } - return true; - } - /* * typeParameters * : ("<" typeParameter{","} ">" @@ -1443,16 +1376,28 @@ public class JetParsing extends AbstractJetParsing { /* * functionParameter - * : modifiers functionParameterRest + * : modifiers ("val" | "var")? parameter ("=" expression)? * ; */ private boolean tryParseValueParameter() { + return parseValueParameter(true); + } + + private void parseValueParameter() { + parseValueParameter(false); + } + + private boolean parseValueParameter(boolean rollbackOnFailure) { PsiBuilder.Marker parameter = mark(); int lastId = findLastBefore(TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, RPAR, COLON), false); createTruncatedBuilder(lastId).parseModifierList(); - if (!parseFunctionParameterRest()) { + if (at(VAR_KEYWORD) || at(VAL_KEYWORD)) { + advance(); // VAR_KEYWORD | VAL_KEYWORD + } + + if (!parseFunctionParameterRest() && rollbackOnFailure) { parameter.rollbackTo(); return false; } @@ -1462,19 +1407,27 @@ public class JetParsing extends AbstractJetParsing { } /* - * functionParameter - * : modifiers functionParameterRest + * functionParameterRest + * : parameter ("=" expression)? * ; */ - private void parseValueParameter() { - PsiBuilder.Marker parameter = mark(); + private boolean parseFunctionParameterRest() { + expect(IDENTIFIER, "Parameter name expected", PARAMETER_NAME_RECOVERY_SET); - int lastId = findLastBefore(TokenSet.create(IDENTIFIER), TokenSet.create(COMMA, RPAR, COLON), false); - createTruncatedBuilder(lastId).parseModifierList(); + if (at(COLON)) { + advance(); // COLON + parseTypeRef(); + } + else { + error("Parameters must have type annotation"); + return false; + } - parseFunctionParameterRest(); - - parameter.done(VALUE_PARAMETER); + if (at(EQ)) { + advance(); // EQ + myExpressionParsing.parseExpression(); + } + return true; } @Override diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetConstructor.java b/idea/src/org/jetbrains/jet/lang/psi/JetConstructor.java index 88ef96e8bb5..df6251706cb 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetConstructor.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetConstructor.java @@ -11,7 +11,7 @@ import java.util.List; /** * @author max */ -public class JetConstructor extends JetDeclaration { +public class JetConstructor extends JetDeclaration implements JetDeclarationWithBody { public JetConstructor(@NotNull ASTNode node) { super(node); } @@ -42,4 +42,9 @@ public class JetConstructor extends JetDeclaration { JetInitializerList list = getInitializerList(); return list != null ? list.getInitializers() : Collections.emptyList(); } + + @Override + public JetExpression getBodyExpression() { + return findChildByClass(JetExpression.class); + } } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetDeclarationWithBody.java b/idea/src/org/jetbrains/jet/lang/psi/JetDeclarationWithBody.java new file mode 100644 index 00000000000..072acf8ba84 --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/psi/JetDeclarationWithBody.java @@ -0,0 +1,12 @@ +package org.jetbrains.jet.lang.psi; + +import org.jetbrains.annotations.Nullable; + +/** + * @author abreslav + */ +public interface JetDeclarationWithBody { + + @Nullable + JetExpression getBodyExpression(); +} diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetFunction.java b/idea/src/org/jetbrains/jet/lang/psi/JetFunction.java index eeddef516c7..6ad6045afc8 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetFunction.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetFunction.java @@ -14,7 +14,7 @@ import java.util.List; /** * @author max */ -public class JetFunction extends JetTypeParameterListOwner { +public class JetFunction extends JetTypeParameterListOwner implements JetDeclarationWithBody { public JetFunction(@NotNull ASTNode node) { super(node); } @@ -35,6 +35,7 @@ public class JetFunction extends JetTypeParameterListOwner { return list != null ? list.getParameters() : Collections.emptyList(); } + @Override @Nullable public JetExpression getBodyExpression() { return findChildByClass(JetExpression.class); diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetParameter.java b/idea/src/org/jetbrains/jet/lang/psi/JetParameter.java index 00819e39abb..31262d052dc 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetParameter.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetParameter.java @@ -39,13 +39,28 @@ public class JetParameter extends JetNamedDeclaration { return null; } - public boolean isOut() { - JetModifierList modifierList = getModifierList(); - return modifierList != null && modifierList.hasModifier(JetTokens.OUT_KEYWORD); + public boolean isRef() { + ASTNode refNode = getRefNode(); + return refNode != null; } - public boolean isRef() { + @Nullable + public ASTNode getRefNode() { JetModifierList modifierList = getModifierList(); - return modifierList != null && modifierList.hasModifier(JetTokens.REF_KEYWORD); + return modifierList == null ? null : modifierList.getModifierNode(JetTokens.REF_KEYWORD); } + + public boolean isMutable() { + return findChildByType(JetTokens.VAR_KEYWORD) != null || isRef(); + } + + @Nullable + public ASTNode getValOrVarNode() { + ASTNode val = getNode().findChildByType(JetTokens.VAL_KEYWORD); + if (val != null) return val; + + return getNode().findChildByType(JetTokens.VAR_KEYWORD); + } + + } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java index 163122ab009..c29d77d17ab 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java @@ -1,5 +1,6 @@ package org.jetbrains.jet.lang.resolve; +import com.intellij.lang.ASTNode; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.JetSemanticServices; @@ -66,7 +67,6 @@ public class ClassDescriptorResolver { WritableScope parameterScope = descriptor.getUnsubstitutedMemberScope(); - // This call has side-effects on the parameterScope (fills it in) List typeParameters = resolveTypeParameters(descriptor, parameterScope, classElement.getTypeParameters()); @@ -193,6 +193,11 @@ public class ClassDescriptorResolver { JetParameter valueParameter = valueParameters.get(i); JetTypeReference typeReference = valueParameter.getTypeReference(); + ASTNode valOrVarNode = valueParameter.getValOrVarNode(); + if (valueParameter.isRef() && valOrVarNode != null) { + semanticServices.getErrorHandler().genericError(valOrVarNode, "'val' and 'var' are not allowed on ref-parameters"); + } + String name = valueParameter.getName(); JetType type; if (typeReference == null) { @@ -206,6 +211,7 @@ public class ClassDescriptorResolver { i, AttributeResolver.INSTANCE.resolveAttributes(valueParameter.getModifierList()), name == null ? "" : name, + valueParameter.isMutable() ? type : null, type, valueParameter.getDefaultValue() != null, false // TODO : varargs @@ -264,25 +270,33 @@ public class ClassDescriptorResolver { } @NotNull - public PropertyDescriptor resolvePropertyDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope scope, @NotNull JetParameter parameter) { + public PropertyDescriptor resolveValueParameterDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope scope, @NotNull JetParameter parameter) { + JetType type = getParameterType(scope, parameter); + return resolveValueParameterDescriptor(containingDeclaration, parameter, type); + } + + private JetType getParameterType(JetScope scope, JetParameter parameter) { JetTypeReference typeReference = parameter.getTypeReference(); JetType type; if (typeReference != null) { type = typeResolver.resolveType(scope, typeReference); } else { + // Error is reported by the parser type = ErrorType.createErrorType("Annotation is absent"); } - return resolvePropertyDescriptor(containingDeclaration, parameter, type); + return type; } - public PropertyDescriptor resolvePropertyDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetParameter parameter, @NotNull JetType type) { - return new PropertyDescriptorImpl( + public PropertyDescriptor resolveValueParameterDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetParameter parameter, @NotNull JetType type) { + PropertyDescriptor propertyDescriptor = new PropertyDescriptorImpl( containingDeclaration, AttributeResolver.INSTANCE.resolveAttributes(parameter.getModifierList()), parameter.getName(), - type, // TODO + parameter.isMutable() ? null : type, type); + trace.recordDeclarationResolution(parameter, propertyDescriptor); + return propertyDescriptor; } public PropertyDescriptor resolvePropertyDescriptor(@NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope scope, JetProperty property) { @@ -303,12 +317,14 @@ public class ClassDescriptorResolver { type = typeResolver.resolveType(scope, propertyTypeRef); } - return new PropertyDescriptorImpl( + PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorImpl( containingDeclaration, AttributeResolver.INSTANCE.resolveAttributes(property.getModifierList()), property.getName(), property.isVar() ? type : null, type); + trace.recordDeclarationResolution(property, propertyDescriptor); + return propertyDescriptor; } @NotNull @@ -357,4 +373,20 @@ public class ClassDescriptorResolver { else return null; } } + + public PropertyDescriptor resolvePrimaryConstructorParameterToAProperty( + @NotNull ClassDescriptor classDescriptor, + @NotNull JetScope scope, + @NotNull JetParameter parameter) { + JetType type = getParameterType(scope, parameter); + String name = parameter.getName(); + PropertyDescriptorImpl propertyDescriptor = new PropertyDescriptorImpl( + classDescriptor, + AttributeResolver.INSTANCE.resolveAttributes(parameter.getModifierList()), + name == null ? "" : name, + parameter.isMutable() ? type : null, + type); + trace.recordDeclarationResolution(parameter, propertyDescriptor); + return propertyDescriptor; + } } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java index 8b5c6fb3b3b..167541b1852 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java @@ -14,7 +14,7 @@ public class TopDownAnalyzer { private final Map classes = new LinkedHashMap(); private final Map namespaceScopes = new LinkedHashMap(); - private final Map functions = new HashMap(); + private final Map functions = new HashMap(); private final Map declaringScopes = new HashMap(); private final JetSemanticServices semanticServices; @@ -142,8 +142,8 @@ public class TopDownAnalyzer { @Override public void visitClass(JetClass klass) { MutableClassDescriptor mutableClassDescriptor = classes.get(klass); - processBehaviorDeclarators(mutableClassDescriptor.getUnsubstitutedMemberScope(), klass.getDeclarations()); processPrimaryConstructor(mutableClassDescriptor, klass); + processBehaviorDeclarators(mutableClassDescriptor.getUnsubstitutedMemberScope(), klass.getDeclarations()); } @Override @@ -189,14 +189,28 @@ public class TopDownAnalyzer { } private void processPrimaryConstructor(MutableClassDescriptor classDescriptor, JetClass klass) { - ConstructorDescriptor constructorDescriptor = classDescriptorResolver.resolvePrimaryConstructor(classDescriptor.getUnsubstitutedMemberScope(), classDescriptor, klass); + // TODO : not all the parameters are real properties + WritableScope memberScope = classDescriptor.getUnsubstitutedMemberScope(); // TODO : this is REALLY questionable + ConstructorDescriptor constructorDescriptor = classDescriptorResolver.resolvePrimaryConstructor(memberScope, classDescriptor, klass); + for (JetParameter parameter : klass.getPrimaryConstructorParameters()) { + PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolvePrimaryConstructorParameterToAProperty( + classDescriptor, + memberScope, + parameter + ); + memberScope.addPropertyDescriptor( + propertyDescriptor); + } if (constructorDescriptor != null) { classDescriptor.addConstructor(constructorDescriptor); } } private void processConstructor(MutableClassDescriptor classDescriptor, JetConstructor constructor) { - classDescriptor.addConstructor(classDescriptorResolver.resolveConstructorDescriptor(classDescriptor.getUnsubstitutedMemberScope(), classDescriptor, constructor, false)); + ConstructorDescriptor constructorDescriptor = classDescriptorResolver.resolveConstructorDescriptor(classDescriptor.getUnsubstitutedMemberScope(), classDescriptor, constructor, false); + classDescriptor.addConstructor(constructorDescriptor); + functions.put(constructor, constructorDescriptor); + declaringScopes.put(constructor, classDescriptor.getUnsubstitutedMemberScope()); } private void processFunction(@NotNull WritableScope declaringScope, JetFunction function) { @@ -211,7 +225,6 @@ public class TopDownAnalyzer { declaringScopes.put(property, declaringScope); PropertyDescriptor descriptor = classDescriptorResolver.resolvePropertyDescriptor(declaringScope.getContainingDeclaration(), declaringScope, property); declaringScope.addPropertyDescriptor(descriptor); - trace.recordDeclarationResolution(property, descriptor); } private void processClassObject(JetClassObject classObject) { @@ -221,11 +234,11 @@ public class TopDownAnalyzer { //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private void resolveBehaviorDeclarationBodies() { - for (Map.Entry entry : functions.entrySet()) { - JetFunction function = entry.getKey(); + for (Map.Entry entry : functions.entrySet()) { + JetDeclaration declarations = entry.getKey(); FunctionDescriptor descriptor = entry.getValue(); - WritableScope declaringScope = declaringScopes.get(function); + WritableScope declaringScope = declaringScopes.get(declarations); assert declaringScope != null; WritableScope parameterScope = semanticServices.createWritableScope(declaringScope, descriptor); @@ -236,7 +249,8 @@ public class TopDownAnalyzer { parameterScope.addPropertyDescriptor(valueParameterDescriptor); } - JetExpression bodyExpression = function.getBodyExpression(); + assert declarations instanceof JetFunction || declarations instanceof JetConstructor; + JetExpression bodyExpression = ((JetDeclarationWithBody) declarations).getBodyExpression(); if (bodyExpression != null) { resolveExpression(parameterScope, bodyExpression, true); } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java index 85119b43225..87556345e83 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/java/JavaDescriptorResolver.java @@ -163,6 +163,7 @@ public class JavaDescriptorResolver { i, Collections.emptyList(), // TODO name == null ? "p" + i : name, + null, // TODO : review semanticServices.getTypeTransformer().transform(parameter.getType()), false, parameter.isVarArgs() diff --git a/idea/src/org/jetbrains/jet/lang/types/ErrorType.java b/idea/src/org/jetbrains/jet/lang/types/ErrorType.java index 17679c5f6f0..e4d196ed7f0 100644 --- a/idea/src/org/jetbrains/jet/lang/types/ErrorType.java +++ b/idea/src/org/jetbrains/jet/lang/types/ErrorType.java @@ -111,16 +111,17 @@ public class ErrorType { ); } + private static final JetType ERROR_PARAMETER_TYPE = createErrorType(""); private static List getValueParameters(FunctionDescriptor functionDescriptor, List argumentTypes) { List result = new ArrayList(); for (int i = 0, argumentTypesSize = argumentTypes.size(); i < argumentTypesSize; i++) { - JetType argumentType = argumentTypes.get(i); result.add(new ValueParameterDescriptorImpl( functionDescriptor, i, Collections.emptyList(), "", - createErrorType(""), + ERROR_PARAMETER_TYPE, + ERROR_PARAMETER_TYPE, false, false)); } diff --git a/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorUtil.java b/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorUtil.java index 1ff52c1f332..98e36cc61cd 100644 --- a/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorUtil.java +++ b/idea/src/org/jetbrains/jet/lang/types/FunctionDescriptorUtil.java @@ -68,6 +68,7 @@ public class FunctionDescriptorUtil { i, unsubstitutedValueParameter.getAttributes(), unsubstitutedValueParameter.getName(), + unsubstitutedValueParameter.getInType() == null ? null : substitutedType, substitutedType, unsubstitutedValueParameter.hasDefaultValue(), unsubstitutedValueParameter.isVararg() diff --git a/idea/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java b/idea/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java index b95fd2b6502..ca0fe0f7066 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetStandardLibrary.java @@ -28,7 +28,6 @@ public class JetStandardLibrary { // TODO : consider releasing this memory private static final Map standardLibraryCache = new HashMap(); - public static JetStandardLibrary getJetStandardLibrary(@NotNull Project project) { JetStandardLibrary standardLibrary = standardLibraryCache.get(project); if (standardLibrary == null) { @@ -39,6 +38,7 @@ public class JetStandardLibrary { } private final JetScope libraryScope; + private final ClassDescriptor byteClass; private final ClassDescriptor charClass; private final ClassDescriptor shortClass; @@ -50,8 +50,8 @@ public class JetStandardLibrary { private final ClassDescriptor stringClass; private final ClassDescriptor arrayClass; private final ClassDescriptor iterableClass; - private final JetType byteType; + private final JetType charType; private final JetType shortType; private final JetType intType; @@ -60,6 +60,7 @@ public class JetStandardLibrary { private final JetType doubleType; private final JetType booleanType; private final JetType stringType; + private final JetType nullableStringType; private JetStandardLibrary(@NotNull Project project) { // TODO : review @@ -98,6 +99,7 @@ public class JetStandardLibrary { this.doubleType = new JetTypeImpl(getDouble()); this.booleanType = new JetTypeImpl(getBoolean()); this.stringType = new JetTypeImpl(getString()); + this.nullableStringType = TypeUtils.makeNullable(stringType); } catch (IOException e) { throw new IllegalStateException(e); } @@ -236,4 +238,8 @@ public class JetStandardLibrary { getIterable().getMemberScope(types) ); } + + public JetType getNullableStringType() { + return nullableStringType; + } } diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index 5961cc51a7a..fb791d2a240 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -378,7 +378,7 @@ public class JetTypeInferrer { if (typeReference == null) { throw new UnsupportedOperationException("Type inference for parameters is not implemented yet"); } - PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolvePropertyDescriptor(functionDescriptor, scope, parameter); + PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolveValueParameterDescriptor(functionDescriptor, scope, parameter); parameterDescriptors.put(parameter.getName(), propertyDescriptor); parameterTypes.add(propertyDescriptor.getOutType()); } @@ -644,7 +644,7 @@ public class JetTypeInferrer { JetTypeReference typeReference = loopParameter.getTypeReference(); PropertyDescriptor propertyDescriptor; if (typeReference != null) { - propertyDescriptor = semanticServices.getClassDescriptorResolver(trace).resolvePropertyDescriptor(scope.getContainingDeclaration(), scope, loopParameter); + propertyDescriptor = semanticServices.getClassDescriptorResolver(trace).resolveValueParameterDescriptor(scope.getContainingDeclaration(), scope, loopParameter); JetType actualParameterType = propertyDescriptor.getOutType(); if (expectedParameterType != null && !semanticServices.getTypeChecker().isSubtypeOf(expectedParameterType, actualParameterType)) { @@ -655,10 +655,9 @@ public class JetTypeInferrer { if (expectedParameterType == null) { expectedParameterType = ErrorType.createErrorType("Error"); } - propertyDescriptor = semanticServices.getClassDescriptorResolver(trace).resolvePropertyDescriptor(scope.getContainingDeclaration(), loopParameter, expectedParameterType); + propertyDescriptor = semanticServices.getClassDescriptorResolver(trace).resolveValueParameterDescriptor(scope.getContainingDeclaration(), loopParameter, expectedParameterType); } loopScope.addPropertyDescriptor(propertyDescriptor); - trace.recordDeclarationResolution(loopParameter, propertyDescriptor); JetExpression body = expression.getBody(); if (body != null) { @@ -783,6 +782,9 @@ public class JetTypeInferrer { else { result = selectorReturnType; } + if (selectorExpression != null && result != null) { + trace.recordExpressionType(selectorExpression, result); + } } } @@ -798,7 +800,7 @@ public class JetTypeInferrer { } else if (selectorExpression != null) { // TODO : not a simple name -> resolve in scope, expect property type or a function type - throw new UnsupportedOperationException(); + semanticServices.getErrorHandler().genericError(selectorExpression.getNode(), "Unsupported selector expression type: " + selectorExpression); } return receiverType; } @@ -1121,7 +1123,6 @@ public class JetTypeInferrer { } scope.addPropertyDescriptor(propertyDescriptor); - trace.recordDeclarationResolution(property, propertyDescriptor); } @Override diff --git a/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptor.java index 4acbd9028bd..b2168a6729c 100644 --- a/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptor.java @@ -7,13 +7,20 @@ import org.jetbrains.annotations.Nullable; * @author abreslav */ public interface PropertyDescriptor extends DeclarationDescriptor { + /** + * @return null for write-only variables (i.e. properties), variable value type otherwise + */ @Nullable JetType getOutType(); + /** + * @return null for read-only variables (i.e. val's etc), or the type expected on assignment type otherwise + */ @Nullable JetType getInType(); @Override + @SuppressWarnings({"NullableProblems"}) @NotNull DeclarationDescriptor getContainingDeclaration(); } diff --git a/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptorImpl.java b/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptorImpl.java index 3a2ec60813a..4147cf7e815 100644 --- a/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptorImpl.java +++ b/idea/src/org/jetbrains/jet/lang/types/PropertyDescriptorImpl.java @@ -25,6 +25,7 @@ public class PropertyDescriptorImpl extends DeclarationDescriptorImpl implements this.outType = outType; } + @NotNull @Override public JetType getOutType() { return outType; diff --git a/idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptor.java index e974bc3f69f..c7fb22bf6cf 100644 --- a/idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptor.java @@ -1,5 +1,7 @@ package org.jetbrains.jet.lang.types; +import org.jetbrains.annotations.NotNull; + /** * @author abreslav */ @@ -13,4 +15,8 @@ public interface ValueParameterDescriptor extends PropertyDescriptor { boolean hasDefaultValue(); boolean isRef(); boolean isVararg(); + + @Override + @NotNull + JetType getOutType(); } diff --git a/idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptorImpl.java b/idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptorImpl.java index bcdc79fbd58..20cbb4f89d6 100644 --- a/idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptorImpl.java +++ b/idea/src/org/jetbrains/jet/lang/types/ValueParameterDescriptorImpl.java @@ -1,6 +1,7 @@ package org.jetbrains.jet.lang.types; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -17,10 +18,11 @@ public class ValueParameterDescriptorImpl extends PropertyDescriptorImpl impleme int index, @NotNull List attributes, @NotNull String name, - @NotNull JetType type, + @Nullable JetType inType, + @NotNull JetType outType, boolean hasDefaultValue, boolean isVararg) { - super(containingDeclaration, attributes, name, type, type); // TODO : writable? + super(containingDeclaration, attributes, name, inType, outType); this.index = index; this.hasDefaultValue = hasDefaultValue; this.isVararg = isVararg; diff --git a/idea/testData/psi/BabySteps.txt b/idea/testData/psi/BabySteps.txt index eef0e542f6f..0d6f0b46e64 100644 --- a/idea/testData/psi/BabySteps.txt +++ b/idea/testData/psi/BabySteps.txt @@ -17,9 +17,9 @@ JetFile: BabySteps.jet TYPE_PARAMETER PsiElement(IDENTIFIER)('a') PsiElement(GT)('>') - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('a') PsiWhiteSpace(' ') PsiElement(COLON)(':') diff --git a/idea/testData/psi/BabySteps_ERR.txt b/idea/testData/psi/BabySteps_ERR.txt index 2ebdf887013..3e73733e1f6 100644 --- a/idea/testData/psi/BabySteps_ERR.txt +++ b/idea/testData/psi/BabySteps_ERR.txt @@ -17,9 +17,9 @@ JetFile: BabySteps_ERR.jet TYPE_PARAMETER PsiElement(IDENTIFIER)('a') PsiElement(GT)('>') - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('a') PsiWhiteSpace(' ') PsiElement(COLON)(':') diff --git a/idea/testData/psi/Enums.txt b/idea/testData/psi/Enums.txt index 29d64a81b01..1561c6bd500 100644 --- a/idea/testData/psi/Enums.txt +++ b/idea/testData/psi/Enums.txt @@ -9,9 +9,9 @@ JetFile: Enums.jet PsiElement(IDENTIFIER)('Color') TYPE_PARAMETER_LIST - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(val)('val') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('rgb') @@ -104,9 +104,9 @@ JetFile: Enums.jet PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('T') PsiElement(GT)('>') - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(val)('val') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('size') @@ -157,9 +157,9 @@ JetFile: Enums.jet TYPE_PARAMETER PsiElement(IDENTIFIER)('T') PsiElement(GT)('>') - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(val)('val') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('value') @@ -172,7 +172,7 @@ JetFile: Enums.jet PsiElement(IDENTIFIER)('T') PsiElement(COMMA)(',') PsiWhiteSpace(' ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(val)('val') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('tail') diff --git a/idea/testData/psi/SoftKeywords.txt b/idea/testData/psi/SoftKeywords.txt index 5132ef60e70..3089e4e29d3 100644 --- a/idea/testData/psi/SoftKeywords.txt +++ b/idea/testData/psi/SoftKeywords.txt @@ -125,9 +125,9 @@ JetFile: SoftKeywords.jet PsiWhiteSpace(' ') PsiElement(wraps)('wraps') PsiWhiteSpace(' ') - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('a') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1045,9 +1045,9 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('F') TYPE_PARAMETER_LIST - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(val)('val') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('foo') @@ -1060,7 +1060,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('bar') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('abstract') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1071,7 +1071,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('virtual') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1082,7 +1082,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('enum') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1093,7 +1093,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('open') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1104,7 +1104,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('attribute') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1115,7 +1115,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('override') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1126,7 +1126,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('virtual') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1137,7 +1137,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('abstract') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1148,7 +1148,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('private') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1159,7 +1159,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('protected') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1170,7 +1170,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('public') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1181,7 +1181,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('internal') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1192,7 +1192,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('lazy') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1203,7 +1203,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('wraps') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1214,7 +1214,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('import') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1225,7 +1225,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('where') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1236,7 +1236,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('by') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1247,7 +1247,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('get') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1258,7 +1258,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('set') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1269,7 +1269,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('public') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1280,7 +1280,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('private') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1291,7 +1291,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('protected') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1302,7 +1302,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('internal') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -1313,7 +1313,7 @@ JetFile: SoftKeywords.jet PsiElement(IDENTIFIER)('t') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER MODIFIER_LIST PsiElement(public)('public') PsiWhiteSpace(' ') diff --git a/idea/testData/psi/ThisType.txt b/idea/testData/psi/ThisType.txt index 878ae5222f7..91e8a1667bb 100644 --- a/idea/testData/psi/ThisType.txt +++ b/idea/testData/psi/ThisType.txt @@ -23,9 +23,9 @@ JetFile: ThisType.jet PsiElement(This)('This') PsiElement(GT)('>') PsiElement(GT)('>') - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('a') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -35,7 +35,7 @@ JetFile: ThisType.jet PsiElement(This)('This') PsiElement(COMMA)(',') PsiWhiteSpace(' ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('b') PsiWhiteSpace(' ') PsiElement(COLON)(':') diff --git a/idea/testData/psi/TupleTypes.txt b/idea/testData/psi/TupleTypes.txt index d3d8b45a411..b4cccf85d44 100644 --- a/idea/testData/psi/TupleTypes.txt +++ b/idea/testData/psi/TupleTypes.txt @@ -6,10 +6,10 @@ JetFile: TupleTypes.jet PsiElement(IDENTIFIER)('F') TYPE_PARAMETER_LIST - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('a') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -20,7 +20,7 @@ JetFile: TupleTypes.jet PsiElement(RPAR)(')') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('x') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -35,7 +35,7 @@ JetFile: TupleTypes.jet PsiElement(RPAR)(')') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('b') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -56,7 +56,7 @@ JetFile: TupleTypes.jet PsiElement(RPAR)(')') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('c') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -87,7 +87,7 @@ JetFile: TupleTypes.jet PsiElement(RPAR)(')') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('a') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -107,7 +107,7 @@ JetFile: TupleTypes.jet PsiElement(RPAR)(')') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('x') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -139,7 +139,7 @@ JetFile: TupleTypes.jet PsiElement(RPAR)(')') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('b') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -186,7 +186,7 @@ JetFile: TupleTypes.jet PsiElement(RPAR)(')') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('c') PsiWhiteSpace(' ') PsiElement(COLON)(':') diff --git a/idea/testData/psi/TupleTypes_ERR.txt b/idea/testData/psi/TupleTypes_ERR.txt index 45f46071744..199bc4f5f11 100644 --- a/idea/testData/psi/TupleTypes_ERR.txt +++ b/idea/testData/psi/TupleTypes_ERR.txt @@ -6,10 +6,10 @@ JetFile: TupleTypes_ERR.jet PsiElement(IDENTIFIER)('F') TYPE_PARAMETER_LIST - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('a') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -20,7 +20,7 @@ JetFile: TupleTypes_ERR.jet PsiElement(RPAR)(')') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('x') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -35,7 +35,7 @@ JetFile: TupleTypes_ERR.jet PsiElement(RPAR)(')') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('b') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -54,7 +54,7 @@ JetFile: TupleTypes_ERR.jet PsiElement(RPAR)(')') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('c') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -82,7 +82,7 @@ JetFile: TupleTypes_ERR.jet PsiElement(RPAR)(')') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('a') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -102,7 +102,7 @@ JetFile: TupleTypes_ERR.jet PsiElement(RPAR)(')') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('x') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -135,7 +135,7 @@ JetFile: TupleTypes_ERR.jet PsiElement(RPAR)(')') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('b') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -182,7 +182,7 @@ JetFile: TupleTypes_ERR.jet PsiElement(RPAR)(')') PsiElement(COMMA)(',') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('c') PsiWhiteSpace(' ') PsiElement(COLON)(':') diff --git a/idea/testData/psi/TypeAnnotations.txt b/idea/testData/psi/TypeAnnotations.txt index a5eb40f6240..275436d5eb3 100644 --- a/idea/testData/psi/TypeAnnotations.txt +++ b/idea/testData/psi/TypeAnnotations.txt @@ -6,9 +6,9 @@ JetFile: TypeAnnotations.jet PsiElement(IDENTIFIER)('F') TYPE_PARAMETER_LIST - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('a') PsiWhiteSpace(' ') PsiElement(COLON)(':') diff --git a/idea/testData/psi/examples/BinaryTree.txt b/idea/testData/psi/examples/BinaryTree.txt index 603279aa00c..c6dc2d925f5 100644 --- a/idea/testData/psi/examples/BinaryTree.txt +++ b/idea/testData/psi/examples/BinaryTree.txt @@ -39,10 +39,10 @@ JetFile: BinaryTree.jet PsiElement(IDENTIFIER)('TreeNode') TYPE_PARAMETER_LIST - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') PsiWhiteSpace('\n ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(var)('var') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('value') @@ -55,7 +55,7 @@ JetFile: BinaryTree.jet PsiElement(IDENTIFIER)('T') PsiElement(COMMA)(',') PsiWhiteSpace(' ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(var)('var') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('parent') diff --git a/idea/testData/psi/examples/Color.txt b/idea/testData/psi/examples/Color.txt index dc9fe8234db..3db50d7b082 100644 --- a/idea/testData/psi/examples/Color.txt +++ b/idea/testData/psi/examples/Color.txt @@ -9,9 +9,9 @@ JetFile: Color.jet PsiElement(IDENTIFIER)('Color') TYPE_PARAMETER_LIST - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(val)('val') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('r') @@ -24,7 +24,7 @@ JetFile: Color.jet PsiElement(IDENTIFIER)('Int') PsiElement(COMMA)(',') PsiWhiteSpace(' ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(val)('val') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('g') @@ -37,7 +37,7 @@ JetFile: Color.jet PsiElement(IDENTIFIER)('Int') PsiElement(COMMA)(',') PsiWhiteSpace(' ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(val)('val') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('sb') diff --git a/idea/testData/psi/examples/Graph.txt b/idea/testData/psi/examples/Graph.txt index e9adffcd011..5a316d9f1e0 100644 --- a/idea/testData/psi/examples/Graph.txt +++ b/idea/testData/psi/examples/Graph.txt @@ -9,9 +9,9 @@ JetFile: Graph.jet TYPE_PARAMETER PsiElement(IDENTIFIER)('V') PsiElement(GT)('>') - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(val)('val') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('data') @@ -37,9 +37,9 @@ JetFile: Graph.jet TYPE_PARAMETER PsiElement(IDENTIFIER)('E') PsiElement(GT)('>') - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(val)('val') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('from') @@ -52,7 +52,7 @@ JetFile: Graph.jet PsiElement(IDENTIFIER)('V') PsiElement(COMMA)(',') PsiWhiteSpace(' ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(val)('val') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('data') @@ -65,7 +65,7 @@ JetFile: Graph.jet PsiElement(IDENTIFIER)('E') PsiElement(COMMA)(',') PsiWhiteSpace(' ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(val)('val') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('to') diff --git a/idea/testData/psi/examples/Queue.txt b/idea/testData/psi/examples/Queue.txt index 03cef38354f..1bb353e1472 100644 --- a/idea/testData/psi/examples/Queue.txt +++ b/idea/testData/psi/examples/Queue.txt @@ -42,9 +42,9 @@ JetFile: Queue.jet TYPE_PARAMETER PsiElement(IDENTIFIER)('T') PsiElement(GT)('>') - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(val)('val') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('data') @@ -57,7 +57,7 @@ JetFile: Queue.jet PsiElement(IDENTIFIER)('T') PsiElement(COMMA)(',') PsiWhiteSpace(' ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(var)('var') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('next') diff --git a/idea/testData/psi/examples/UpdateOperation.txt b/idea/testData/psi/examples/UpdateOperation.txt index fd391ea9a4c..548c5ccaa7b 100644 --- a/idea/testData/psi/examples/UpdateOperation.txt +++ b/idea/testData/psi/examples/UpdateOperation.txt @@ -6,9 +6,9 @@ JetFile: UpdateOperation.jet PsiElement(IDENTIFIER)('Pair') TYPE_PARAMETER_LIST - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('x') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -19,7 +19,7 @@ JetFile: UpdateOperation.jet PsiElement(IDENTIFIER)('Int') PsiElement(COMMA)(',') PsiWhiteSpace(' ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('y') PsiWhiteSpace(' ') PsiElement(COLON)(':') diff --git a/idea/testData/psi/examples/collections/HashMap.txt b/idea/testData/psi/examples/collections/HashMap.txt index 122d5e6ca75..7db05a17816 100644 --- a/idea/testData/psi/examples/collections/HashMap.txt +++ b/idea/testData/psi/examples/collections/HashMap.txt @@ -314,9 +314,9 @@ JetFile: HashMap.jet PsiElement(wraps)('wraps') PsiWhiteSpace(' ') - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(val)('val') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('obj') @@ -915,9 +915,9 @@ JetFile: HashMap.jet TYPE_PARAMETER PsiElement(IDENTIFIER)('V') PsiElement(GT)('>') - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('hashingStrategy') PsiWhiteSpace(' ') PsiElement(COLON)(':') diff --git a/idea/testData/psi/examples/collections/LinkedList.txt b/idea/testData/psi/examples/collections/LinkedList.txt index 9cc1d6bf7da..2200108b8fc 100644 --- a/idea/testData/psi/examples/collections/LinkedList.txt +++ b/idea/testData/psi/examples/collections/LinkedList.txt @@ -39,9 +39,9 @@ JetFile: LinkedList.jet PsiElement(IDENTIFIER)('Item') TYPE_PARAMETER_LIST - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(var)('var') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('value') diff --git a/idea/testData/psi/examples/collections/List.txt b/idea/testData/psi/examples/collections/List.txt index 3477235ebf8..89215e8c7d8 100644 --- a/idea/testData/psi/examples/collections/List.txt +++ b/idea/testData/psi/examples/collections/List.txt @@ -15,9 +15,9 @@ JetFile: List.jet PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('T') PsiElement(GT)('>') - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('theSize') PsiWhiteSpace(' ') PsiElement(COLON)(':') @@ -83,9 +83,9 @@ JetFile: List.jet TYPE_PARAMETER PsiElement(IDENTIFIER)('T') PsiElement(GT)('>') - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(val)('val') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('value') @@ -98,7 +98,7 @@ JetFile: List.jet PsiElement(IDENTIFIER)('T') PsiElement(COMMA)(',') PsiWhiteSpace(' ') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(val)('val') PsiWhiteSpace(' ') PsiElement(IDENTIFIER)('tail') diff --git a/idea/testData/psi/examples/io/IOSamples.txt b/idea/testData/psi/examples/io/IOSamples.txt index 357540231e9..84763c47bb1 100644 --- a/idea/testData/psi/examples/io/IOSamples.txt +++ b/idea/testData/psi/examples/io/IOSamples.txt @@ -81,9 +81,9 @@ JetFile: IOSamples.jet PsiElement(IDENTIFIER)('JavaCloseableWrapper') TYPE_PARAMETER_LIST - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('closeable') PsiWhiteSpace(' ') PsiElement(COLON)(':') diff --git a/idea/testData/psi/examples/priorityqueues/PriorityQueueAsPushPop.txt b/idea/testData/psi/examples/priorityqueues/PriorityQueueAsPushPop.txt index 118d1a95e02..f0c3416c583 100644 --- a/idea/testData/psi/examples/priorityqueues/PriorityQueueAsPushPop.txt +++ b/idea/testData/psi/examples/priorityqueues/PriorityQueueAsPushPop.txt @@ -11,9 +11,9 @@ JetFile: PriorityQueueAsPushPop.jet PsiElement(GT)('>') PsiWhiteSpace(' ') PsiElement(wraps)('wraps') - PRIMARY_CONSTRUCTOR_PARAMETERS_LIST + VALUE_PARAMETER_LIST PsiElement(LPAR)('(') - PRIMARY_CONSTRUCTOR_PARAMETER + VALUE_PARAMETER PsiElement(IDENTIFIER)('wrapped') PsiWhiteSpace(' ') PsiElement(COLON)(':') diff --git a/idea/testData/resolve/PrimaryConstructors.jet b/idea/testData/resolve/PrimaryConstructors.jet new file mode 100644 index 00000000000..978919dc874 --- /dev/null +++ b/idea/testData/resolve/PrimaryConstructors.jet @@ -0,0 +1,12 @@ +class A(~a~val a : Int) { + this() {`a`a} + ~b~val b = `a`a + ~f~fun f() = `a`a +} + +fun test() { + ~va~val a = new A() + `va`a.`a`a`:std::Int` + a.`b`b`:std::Int` + a.`f`f()`:std::Int` +} diff --git a/idea/testData/resolve/ResolveToJava.jet b/idea/testData/resolve/ResolveToJava.jet index 798db5c9be8..379371816ef 100644 --- a/idea/testData/resolve/ResolveToJava.jet +++ b/idea/testData/resolve/ResolveToJava.jet @@ -16,7 +16,7 @@ fun foo(o : `java::java.lang.Object`Object, l : `java::java.util`util.`java::jav class B : `java::java.lang.Object`Object { fun bar(~o~o : `java::java.lang.Object`Object) { - `java::java.lang.System`System.`java::java.lang.System.out`out.`java::java.io.PrintStream.print(Object)`print(`o`o) + `java::java.lang.System`System.`java::java.lang.System.out`out.`java::java.io.PrintStream.print(Object)`print(`o`o)`:std::Unit` } fun f(a : `java::java.util`util.`java::java.util.List`List) {} diff --git a/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java b/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java index 4164a38e86b..124f2818fdf 100644 --- a/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java +++ b/idea/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java @@ -108,16 +108,9 @@ public class ExpectedResolveData { if ("!".equals(name)) { JetReferenceExpression referenceExpression = PsiTreeUtil.getParentOfType(element, JetReferenceExpression.class); - JetExpression statement = referenceExpression; - while (true) { - PsiElement parent = statement.getParent(); - if (!(parent instanceof JetExpression)) break; - if (parent instanceof JetBlockExpression) break; - statement = (JetExpression) parent; - } assertTrue( - "Must have been unresolved: " + referenceExpression.getText() + - " in " + statement.getText() + + "Must have been unresolved: " + + renderReferenceInContext(referenceExpression) + " but was resolved to " + DescriptorUtil.renderPresentableText(bindingContext.resolveReferenceExpression(referenceExpression)), unresolvedReferences.contains(referenceExpression)); continue; @@ -157,7 +150,7 @@ public class ExpectedResolveData { } assertNotNull(reference); assertSame( - "Reference `" + name + "`" + reference.getText() + " at " + reference.getTextOffset() + " is resolved into " + actualName + ".", + "Reference `" + name + "`" + renderReferenceInContext(reference) + " is resolved into " + actualName + ".", expected, actual); } @@ -196,12 +189,25 @@ public class ExpectedResolveData { } } - assertNotNull(expression.getText(), expressionType); + assertNotNull(expression.getText() + " type is null", expressionType); assertSame("At " + position + ": ", expectedTypeConstructor, expressionType.getConstructor()); } } - private T getAncestorOfType(Class type, PsiElement element) { + private static String renderReferenceInContext(JetReferenceExpression referenceExpression) { + JetExpression statement = referenceExpression; + while (true) { + PsiElement parent = statement.getParent(); + if (!(parent instanceof JetExpression)) break; + if (parent instanceof JetBlockExpression) break; + statement = (JetExpression) parent; + } + JetDeclaration declaration = PsiTreeUtil.getParentOfType(referenceExpression, JetDeclaration.class); + return referenceExpression.getText() + + " in " + statement.getText() + (declaration == null ? "" : " in " + declaration.getText()); + } + + private static T getAncestorOfType(Class type, PsiElement element) { while (element != null && !type.isInstance(element)) { element = element.getParent(); } diff --git a/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java b/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java index ab7f5fad3fc..bc8ae6d1bb6 100644 --- a/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java +++ b/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java @@ -150,4 +150,8 @@ public class JetResolveTest extends ExtensibleResolveTestCase { doTest("/resolve/Projections.jet", true, true); } + public void testPrimaryConstructors() throws Exception { + doTest("/resolve/PrimaryConstructors.jet", true, true); + } + } \ No newline at end of file