diff --git a/idea/src/jet/lang/Library.jet b/idea/src/jet/lang/Library.jet index 5eb208ecee7..2ebdea6d192 100644 --- a/idea/src/jet/lang/Library.jet +++ b/idea/src/jet/lang/Library.jet @@ -5,39 +5,58 @@ class Array { fun set(index : Int, value : T) : Unit } -class Boolean { +virtual class Comparable { + fun compareTo(other : T) : Int } -class String { +class Boolean : Comparable { + fun not() : Boolean +} + +class String : Comparable { fun get(index : Int) : Char val length : Int fun plus(other : Any?) : String } -class Double { +class Double : Comparable { fun plus(other : Double) : Double } -class Float { +class Float : Comparable { + fun compareTo(other : Double) : Int + fun plus(other : Double) : Double fun plus(other : Float) : Float } -class Long { +class Long : Comparable { + fun compareTo(other : Double) : Int + fun compareTo(other : Float) : Int + fun plus(other : Double) : Double fun plus(other : Float) : Float fun plus(other : Long) : Long } -class Int { +class Int : Comparable { + fun compareTo(other : Double) : Int + fun compareTo(other : Float) : Int + fun compareTo(other : Long) : Int + fun plus(other : Double) : Double fun plus(other : Float) : Float fun plus(other : Long) : Long fun plus(other : Int) : Int } -class Char { +class Char : Comparable { + fun compareTo(other : Double) : Int + fun compareTo(other : Float) : Int + fun compareTo(other : Long) : Int + fun compareTo(other : Int) : Int + fun plus(other : Double) : Double fun plus(other : Float) : Float fun plus(other : Long) : Long @@ -45,7 +64,12 @@ class Char { fun plus(other : Char) : Char } -class Short { +class Short : Comparable { + fun compareTo(other : Double) : Int + fun compareTo(other : Float) : Int + fun compareTo(other : Long) : Int + fun compareTo(other : Int) : Int + fun plus(other : Double) : Double fun plus(other : Float) : Float fun plus(other : Long) : Long @@ -53,7 +77,13 @@ class Short { fun plus(other : Short) : Short } -class Byte { +class Byte : Comparable { + fun compareTo(other : Double) : Int + fun compareTo(other : Float) : Int + fun compareTo(other : Long) : Int + fun compareTo(other : Int) : Int + fun compareTo(other : Short) : Int + fun plus(other : Double) : Double fun plus(other : Float) : Float fun plus(other : Long) : Long diff --git a/idea/src/org/jetbrains/jet/lang/annotations/LabelsAnnotator.java b/idea/src/org/jetbrains/jet/lang/annotations/LabelsAnnotator.java index 61b74f9b175..7a0b0748282 100644 --- a/idea/src/org/jetbrains/jet/lang/annotations/LabelsAnnotator.java +++ b/idea/src/org/jetbrains/jet/lang/annotations/LabelsAnnotator.java @@ -17,9 +17,9 @@ public class LabelsAnnotator implements Annotator { element.accept(new JetVisitor() { @Override public void visitPrefixExpression(JetPrefixExpression expression) { - ASTNode operationTokenNode = expression.getOperationTokenNode(); - if (JetTokens.LABELS.contains(operationTokenNode.getElementType())) { - holder.createInfoAnnotation(operationTokenNode, null).setTextAttributes(JetHighlighter.JET_LABEL_IDENTIFIER); + JetSimpleNameExpression operationSign = expression.getOperationSign(); + if (JetTokens.LABELS.contains(operationSign.getReferencedNameElementType())) { + holder.createInfoAnnotation(operationSign, null).setTextAttributes(JetHighlighter.JET_LABEL_IDENTIFIER); } } diff --git a/idea/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java b/idea/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java index 788fbafc10d..ec09f5af435 100644 --- a/idea/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java +++ b/idea/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java @@ -263,9 +263,7 @@ public class JetExpressionParsing extends AbstractJetParsing { while (!myBuilder.newlineBeforeCurrentToken() && atSet(precedence.getOperations())) { IElementType operation = tt(); - PsiBuilder.Marker operationReference = mark(); - advance(); // operation - operationReference.done(OPERATION_REFERENCE); + parseOperationReference(); JetNodeType resultType = precedence.parseRightHandSide(operation, this); expression.done(resultType); @@ -291,7 +289,8 @@ public class JetExpressionParsing extends AbstractJetParsing { } } else if (atSet(Precedence.PREFIX.getOperations())) { PsiBuilder.Marker expression = mark(); - advance(); // operation + + parseOperationReference(); parsePrefixExpression(); expression.done(PREFIX_EXPRESSION); @@ -323,7 +322,7 @@ public class JetExpressionParsing extends AbstractJetParsing { parseArrayAccess(); expression.done(ARRAY_ACCESS_EXPRESSION); } else if (atSet(Precedence.POSTFIX.getOperations())) { - advance(); // operation + parseOperationReference(); expression.done(POSTFIX_EXPRESSION); } else if (parseCallWithClosure()) { parseCallWithClosure(); @@ -380,6 +379,12 @@ public class JetExpressionParsing extends AbstractJetParsing { expression.drop(); } + private void parseOperationReference() { + PsiBuilder.Marker operationReference = mark(); + advance(); // operation + operationReference.done(OPERATION_REFERENCE); + } + /* * expression (label? functionLiteral)? */ diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetNamedDeclaration.java b/idea/src/org/jetbrains/jet/lang/psi/JetNamedDeclaration.java index 50951009916..1fb42c41916 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetNamedDeclaration.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetNamedDeclaration.java @@ -40,7 +40,9 @@ public abstract class JetNamedDeclaration extends JetDeclaration implements PsiN @Override public TextRange getRangeInElement() { - return getElement().getTextRange().shiftRight(getElement().getTextOffset()); + PsiElement element = getElement(); + if (element == null) return null; + return element.getTextRange().shiftRight(element.getTextOffset()); } @Override diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetPostfixExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetPostfixExpression.java index fde399bebd5..2afe27991c1 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetPostfixExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetPostfixExpression.java @@ -2,9 +2,7 @@ package org.jetbrains.jet.lang.psi; import com.intellij.lang.ASTNode; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lexer.JetToken; -import org.jetbrains.jet.lexer.JetTokens; +import org.jetbrains.jet.JetNodeTypes; /** * @author max @@ -27,14 +25,7 @@ public class JetPostfixExpression extends JetExpression { } @NotNull - public ASTNode getOperationTokenNode() { - ASTNode operationNode = getNode().findChildByType(JetTokens.OPERATIONS); - assert operationNode != null; - return operationNode; - } - - @Nullable - public JetToken getOperationSign() { - return (JetToken) getOperationTokenNode().getElementType(); + public JetSimpleNameExpression getOperationSign() { + return (JetSimpleNameExpression) findChildByType(JetNodeTypes.OPERATION_REFERENCE); } } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetPrefixExpression.java b/idea/src/org/jetbrains/jet/lang/psi/JetPrefixExpression.java index caaef63eef2..60ffd310fd3 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetPrefixExpression.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetPrefixExpression.java @@ -1,9 +1,9 @@ package org.jetbrains.jet.lang.psi; import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lexer.JetToken; -import org.jetbrains.jet.lexer.JetTokens; +import org.jetbrains.jet.JetNodeTypes; /** * @author max @@ -20,20 +20,16 @@ public class JetPrefixExpression extends JetExpression { @NotNull public JetExpression getBaseExpression() { - JetExpression answer = findChildByClass(JetExpression.class); - assert answer != null; - return answer; + PsiElement expression = getOperationSign().getNextSibling(); + while (expression != null && false == expression instanceof JetExpression) { + expression = expression.getNextSibling(); + } + assert expression != null; + return (JetExpression) expression; } @NotNull - public ASTNode getOperationTokenNode() { - ASTNode operationNode = getNode().findChildByType(JetTokens.OPERATIONS); - assert operationNode != null; - return operationNode; - } - - @NotNull - public JetToken getOperationSign() { - return (JetToken) getOperationTokenNode().getElementType(); + public JetSimpleNameExpression getOperationSign() { + return (JetSimpleNameExpression) findChildByType(JetNodeTypes.OPERATION_REFERENCE); } } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java index 362b07bb968..2f81285e463 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java @@ -61,22 +61,33 @@ public class ClassDescriptorResolver { List typeParameters = resolveTypeParameters(descriptor, parameterScope, classElement.getTypeParameters()); + boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD); + List supertypes = new ArrayList(); + TypeConstructorImpl typeConstructor = new TypeConstructorImpl( + descriptor, + AttributeResolver.INSTANCE.resolveAttributes(classElement.getModifierList()), + !open, + classElement.getName(), + typeParameters, + supertypes); + descriptor.setTypeConstructor( + typeConstructor + ); + List delegationSpecifiers = classElement.getDelegationSpecifiers(); // TODO : assuming that the hierarchy is acyclic Collection superclasses = delegationSpecifiers.isEmpty() ? Collections.singleton(JetStandardClasses.getAnyType()) : resolveTypes(parameterScope, delegationSpecifiers); - boolean open = classElement.hasModifier(JetTokens.OPEN_KEYWORD); - descriptor.setTypeConstructor( - new TypeConstructor( - descriptor, - AttributeResolver.INSTANCE.resolveAttributes(classElement.getModifierList()), - !open, - classElement.getName(), - typeParameters, - superclasses) - ); + // TODO : UGLY HACK + supertypes.addAll(superclasses); + + + // TODO : importing may be a bad idea + for (JetType supertype : superclasses) { + parameterScope.importScope(supertype.getMemberScope()); + } trace.recordDeclarationResolution(classElement, descriptor); } diff --git a/idea/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java b/idea/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java index d0f6551a337..8f5b0bab5c5 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/java/JavaClassMembersScope.java @@ -32,7 +32,13 @@ public class JavaClassMembersScope implements JetScope { @Override public ClassDescriptor getClass(@NotNull String name) { - throw new UnsupportedOperationException(); // TODO + for (PsiClass innerClass : psiClass.getAllInnerClasses()) { + if (name.equals(innerClass.getName())) { + if (innerClass.hasModifierProperty(PsiModifier.STATIC) != staticMembers) return null; + return semanticServices.getDescriptorResolver().resolveClass(innerClass); + } + } + return null; } @Override diff --git a/idea/src/org/jetbrains/jet/lang/types/ClassDescriptorImpl.java b/idea/src/org/jetbrains/jet/lang/types/ClassDescriptorImpl.java index af7d0c4fefd..eec0c493bb1 100644 --- a/idea/src/org/jetbrains/jet/lang/types/ClassDescriptorImpl.java +++ b/idea/src/org/jetbrains/jet/lang/types/ClassDescriptorImpl.java @@ -33,7 +33,7 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl public final ClassDescriptorImpl initialize(boolean sealed, List typeParameters, Collection superclasses, JetScope memberDeclarations) { - this.typeConstructor = new TypeConstructor(this, getAttributes(), sealed, getName(), typeParameters, superclasses); + this.typeConstructor = new TypeConstructorImpl(this, getAttributes(), sealed, getName(), typeParameters, superclasses); this.memberDeclarations = memberDeclarations; return this; } diff --git a/idea/src/org/jetbrains/jet/lang/types/ErrorType.java b/idea/src/org/jetbrains/jet/lang/types/ErrorType.java index 2cd67569608..cb59e76d75e 100644 --- a/idea/src/org/jetbrains/jet/lang/types/ErrorType.java +++ b/idea/src/org/jetbrains/jet/lang/types/ErrorType.java @@ -63,7 +63,7 @@ public class ErrorType { } private static JetType createErrorType(String debugMessage, JetScope memberScope) { - return new ErrorTypeImpl(new TypeConstructor(null, Collections.emptyList(), false, "[ERROR : " + debugMessage + "]", Collections.emptyList(), Collections.emptyList()), memberScope); + return new ErrorTypeImpl(new TypeConstructorImpl(null, Collections.emptyList(), false, "[ERROR : " + debugMessage + "]", Collections.emptyList(), Collections.emptyList()), memberScope); } public static JetType createWrongVarianceErrorType(TypeProjection value) { diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java index 2efdb8b32b3..0c50773a7bd 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java @@ -39,399 +39,13 @@ public class JetTypeInferrer { @Nullable public JetType getType(@NotNull final JetScope scope, @NotNull JetExpression expression, final boolean preferBlock) { - final JetType[] result = new JetType[1]; - expression.accept(new JetVisitor() { - @Override - public void visitReferenceExpression(JetSimpleNameExpression expression) { - // TODO : other members - // TODO : type substitutions??? - String referencedName = expression.getReferencedName(); - PropertyDescriptor property = scope.getProperty(referencedName); - if (property != null) { - trace.recordReferenceResolution(expression, property); - result[0] = property.getType(); - return; - } else { - NamespaceDescriptor namespace = scope.getNamespace(referencedName); - if (namespace != null) { - trace.recordReferenceResolution(expression, namespace); - result[0] = namespace.getNamespaceType(); - return; - } - } - semanticServices.getErrorHandler().unresolvedReference(expression); - } - - @Override - public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) { - if (preferBlock && !expression.hasParameterSpecification()) { - result[0] = getBlockReturnedType(scope, expression.getBody()); - return; - } - - FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(scope.getContainingDeclaration(), Collections.emptyList(), ""); - - JetTypeReference returnTypeRef = expression.getReturnTypeRef(); - - JetTypeReference receiverTypeRef = expression.getReceiverTypeRef(); - final JetType receiverType; - if (receiverTypeRef != null) { - receiverType = typeResolver.resolveType(scope, receiverTypeRef); - } else { - receiverType = 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.resolvePropertyDescriptor(functionDescriptor, scope, parameter); - parameterDescriptors.put(parameter.getName(), propertyDescriptor); - parameterTypes.add(propertyDescriptor.getType()); - } - JetType returnType; - if (returnTypeRef != null) { - returnType = typeResolver.resolveType(scope, returnTypeRef); - } else { - WritableScope writableScope = new WritableScope(scope, functionDescriptor); - for (PropertyDescriptor propertyDescriptor : parameterDescriptors.values()) { - writableScope.addPropertyDescriptor(propertyDescriptor); - } - writableScope.setThisType(receiverType); - returnType = getBlockReturnedType(writableScope, body); - } - result[0] = JetStandardClasses.getFunctionType(null, receiverTypeRef == null ? null : receiverType, parameterTypes, returnType); - } - - @Override - public void visitParenthesizedExpression(JetParenthesizedExpression expression) { - result[0] = getType(scope, expression.getExpression(), false); - } - - @Override - public void visitConstantExpression(JetConstantExpression expression) { - IElementType elementType = expression.getNode().getElementType(); - JetStandardLibrary standardLibrary = semanticServices.getStandardLibrary(); - if (elementType == JetNodeTypes.INTEGER_CONSTANT) { - result[0] = standardLibrary.getIntType(); - } else if (elementType == JetNodeTypes.LONG_CONSTANT) { - result[0] = standardLibrary.getLongType(); - } 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] = standardLibrary.getFloatType(); - } else { - result[0] = standardLibrary.getDoubleType(); - } - } else if (elementType == JetNodeTypes.BOOLEAN_CONSTANT) { - result[0] = standardLibrary.getBooleanType(); - } else if (elementType == JetNodeTypes.CHARACTER_CONSTANT) { - result[0] = standardLibrary.getCharType(); - } else if (elementType == JetNodeTypes.STRING_CONSTANT) { - result[0] = standardLibrary.getStringType(); - } else if (elementType == JetNodeTypes.NULL) { - result[0] = JetStandardClasses.getNullableNothingType(); - } else { - throw new IllegalArgumentException("Unsupported constant: " + expression); - } - } - - @Override - public void visitThrowExpression(JetThrowExpression expression) { - result[0] = JetStandardClasses.getNothingType(); - } - - @Override - public void visitReturnExpression(JetReturnExpression expression) { - JetExpression returnedExpression = expression.getReturnedExpression(); - if (returnedExpression != null) { - getType(scope, returnedExpression, false); - } - result[0] = JetStandardClasses.getNothingType(); - } - - @Override - public void visitBreakExpression(JetBreakExpression expression) { - result[0] = JetStandardClasses.getNothingType(); - } - - @Override - public void visitContinueExpression(JetContinueExpression expression) { - result[0] = JetStandardClasses.getNothingType(); - } - - @Override - public void visitTypeofExpression(JetTypeofExpression expression) { - throw new UnsupportedOperationException("Return some reflection interface"); // TODO - } - - @Override - public void visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression) { - if (expression.getOperationReference().getReferencedNameElementType() == JetTokens.COLON) { - JetType actualType = getType(scope, expression.getLeft(), false); - JetType expectedType = typeResolver.resolveType(scope, expression.getRight()); - if (actualType != null && !semanticServices.getTypeChecker().isSubtypeOf(actualType, expectedType)) { - // TODO - semanticServices.getErrorHandler().typeMismatch(expression.getLeft(), expectedType, actualType); - } - result[0] = expectedType; - return; - } - throw new UnsupportedOperationException(); // TODO - } - - @Override - public void visitIfExpression(JetIfExpression expression) { - // TODO : check condition type - // TODO : change types according to is and nullability checks - JetExpression elseBranch = expression.getElse(); - if (elseBranch == null) { - // TODO : type-check the branch - result[0] = JetStandardClasses.getUnitType(); - } else { - JetType thenType = getType(scope, expression.getThen(), true); - JetType elseType = getType(scope, elseBranch, true); - result[0] = semanticServices.getTypeChecker().commonSupertype(Arrays.asList(thenType, elseType)); - } - } - - @Override - public void visitWhenExpression(JetWhenExpression expression) { - // TODO :change scope according to the bound value in the when header - List expressions = new ArrayList(); - collectAllReturnTypes(expression, scope, expressions); - result[0] = semanticServices.getTypeChecker().commonSupertype(expressions); - } - - @Override - public void visitTryExpression(JetTryExpression expression) { - JetExpression tryBlock = expression.getTryBlock(); - List catchClauses = expression.getCatchClauses(); - JetFinallySection finallyBlock = expression.getFinallyBlock(); - List types = new ArrayList(); - if (finallyBlock == null) { - for (JetCatchClause catchClause : catchClauses) { - // TODO: change scope here - types.add(getType(scope, catchClause.getCatchBody(), true)); - } - } else { - types.add(getType(scope, finallyBlock.getFinalExpression(), true)); - } - types.add(getType(scope, tryBlock, true)); - result[0] = semanticServices.getTypeChecker().commonSupertype(types); - } - - @Override - public void visitTupleExpression(JetTupleExpression expression) { - List entries = expression.getEntries(); - List types = new ArrayList(); - for (JetExpression entry : entries) { - types.add(getType(scope, entry, false)); - } - // TODO : labels - result[0] = JetStandardClasses.getTupleType(types); - } - - @Override - public void visitThisExpression(JetThisExpression expression) { - // TODO : qualified this, e.g. Foo.this - JetType thisType = scope.getThisType(); - JetTypeReference superTypeQualifier = expression.getSuperTypeQualifier(); - if (superTypeQualifier != null) { - // This cast must be safe (assuming the PSI doesn't contain errors) - JetUserType typeElement = (JetUserType) superTypeQualifier.getTypeElement(); - ClassDescriptor superclass = typeResolver.resolveClass(scope, typeElement); - Collection supertypes = thisType.getConstructor().getSupertypes(); - Map substitutionContext = TypeSubstitutor.INSTANCE.getSubstitutionContext(thisType); - for (JetType declaredSupertype : supertypes) { - if (declaredSupertype.getConstructor().equals(superclass.getTypeConstructor())) { - result[0] = TypeSubstitutor.INSTANCE.substitute(substitutionContext, declaredSupertype, Variance.INVARIANT); - break; - } - } - assert result[0] != null; - } else { - result[0] = thisType; - } - } - - @Override - public void visitBlockExpression(JetBlockExpression expression) { - result[0] = getBlockReturnedType(scope, expression.getStatements()); - } - - @Override - public void visitLoopExpression(JetLoopExpression expression) { - result[0] = JetStandardClasses.getUnitType(); - } - - @Override - public void visitNewExpression(JetNewExpression expression) { - // TODO : type argument inference - JetTypeReference typeReference = expression.getTypeReference(); - result[0] = typeResolver.resolveType(scope, typeReference); - } - - @Override - public void visitDotQualifiedExpression(JetDotQualifiedExpression expression) { - // TODO : functions - JetExpression receiverExpression = expression.getReceiverExpression(); - JetExpression selectorExpression = expression.getSelectorExpression(); - JetType receiverType = getType(scope, receiverExpression, false); - if (receiverType != null) { // TODO : review - JetScope compositeScope = new ScopeWithReceiver(scope, receiverType); - result[0] = getType(compositeScope, selectorExpression, false); - } - } - - @Override - public void visitCallExpression(JetCallExpression expression) { - JetExpression calleeExpression = expression.getCalleeExpression(); - - // 1) ends with a name -> (scope, name) to look up - // 2) ends with something else -> just check types - - // TODO : check somewhere that these are NOT projections - List typeArguments = expression.getTypeArguments(); - - List valueArguments = expression.getValueArguments(); - - boolean someNamed = false; - for (JetArgument argument : valueArguments) { - if (argument.isNamed()) { - someNamed = true; - break; - } - } - List functionLiteralArguments = expression.getFunctionLiteralArguments(); - -// JetExpression functionLiteralArgument = functionLiteralArguments.isEmpty() ? null : functionLiteralArguments.get(0); - // TODO : must be a check - assert functionLiteralArguments.size() <= 1; - - OverloadDomain overloadDomain = getOverloadDomain(scope, calleeExpression); - if (someNamed) { - // TODO : check that all are named - throw new UnsupportedOperationException(); // TODO - -// result[0] = overloadDomain.getFunctionDescriptorForNamedArguments(typeArguments, valueArguments, functionLiteralArgument); - } else { - List types = new ArrayList(); - for (JetTypeProjection projection : typeArguments) { - // TODO : check that there's no projection - types.add(typeResolver.resolveType(scope, projection.getTypeReference())); - } - - List positionedValueArguments = new ArrayList(); - for (JetArgument argument : valueArguments) { - positionedValueArguments.add(argument.getArgumentExpression()); - } - - positionedValueArguments.addAll(functionLiteralArguments); - - List valueArgumentTypes = new ArrayList(); - for (JetExpression valueArgument : positionedValueArguments) { - valueArgumentTypes.add(getType(scope, valueArgument, false)); - } - - FunctionDescriptor functionDescriptor = overloadDomain.getFunctionDescriptorForPositionedArguments(types, valueArgumentTypes); - if (functionDescriptor != null) { - result[0] = functionDescriptor.getUnsubstitutedReturnType(); - } - } - } - - @Override - public void visitBinaryExpression(JetBinaryExpression expression) { - JetSimpleNameExpression operationSign = expression.getOperationReference(); - - IElementType operationType = operationSign.getReferencedNameElementType(); - if (operationType == JetTokens.IDENTIFIER) { - result[0] = getTypeForBinaryCall(expression, operationSign.getReferencedName(), scope); - } - else if (operationType == JetTokens.PLUS) { - result[0] = getTypeForBinaryCall(expression, "plus", scope); - } - else if (operationType == JetTokens.EQ) { - JetExpression left = expression.getLeft(); - JetExpression deparenthesized = deparenthesize(left); - if (deparenthesized instanceof JetArrayAccessExpression) { - JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) deparenthesized; - resolveArrayAccessToLValue(arrayAccessExpression, expression.getRight(), expression.getOperationReference()); - } - else { - getType(scope, expression.getRight(), false); - //throw new UnsupportedOperationException(); - } - result[0] = null; // TODO : This is not an expression, in fact! - } else { - throw new UnsupportedOperationException(); // TODO - } - } - - @Override - public void visitArrayAccessExpression(JetArrayAccessExpression expression) { - JetExpression arrayExpression = expression.getArrayExpression(); - JetType receiverType = getType(scope, arrayExpression, false); - List indexExpressions = expression.getIndexExpressions(); - List argumentTypes = getTypes(scope, indexExpressions); - if (argumentTypes == null) return; - - FunctionDescriptor functionDescriptor = lookupFunction(scope, expression, "get", receiverType, argumentTypes); - if (functionDescriptor != null) { - result[0] = functionDescriptor.getUnsubstitutedReturnType(); - } - } - - private void resolveArrayAccessToLValue(JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide, JetSimpleNameExpression operationSign) { - List argumentTypes = getTypes(scope, arrayAccessExpression.getIndexExpressions()); - if (argumentTypes == null) return; - JetType rhsType = getType(scope, rightHandSide, false); - if (rhsType == null) return; - argumentTypes.add(rhsType); - - JetType receiverType = getType(scope, arrayAccessExpression.getArrayExpression(), false); - if (receiverType == null) return; - - // TODO : nasty hack: effort is duplicated - lookupFunction(scope, arrayAccessExpression, "set", receiverType, argumentTypes); - FunctionDescriptor functionDescriptor = lookupFunction(scope, operationSign, "set", receiverType, argumentTypes); - if (functionDescriptor != null) { - result[0] = functionDescriptor.getUnsubstitutedReturnType(); - } - } - - @Override - public void visitJetElement(JetElement elem) { - throw new IllegalArgumentException("Unsupported element: " + elem); - } - - private JetType getTypeForBinaryCall(JetBinaryExpression expression, String name, JetScope scope) { - JetSimpleNameExpression operationSign = expression.getOperationReference(); - JetExpression left = expression.getLeft(); - JetType leftType = getType(scope, left, false); - JetExpression right = expression.getRight(); - if (right == null) { - return ErrorType.createErrorType("No right argument"); - } - JetType rightType = getType(scope, right, false); - FunctionDescriptor functionDescriptor = lookupFunction(scope, operationSign, name, leftType, Collections.singletonList(rightType)); - if (functionDescriptor != null) { - return functionDescriptor.getUnsubstitutedReturnType(); - } - return null; - } - }); - if (result[0] != null) { - trace.recordExpressionType(expression, result[0]); + TypeInferrerVisitor visitor = new TypeInferrerVisitor(scope, preferBlock); + expression.accept(visitor); + JetType result = visitor.getResult(); + if (result != null) { + trace.recordExpressionType(expression, result); } - return result[0]; + return result; } @NotNull @@ -590,4 +204,472 @@ public class JetTypeInferrer { } } + private class TypeInferrerVisitor extends JetVisitor { + private final JetScope scope; + private JetType result; + private final boolean preferBlock; + + public TypeInferrerVisitor(JetScope scope, boolean preferBlock) { + this.scope = scope; + this.preferBlock = preferBlock; + } + + public JetType getResult() { + return result; + } + + @Override + public void visitReferenceExpression(JetSimpleNameExpression expression) { + // TODO : other members + // TODO : type substitutions??? + String referencedName = expression.getReferencedName(); + PropertyDescriptor property = scope.getProperty(referencedName); + if (property != null) { + trace.recordReferenceResolution(expression, property); + result = property.getType(); + return; + } else { + NamespaceDescriptor namespace = scope.getNamespace(referencedName); + if (namespace != null) { + trace.recordReferenceResolution(expression, namespace); + result = namespace.getNamespaceType(); + return; + } + } + semanticServices.getErrorHandler().unresolvedReference(expression); + } + + @Override + public void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression) { + if (preferBlock && !expression.hasParameterSpecification()) { + result = getBlockReturnedType(scope, expression.getBody()); + return; + } + + FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(scope.getContainingDeclaration(), Collections.emptyList(), ""); + + JetTypeReference returnTypeRef = expression.getReturnTypeRef(); + + JetTypeReference receiverTypeRef = expression.getReceiverTypeRef(); + final JetType receiverType; + if (receiverTypeRef != null) { + receiverType = typeResolver.resolveType(scope, receiverTypeRef); + } else { + receiverType = 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.resolvePropertyDescriptor(functionDescriptor, scope, parameter); + parameterDescriptors.put(parameter.getName(), propertyDescriptor); + parameterTypes.add(propertyDescriptor.getType()); + } + JetType returnType; + if (returnTypeRef != null) { + returnType = typeResolver.resolveType(scope, returnTypeRef); + } else { + WritableScope writableScope = new WritableScope(scope, functionDescriptor); + for (PropertyDescriptor propertyDescriptor : parameterDescriptors.values()) { + writableScope.addPropertyDescriptor(propertyDescriptor); + } + writableScope.setThisType(receiverType); + returnType = getBlockReturnedType(writableScope, body); + } + result = JetStandardClasses.getFunctionType(null, receiverTypeRef == null ? null : receiverType, parameterTypes, returnType); + } + + @Override + public void visitParenthesizedExpression(JetParenthesizedExpression expression) { + result = getType(scope, expression.getExpression(), false); + } + + @Override + public void visitConstantExpression(JetConstantExpression expression) { + IElementType elementType = expression.getNode().getElementType(); + JetStandardLibrary standardLibrary = semanticServices.getStandardLibrary(); + if (elementType == JetNodeTypes.INTEGER_CONSTANT) { + result = standardLibrary.getIntType(); + } else if (elementType == JetNodeTypes.LONG_CONSTANT) { + result = standardLibrary.getLongType(); + } 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 = standardLibrary.getFloatType(); + } else { + result = standardLibrary.getDoubleType(); + } + } else if (elementType == JetNodeTypes.BOOLEAN_CONSTANT) { + result = standardLibrary.getBooleanType(); + } else if (elementType == JetNodeTypes.CHARACTER_CONSTANT) { + result = standardLibrary.getCharType(); + } else if (elementType == JetNodeTypes.STRING_CONSTANT) { + result = standardLibrary.getStringType(); + } else if (elementType == JetNodeTypes.NULL) { + result = JetStandardClasses.getNullableNothingType(); + } else { + throw new IllegalArgumentException("Unsupported constant: " + expression); + } + } + + @Override + public void visitThrowExpression(JetThrowExpression expression) { + result = JetStandardClasses.getNothingType(); + } + + @Override + public void visitReturnExpression(JetReturnExpression expression) { + JetExpression returnedExpression = expression.getReturnedExpression(); + if (returnedExpression != null) { + getType(scope, returnedExpression, false); + } + result = JetStandardClasses.getNothingType(); + } + + @Override + public void visitBreakExpression(JetBreakExpression expression) { + result = JetStandardClasses.getNothingType(); + } + + @Override + public void visitContinueExpression(JetContinueExpression expression) { + result = JetStandardClasses.getNothingType(); + } + + @Override + public void visitTypeofExpression(JetTypeofExpression expression) { + throw new UnsupportedOperationException("Return some reflection interface"); // TODO + } + + @Override + public void visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression) { + if (expression.getOperationReference().getReferencedNameElementType() == JetTokens.COLON) { + JetType actualType = getType(scope, expression.getLeft(), false); + JetType expectedType = typeResolver.resolveType(scope, expression.getRight()); + if (actualType != null && !semanticServices.getTypeChecker().isSubtypeOf(actualType, expectedType)) { + // TODO + semanticServices.getErrorHandler().typeMismatch(expression.getLeft(), expectedType, actualType); + } + result = expectedType; + return; + } + throw new UnsupportedOperationException(); // TODO + } + + @Override + public void visitIfExpression(JetIfExpression expression) { + // TODO : check condition type + // TODO : change types according to is and nullability checks + JetExpression elseBranch = expression.getElse(); + if (elseBranch == null) { + // TODO : type-check the branch + result = JetStandardClasses.getUnitType(); + } else { + JetType thenType = getType(scope, expression.getThen(), true); + JetType elseType = getType(scope, elseBranch, true); + result = semanticServices.getTypeChecker().commonSupertype(Arrays.asList(thenType, elseType)); + } + } + + @Override + public void visitWhenExpression(JetWhenExpression expression) { + // TODO :change scope according to the bound value in the when header + List expressions = new ArrayList(); + collectAllReturnTypes(expression, scope, expressions); + result = semanticServices.getTypeChecker().commonSupertype(expressions); + } + + @Override + public void visitTryExpression(JetTryExpression expression) { + JetExpression tryBlock = expression.getTryBlock(); + List catchClauses = expression.getCatchClauses(); + JetFinallySection finallyBlock = expression.getFinallyBlock(); + List types = new ArrayList(); + if (finallyBlock == null) { + for (JetCatchClause catchClause : catchClauses) { + // TODO: change scope here + types.add(getType(scope, catchClause.getCatchBody(), true)); + } + } else { + types.add(getType(scope, finallyBlock.getFinalExpression(), true)); + } + types.add(getType(scope, tryBlock, true)); + result = semanticServices.getTypeChecker().commonSupertype(types); + } + + @Override + public void visitTupleExpression(JetTupleExpression expression) { + List entries = expression.getEntries(); + List types = new ArrayList(); + for (JetExpression entry : entries) { + types.add(getType(scope, entry, false)); + } + // TODO : labels + result = JetStandardClasses.getTupleType(types); + } + + @Override + public void visitThisExpression(JetThisExpression expression) { + // TODO : qualified this, e.g. Foo.this + JetType thisType = scope.getThisType(); + JetTypeReference superTypeQualifier = expression.getSuperTypeQualifier(); + if (superTypeQualifier != null) { + // This cast must be safe (assuming the PSI doesn't contain errors) + JetUserType typeElement = (JetUserType) superTypeQualifier.getTypeElement(); + ClassDescriptor superclass = typeResolver.resolveClass(scope, typeElement); + Collection supertypes = thisType.getConstructor().getSupertypes(); + Map substitutionContext = TypeSubstitutor.INSTANCE.getSubstitutionContext(thisType); + for (JetType declaredSupertype : supertypes) { + if (declaredSupertype.getConstructor().equals(superclass.getTypeConstructor())) { + result = TypeSubstitutor.INSTANCE.substitute(substitutionContext, declaredSupertype, Variance.INVARIANT); + break; + } + } + assert result != null; + } else { + result = thisType; + } + } + + @Override + public void visitBlockExpression(JetBlockExpression expression) { + result = getBlockReturnedType(scope, expression.getStatements()); + } + + @Override + public void visitLoopExpression(JetLoopExpression expression) { + result = JetStandardClasses.getUnitType(); + } + + @Override + public void visitNewExpression(JetNewExpression expression) { + // TODO : type argument inference + JetTypeReference typeReference = expression.getTypeReference(); + result = typeResolver.resolveType(scope, typeReference); + } + + @Override + public void visitDotQualifiedExpression(JetDotQualifiedExpression expression) { + // TODO : functions + JetExpression receiverExpression = expression.getReceiverExpression(); + JetExpression selectorExpression = expression.getSelectorExpression(); + JetType receiverType = getType(scope, receiverExpression, false); + if (receiverType != null) { // TODO : review + JetScope compositeScope = new ScopeWithReceiver(scope, receiverType); + result = getType(compositeScope, selectorExpression, false); + } + } + + @Override + public void visitCallExpression(JetCallExpression expression) { + JetExpression calleeExpression = expression.getCalleeExpression(); + + // 1) ends with a name -> (scope, name) to look up + // 2) ends with something else -> just check types + + // TODO : check somewhere that these are NOT projections + List typeArguments = expression.getTypeArguments(); + + List valueArguments = expression.getValueArguments(); + + boolean someNamed = false; + for (JetArgument argument : valueArguments) { + if (argument.isNamed()) { + someNamed = true; + break; + } + } + List functionLiteralArguments = expression.getFunctionLiteralArguments(); + +// JetExpression functionLiteralArgument = functionLiteralArguments.isEmpty() ? null : functionLiteralArguments.get(0); + // TODO : must be a check + assert functionLiteralArguments.size() <= 1; + + OverloadDomain overloadDomain = getOverloadDomain(scope, calleeExpression); + if (someNamed) { + // TODO : check that all are named + throw new UnsupportedOperationException(); // TODO + +// result = overloadDomain.getFunctionDescriptorForNamedArguments(typeArguments, valueArguments, functionLiteralArgument); + } else { + List types = new ArrayList(); + for (JetTypeProjection projection : typeArguments) { + // TODO : check that there's no projection + types.add(typeResolver.resolveType(scope, projection.getTypeReference())); + } + + List positionedValueArguments = new ArrayList(); + for (JetArgument argument : valueArguments) { + positionedValueArguments.add(argument.getArgumentExpression()); + } + + positionedValueArguments.addAll(functionLiteralArguments); + + List valueArgumentTypes = new ArrayList(); + for (JetExpression valueArgument : positionedValueArguments) { + valueArgumentTypes.add(getType(scope, valueArgument, false)); + } + + FunctionDescriptor functionDescriptor = overloadDomain.getFunctionDescriptorForPositionedArguments(types, valueArgumentTypes); + if (functionDescriptor != null) { + result = functionDescriptor.getUnsubstitutedReturnType(); + } + } + } + + @Override + public void visitPrefixExpression(JetPrefixExpression expression) { + JetSimpleNameExpression operationSign = expression.getOperationSign(); + if (operationSign.getReferencedNameElementType() == JetTokens.EXCL) { + JetExpression baseExpression = expression.getBaseExpression(); + JetType type = getType(scope, baseExpression, false); + if (type != null) { + FunctionDescriptor functionDescriptor = lookupFunction(scope, operationSign, "not", type, Collections.emptyList()); + if (functionDescriptor != null) { + result = functionDescriptor.getUnsubstitutedReturnType(); + } + } + } + else { + throw new UnsupportedOperationException(); // TODO + } + } + + @Override + public void visitBinaryExpression(JetBinaryExpression expression) { + JetSimpleNameExpression operationSign = expression.getOperationReference(); + + IElementType operationType = operationSign.getReferencedNameElementType(); + if (operationType == JetTokens.IDENTIFIER) { + result = getTypeForBinaryCall(expression, operationSign.getReferencedName(), scope); + } + else if (operationType == JetTokens.PLUS) { + result = getTypeForBinaryCall(expression, "plus", scope); + } + else if (operationType == JetTokens.EQ) { + JetExpression left = expression.getLeft(); + JetExpression deparenthesized = deparenthesize(left); + if (deparenthesized instanceof JetArrayAccessExpression) { + JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) deparenthesized; + resolveArrayAccessToLValue(arrayAccessExpression, expression.getRight(), expression.getOperationReference()); + } + else { + getType(scope, expression.getRight(), false); + //throw new UnsupportedOperationException(); + } + result = null; // TODO : This is not an expression, in fact! + } + else if (operationType == JetTokens.LT) { + JetExpression left = expression.getLeft(); + JetExpression deparenthesized = deparenthesize(left); + if (deparenthesized instanceof JetArrayAccessExpression) { + JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) deparenthesized; + resolveArrayAccessToLValue(arrayAccessExpression, expression.getRight(), expression.getOperationReference()); + } + else { + getType(scope, expression.getRight(), false); + //throw new UnsupportedOperationException(); + } + result = null; // TODO : This is not an expression, in fact! + } else { + throw new UnsupportedOperationException(); // TODO + } + } + + @Override + public void visitArrayAccessExpression(JetArrayAccessExpression expression) { + JetExpression arrayExpression = expression.getArrayExpression(); + JetType receiverType = getType(scope, arrayExpression, false); + List indexExpressions = expression.getIndexExpressions(); + List argumentTypes = getTypes(scope, indexExpressions); + if (argumentTypes == null) return; + + FunctionDescriptor functionDescriptor = lookupFunction(scope, expression, "get", receiverType, argumentTypes); + if (functionDescriptor != null) { + result = functionDescriptor.getUnsubstitutedReturnType(); + } + } + + private void resolveArrayAccessToLValue(JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide, JetSimpleNameExpression operationSign) { + List argumentTypes = getTypes(scope, arrayAccessExpression.getIndexExpressions()); + if (argumentTypes == null) return; + JetType rhsType = getType(scope, rightHandSide, false); + if (rhsType == null) return; + argumentTypes.add(rhsType); + + JetType receiverType = getType(scope, arrayAccessExpression.getArrayExpression(), false); + if (receiverType == null) return; + + // TODO : nasty hack: effort is duplicated + lookupFunction(scope, arrayAccessExpression, "set", receiverType, argumentTypes); + FunctionDescriptor functionDescriptor = lookupFunction(scope, operationSign, "set", receiverType, argumentTypes); + if (functionDescriptor != null) { + result = functionDescriptor.getUnsubstitutedReturnType(); + } + } + + @Override + public void visitJetElement(JetElement elem) { + throw new IllegalArgumentException("Unsupported element: " + elem); + } + + private JetType getTypeForBinaryCall(JetBinaryExpression expression, String name, JetScope scope) { + JetSimpleNameExpression operationSign = expression.getOperationReference(); + JetExpression left = expression.getLeft(); + JetType leftType = getType(scope, left, false); + JetExpression right = expression.getRight(); + if (right == null) { + return ErrorType.createErrorType("No right argument"); // TODO + } + JetType rightType = getType(scope, right, false); + FunctionDescriptor functionDescriptor = lookupFunction(scope, operationSign, name, leftType, Collections.singletonList(rightType)); + if (functionDescriptor != null) { + return functionDescriptor.getUnsubstitutedReturnType(); + } + return null; + } + } + + { + Map operationToMethodName = new HashMap(); + +// operationToMethodName.put(JetTokens.EXCL, "excl"); +// +// operationToMethodName.put(JetTokens.LT, "lt"); +// operationToMethodName.put(JetTokens.GT, "gt"); +// operationToMethodName.put(JetTokens.LTEQ, "lteq"); +// operationToMethodName.put(JetTokens.GTEQ, "gteq"); +// +// operationToMethodName.put(JetTokens.EQEQ, "eqeq"); +// operationToMethodName.put(JetTokens.EXCLEQ, "excleq"); +// +// operationToMethodName.put(JetTokens.MULTEQ, "multeq"); +// operationToMethodName.put(JetTokens.DIVEQ, "diveq"); +// operationToMethodName.put(JetTokens.PERCEQ, "perceq"); +// operationToMethodName.put(JetTokens.PLUSEQ, "pluseq"); +// operationToMethodName.put(JetTokens.MINUSEQ, "minuseq"); +// +// operationToMethodName.put(JetTokens.PLUSPLUS, "plusplus"); +// operationToMethodName.put(JetTokens.MINUSMINUS, "minusminus"); + + operationToMethodName.put(JetTokens.MUL, "times"); + operationToMethodName.put(JetTokens.PLUS, "plus"); + operationToMethodName.put(JetTokens.MINUS, "minus"); + operationToMethodName.put(JetTokens.DIV, "div"); + operationToMethodName.put(JetTokens.PERC, "mod"); + operationToMethodName.put(JetTokens.ARROW, "arrow"); + operationToMethodName.put(JetTokens.RANGE, "rangeTo"); + +// operationToMethodName.put(JetTokens.IN_KEYWORD, "contains"); +// operationToMethodName.put(JetTokens.NOT_IN, "not_in"); + } + + } diff --git a/idea/src/org/jetbrains/jet/lang/types/TypeConstructor.java b/idea/src/org/jetbrains/jet/lang/types/TypeConstructor.java index c49d544d4b4..9af1656205b 100644 --- a/idea/src/org/jetbrains/jet/lang/types/TypeConstructor.java +++ b/idea/src/org/jetbrains/jet/lang/types/TypeConstructor.java @@ -3,58 +3,21 @@ package org.jetbrains.jet.lang.types; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * @author abreslav */ -public class TypeConstructor extends AnnotatedImpl { - private final List parameters; - private final Collection supertypes; - private final String debugName; - private final boolean sealed; - - @Nullable - private final DeclarationDescriptor declarationDescriptor; - - public TypeConstructor( - @Nullable DeclarationDescriptor declarationDescriptor, - @NotNull List attributes, - boolean sealed, - @NotNull String debugName, - @NotNull List parameters, - @NotNull Collection supertypes) { - super(attributes); - this.declarationDescriptor = declarationDescriptor; - this.sealed = sealed; - this.debugName = debugName; - this.parameters = new ArrayList(parameters); - this.supertypes = supertypes; - } +public interface TypeConstructor extends Annotated { + @NotNull + List getParameters(); @NotNull - public List getParameters() { - return parameters; - } + Collection getSupertypes(); - @NotNull - public Collection getSupertypes() { - return supertypes; - } - - @Override - public String toString() { - return debugName; - } - - public boolean isSealed() { - return sealed; - } + boolean isSealed(); @Nullable - public DeclarationDescriptor getDeclarationDescriptor() { - return declarationDescriptor; - } + DeclarationDescriptor getDeclarationDescriptor(); } diff --git a/idea/src/org/jetbrains/jet/lang/types/TypeConstructorImpl.java b/idea/src/org/jetbrains/jet/lang/types/TypeConstructorImpl.java new file mode 100644 index 00000000000..dd810fb4afe --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/types/TypeConstructorImpl.java @@ -0,0 +1,64 @@ +package org.jetbrains.jet.lang.types; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +/** + * @author abreslav + */ +public class TypeConstructorImpl extends AnnotatedImpl implements TypeConstructor { + private final List parameters; + private Collection supertypes; + private final String debugName; + private final boolean sealed; + + @Nullable + private final DeclarationDescriptor declarationDescriptor; + + public TypeConstructorImpl( + @Nullable DeclarationDescriptor declarationDescriptor, + @NotNull List attributes, + boolean sealed, + @NotNull String debugName, + @NotNull List parameters, + @NotNull Collection supertypes) { + super(attributes); + this.declarationDescriptor = declarationDescriptor; + this.sealed = sealed; + this.debugName = debugName; + this.parameters = new ArrayList(parameters); + this.supertypes = supertypes; + } + + @Override + @NotNull + public List getParameters() { + return parameters; + } + + @Override + @NotNull + public Collection getSupertypes() { + return supertypes; + } + + @Override + public String toString() { + return debugName; + } + + @Override + public boolean isSealed() { + return sealed; + } + + @Override + @Nullable + public DeclarationDescriptor getDeclarationDescriptor() { + return declarationDescriptor; + } +} diff --git a/idea/src/org/jetbrains/jet/lang/types/TypeParameterDescriptor.java b/idea/src/org/jetbrains/jet/lang/types/TypeParameterDescriptor.java index f3bfd1da048..fc778a3670a 100644 --- a/idea/src/org/jetbrains/jet/lang/types/TypeParameterDescriptor.java +++ b/idea/src/org/jetbrains/jet/lang/types/TypeParameterDescriptor.java @@ -19,7 +19,7 @@ public class TypeParameterDescriptor extends DeclarationDescriptorImpl { this.variance = variance; this.upperBounds = upperBounds; // TODO: Should we actually pass the attributes on to the type constructor? - this.typeConstructor = new TypeConstructor( + this.typeConstructor = new TypeConstructorImpl( this, attributes, false, diff --git a/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java b/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java index 5b2d571bddf..4e83ef9115b 100644 --- a/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java +++ b/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java @@ -56,7 +56,7 @@ public class TypeUtils { } List noAttributes = Collections.emptyList(); - TypeConstructor constructor = new TypeConstructor(null, noAttributes, false, debugName.toString(), Collections.emptyList(), types); + TypeConstructor constructor = new TypeConstructorImpl(null, noAttributes, false, debugName.toString(), Collections.emptyList(), types); return new JetTypeImpl( noAttributes, constructor, diff --git a/idea/testData/psi/CallsInWhen.txt b/idea/testData/psi/CallsInWhen.txt index edc36fbcc42..131cbecedb8 100644 --- a/idea/testData/psi/CallsInWhen.txt +++ b/idea/testData/psi/CallsInWhen.txt @@ -148,7 +148,8 @@ JetFile: CallsInWhen.jet PsiElement(LBRACE)('{') BODY PREFIX_EXPRESSION - PsiElement(EXCL)('!') + OPERATION_REFERENCE + PsiElement(EXCL)('!') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('bar') PsiElement(RBRACE)('}') @@ -171,7 +172,8 @@ JetFile: CallsInWhen.jet PsiWhiteSpace(' ') BODY PREFIX_EXPRESSION - PsiElement(EXCL)('!') + OPERATION_REFERENCE + PsiElement(EXCL)('!') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('bar') PsiElement(RBRACE)('}') diff --git a/idea/testData/psi/ControlStructures.txt b/idea/testData/psi/ControlStructures.txt index f10aa833c1d..e8d12357fea 100644 --- a/idea/testData/psi/ControlStructures.txt +++ b/idea/testData/psi/ControlStructures.txt @@ -198,7 +198,8 @@ JetFile: ControlStructures.jet PsiElement(break)('break') PsiWhiteSpace('\n ') PREFIX_EXPRESSION - PsiElement(LABEL_IDENTIFIER)('@la') + OPERATION_REFERENCE + PsiElement(LABEL_IDENTIFIER)('@la') PsiWhiteSpace('\n ') BREAK PsiElement(break)('break') @@ -209,7 +210,8 @@ JetFile: ControlStructures.jet PsiElement(continue)('continue') PsiWhiteSpace('\n ') PREFIX_EXPRESSION - PsiElement(LABEL_IDENTIFIER)('@la') + OPERATION_REFERENCE + PsiElement(LABEL_IDENTIFIER)('@la') PsiWhiteSpace('\n ') CONTINUE PsiElement(continue)('continue') diff --git a/idea/testData/psi/EOLsInComments.txt b/idea/testData/psi/EOLsInComments.txt index 126952c17dd..f5b55e49b28 100644 --- a/idea/testData/psi/EOLsInComments.txt +++ b/idea/testData/psi/EOLsInComments.txt @@ -17,7 +17,8 @@ JetFile: EOLsInComments.jet PsiElement(IDENTIFIER)('a') PsiWhiteSpace('\n ') PREFIX_EXPRESSION - PsiElement(PLUS)('+') + OPERATION_REFERENCE + PsiElement(PLUS)('+') PsiWhiteSpace(' ') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('b') @@ -27,7 +28,8 @@ JetFile: EOLsInComments.jet PsiWhiteSpace('\n ') PsiComment(DOC_COMMENT)('/** */') PREFIX_EXPRESSION - PsiElement(PLUS)('+') + OPERATION_REFERENCE + PsiElement(PLUS)('+') PsiWhiteSpace(' ') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('b') @@ -37,7 +39,8 @@ JetFile: EOLsInComments.jet PsiWhiteSpace('\n ') PsiComment(BLOCK_COMMENT)('/* */') PREFIX_EXPRESSION - PsiElement(PLUS)('+') + OPERATION_REFERENCE + PsiElement(PLUS)('+') PsiWhiteSpace(' ') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('b') @@ -60,7 +63,8 @@ JetFile: EOLsInComments.jet PsiComment(BLOCK_COMMENT)('/*\n */') PsiWhiteSpace(' ') PREFIX_EXPRESSION - PsiElement(PLUS)('+') + OPERATION_REFERENCE + PsiElement(PLUS)('+') PsiWhiteSpace(' ') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('b') @@ -83,7 +87,8 @@ JetFile: EOLsInComments.jet PsiComment(EOL_COMMENT)('//') PsiWhiteSpace('\n ') PREFIX_EXPRESSION - PsiElement(PLUS)('+') + OPERATION_REFERENCE + PsiElement(PLUS)('+') PsiWhiteSpace(' ') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('b') @@ -94,7 +99,8 @@ JetFile: EOLsInComments.jet PsiComment(EOL_COMMENT)('//') PsiWhiteSpace('\n') PREFIX_EXPRESSION - PsiElement(PLUS)('+') + OPERATION_REFERENCE + PsiElement(PLUS)('+') PsiWhiteSpace(' ') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('b') diff --git a/idea/testData/psi/Labels.txt b/idea/testData/psi/Labels.txt index 5ea02f555d8..49297869b22 100644 --- a/idea/testData/psi/Labels.txt +++ b/idea/testData/psi/Labels.txt @@ -28,7 +28,8 @@ JetFile: Labels.jet PARENTHESIZED PsiElement(LPAR)('(') PREFIX_EXPRESSION - PsiElement(LABEL_IDENTIFIER)('@a') + OPERATION_REFERENCE + PsiElement(LABEL_IDENTIFIER)('@a') PsiWhiteSpace(' ') INTEGER_CONSTANT PsiElement(INTEGER_LITERAL)('1') @@ -52,18 +53,20 @@ JetFile: Labels.jet PARENTHESIZED PsiElement(LPAR)('(') PREFIX_EXPRESSION + OPERATION_REFERENCE + PsiElement(AT)('@') + PsiWhiteSpace(' ') + INTEGER_CONSTANT + PsiElement(INTEGER_LITERAL)('1') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n ') + RETURN + PsiElement(return)('return') + PsiElement(AT)('@') + PsiWhiteSpace(' ') + PREFIX_EXPRESSION + OPERATION_REFERENCE PsiElement(AT)('@') - PsiWhiteSpace(' ') - INTEGER_CONSTANT - PsiElement(INTEGER_LITERAL)('1') - PsiElement(RPAR)(')') - PsiWhiteSpace('\n ') - RETURN - PsiElement(return)('return') - PsiElement(AT)('@') - PsiWhiteSpace(' ') - PREFIX_EXPRESSION - PsiElement(AT)('@') PsiWhiteSpace(' ') INTEGER_CONSTANT PsiElement(INTEGER_LITERAL)('1') @@ -86,18 +89,20 @@ JetFile: Labels.jet PARENTHESIZED PsiElement(LPAR)('(') PREFIX_EXPRESSION + OPERATION_REFERENCE + PsiElement(LABEL_IDENTIFIER)('@a') + PsiWhiteSpace(' ') + INTEGER_CONSTANT + PsiElement(INTEGER_LITERAL)('1') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n ') + RETURN + PsiElement(return)('return') + PsiElement(LABEL_IDENTIFIER)('@a') + PsiWhiteSpace(' ') + PREFIX_EXPRESSION + OPERATION_REFERENCE PsiElement(LABEL_IDENTIFIER)('@a') - PsiWhiteSpace(' ') - INTEGER_CONSTANT - PsiElement(INTEGER_LITERAL)('1') - PsiElement(RPAR)(')') - PsiWhiteSpace('\n ') - RETURN - PsiElement(return)('return') - PsiElement(LABEL_IDENTIFIER)('@a') - PsiWhiteSpace(' ') - PREFIX_EXPRESSION - PsiElement(LABEL_IDENTIFIER)('@a') PsiWhiteSpace(' ') INTEGER_CONSTANT PsiElement(INTEGER_LITERAL)('1') @@ -120,7 +125,8 @@ JetFile: Labels.jet PARENTHESIZED PsiElement(LPAR)('(') PREFIX_EXPRESSION - PsiElement(ATAT)('@@') + OPERATION_REFERENCE + PsiElement(ATAT)('@@') PsiWhiteSpace(' ') INTEGER_CONSTANT PsiElement(INTEGER_LITERAL)('1') @@ -131,20 +137,23 @@ JetFile: Labels.jet PsiElement(ATAT)('@@') PsiWhiteSpace(' ') PREFIX_EXPRESSION - PsiElement(ATAT)('@@') + OPERATION_REFERENCE + PsiElement(ATAT)('@@') PsiWhiteSpace(' ') INTEGER_CONSTANT PsiElement(INTEGER_LITERAL)('1') PsiWhiteSpace('\n\n ') PREFIX_EXPRESSION - PsiElement(LABEL_IDENTIFIER)('@a') + OPERATION_REFERENCE + PsiElement(LABEL_IDENTIFIER)('@a') PsiWhiteSpace(' ') RETURN PsiElement(return)('return') PsiElement(ATAT)('@@') PsiWhiteSpace('\n ') PREFIX_EXPRESSION - PsiElement(LABEL_IDENTIFIER)('@a') + OPERATION_REFERENCE + PsiElement(LABEL_IDENTIFIER)('@a') PsiWhiteSpace(' ') RETURN PsiElement(return)('return') @@ -154,7 +163,8 @@ JetFile: Labels.jet PsiElement(INTEGER_LITERAL)('1') PsiWhiteSpace('\n ') PREFIX_EXPRESSION - PsiElement(LABEL_IDENTIFIER)('@a') + OPERATION_REFERENCE + PsiElement(LABEL_IDENTIFIER)('@a') PsiWhiteSpace(' ') RETURN PsiElement(return)('return') @@ -163,21 +173,24 @@ JetFile: Labels.jet PARENTHESIZED PsiElement(LPAR)('(') PREFIX_EXPRESSION - PsiElement(ATAT)('@@') + OPERATION_REFERENCE + PsiElement(ATAT)('@@') PsiWhiteSpace(' ') INTEGER_CONSTANT PsiElement(INTEGER_LITERAL)('1') PsiElement(RPAR)(')') PsiWhiteSpace('\n ') PREFIX_EXPRESSION - PsiElement(LABEL_IDENTIFIER)('@a') + OPERATION_REFERENCE + PsiElement(LABEL_IDENTIFIER)('@a') PsiWhiteSpace(' ') RETURN PsiElement(return)('return') PsiElement(ATAT)('@@') PsiWhiteSpace(' ') PREFIX_EXPRESSION - PsiElement(ATAT)('@@') + OPERATION_REFERENCE + PsiElement(ATAT)('@@') PsiWhiteSpace(' ') INTEGER_CONSTANT PsiElement(INTEGER_LITERAL)('1') @@ -221,7 +234,8 @@ JetFile: Labels.jet PsiElement(IDENTIFIER)('filter') PsiWhiteSpace(' ') PREFIX_EXPRESSION - PsiElement(LABEL_IDENTIFIER)('@f') + OPERATION_REFERENCE + PsiElement(LABEL_IDENTIFIER)('@f') FUNCTION_LITERAL PsiElement(LBRACE)('{') PsiWhiteSpace('\n ') @@ -257,7 +271,8 @@ JetFile: Labels.jet PsiElement(IDENTIFIER)('filter') PsiWhiteSpace(' ') PREFIX_EXPRESSION - PsiElement(AT)('@') + OPERATION_REFERENCE + PsiElement(AT)('@') FUNCTION_LITERAL PsiElement(LBRACE)('{') PsiWhiteSpace('\n ') @@ -293,7 +308,8 @@ JetFile: Labels.jet PsiElement(IDENTIFIER)('filter') PsiWhiteSpace(' ') PREFIX_EXPRESSION - PsiElement(ATAT)('@@') + OPERATION_REFERENCE + PsiElement(ATAT)('@@') FUNCTION_LITERAL PsiElement(LBRACE)('{') PsiWhiteSpace('\n ') diff --git a/idea/testData/psi/NewlinesInParentheses.txt b/idea/testData/psi/NewlinesInParentheses.txt index 06858ad1f55..117fe3fc94d 100644 --- a/idea/testData/psi/NewlinesInParentheses.txt +++ b/idea/testData/psi/NewlinesInParentheses.txt @@ -58,7 +58,8 @@ JetFile: NewlinesInParentheses.jet PsiElement(IDENTIFIER)('a') PsiWhiteSpace('\n ') PREFIX_EXPRESSION - PsiElement(PLUS)('+') + OPERATION_REFERENCE + PsiElement(PLUS)('+') PsiWhiteSpace(' ') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('b') @@ -99,7 +100,8 @@ JetFile: NewlinesInParentheses.jet PsiElement(IDENTIFIER)('a') PsiWhiteSpace('\n ') PREFIX_EXPRESSION - PsiElement(PLUS)('+') + OPERATION_REFERENCE + PsiElement(PLUS)('+') PsiWhiteSpace(' ') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('b') @@ -123,7 +125,8 @@ JetFile: NewlinesInParentheses.jet PsiElement(IDENTIFIER)('a') PsiWhiteSpace('\n ') PREFIX_EXPRESSION - PsiElement(PLUS)('+') + OPERATION_REFERENCE + PsiElement(PLUS)('+') PsiWhiteSpace(' ') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('b') @@ -178,7 +181,8 @@ JetFile: NewlinesInParentheses.jet PsiElement(IDENTIFIER)('c') PsiWhiteSpace('\n ') PREFIX_EXPRESSION - PsiElement(PLUS)('+') + OPERATION_REFERENCE + PsiElement(PLUS)('+') PsiWhiteSpace(' ') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('d') @@ -205,7 +209,8 @@ JetFile: NewlinesInParentheses.jet PsiElement(IDENTIFIER)('c') PsiWhiteSpace('\n ') PREFIX_EXPRESSION - PsiElement(PLUS)('+') + OPERATION_REFERENCE + PsiElement(PLUS)('+') PsiWhiteSpace(' ') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('d') diff --git a/idea/testData/psi/Precedence.txt b/idea/testData/psi/Precedence.txt index 5ca7ce8a71e..11301efde84 100644 --- a/idea/testData/psi/Precedence.txt +++ b/idea/testData/psi/Precedence.txt @@ -28,7 +28,8 @@ JetFile: Precedence.jet POSTFIX_EXPRESSION REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('x') - PsiElement(PLUSPLUS)('++') + OPERATION_REFERENCE + PsiElement(PLUSPLUS)('++') PsiWhiteSpace(' ') PsiElement(DOT)('.') PsiWhiteSpace(' ') @@ -36,13 +37,16 @@ JetFile: Precedence.jet PsiElement(INTEGER_LITERAL)('4') PsiWhiteSpace('\n ') PREFIX_EXPRESSION - PsiElement(PLUSPLUS)('++') + OPERATION_REFERENCE + PsiElement(PLUSPLUS)('++') PsiWhiteSpace(' ') PREFIX_EXPRESSION - PsiElement(MINUSMINUS)('--') + OPERATION_REFERENCE + PsiElement(MINUSMINUS)('--') PsiWhiteSpace(' ') PREFIX_EXPRESSION - PsiElement(EXCL)('!') + OPERATION_REFERENCE + PsiElement(EXCL)('!') PsiWhiteSpace(' ') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('a') @@ -433,10 +437,12 @@ JetFile: Precedence.jet PsiElement(DOT)('.') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('b') - PsiElement(PLUSPLUS)('++') + OPERATION_REFERENCE + PsiElement(PLUSPLUS)('++') PsiWhiteSpace('\n ') PREFIX_EXPRESSION - PsiElement(MINUSMINUS)('--') + OPERATION_REFERENCE + PsiElement(MINUSMINUS)('--') POSTFIX_EXPRESSION DOT_QIALIFIED_EXPRESSION REFERENCE_EXPRESSION @@ -444,11 +450,13 @@ JetFile: Precedence.jet PsiElement(DOT)('.') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('b') - PsiElement(PLUSPLUS)('++') + OPERATION_REFERENCE + PsiElement(PLUSPLUS)('++') PsiWhiteSpace('\n ') BINARY_EXPRESSION PREFIX_EXPRESSION - PsiElement(MINUSMINUS)('--') + OPERATION_REFERENCE + PsiElement(MINUSMINUS)('--') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('a') PsiWhiteSpace(' ') @@ -940,7 +948,8 @@ JetFile: Precedence.jet BINARY_EXPRESSION BINARY_WITH_TYPE PREFIX_EXPRESSION - PsiElement(PLUSPLUS)('++') + OPERATION_REFERENCE + PsiElement(PLUSPLUS)('++') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('t') PsiWhiteSpace(' ') diff --git a/idea/testData/psi/SimpleExpressions.txt b/idea/testData/psi/SimpleExpressions.txt index 09a374f8af5..a90cabc98b3 100644 --- a/idea/testData/psi/SimpleExpressions.txt +++ b/idea/testData/psi/SimpleExpressions.txt @@ -671,7 +671,8 @@ JetFile: SimpleExpressions.jet PsiElement(break)('break') PsiWhiteSpace('\n ') PREFIX_EXPRESSION - PsiElement(LABEL_IDENTIFIER)('@la') + OPERATION_REFERENCE + PsiElement(LABEL_IDENTIFIER)('@la') PsiWhiteSpace('\n ') BREAK PsiElement(break)('break') @@ -682,7 +683,8 @@ JetFile: SimpleExpressions.jet PsiElement(continue)('continue') PsiWhiteSpace('\n ') PREFIX_EXPRESSION - PsiElement(LABEL_IDENTIFIER)('@la') + OPERATION_REFERENCE + PsiElement(LABEL_IDENTIFIER)('@la') PsiWhiteSpace('\n ') CONTINUE PsiElement(continue)('continue') diff --git a/idea/testData/psi/examples/AnonymousObjects.txt b/idea/testData/psi/examples/AnonymousObjects.txt index dfe32c19ecc..6f20a9d375a 100644 --- a/idea/testData/psi/examples/AnonymousObjects.txt +++ b/idea/testData/psi/examples/AnonymousObjects.txt @@ -77,7 +77,8 @@ JetFile: AnonymousObjects.jet POSTFIX_EXPRESSION REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('clickCount') - PsiElement(PLUSPLUS)('++') + OPERATION_REFERENCE + PsiElement(PLUSPLUS)('++') PsiElement(SEMICOLON)(';') PsiWhiteSpace('\n ') IF diff --git a/idea/testData/psi/examples/BinaryTree.txt b/idea/testData/psi/examples/BinaryTree.txt index 90693bcb436..467253662b6 100644 --- a/idea/testData/psi/examples/BinaryTree.txt +++ b/idea/testData/psi/examples/BinaryTree.txt @@ -564,12 +564,14 @@ JetFile: BinaryTree.jet POSTFIX_EXPRESSION REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('size') - PsiElement(PLUSPLUS)('++') + OPERATION_REFERENCE + PsiElement(PLUSPLUS)('++') PsiWhiteSpace('\n ') POSTFIX_EXPRESSION REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('version') - PsiElement(PLUSPLUS)('++') + OPERATION_REFERENCE + PsiElement(PLUSPLUS)('++') PsiWhiteSpace('\n ') RETURN PsiElement(return)('return') @@ -1168,12 +1170,14 @@ JetFile: BinaryTree.jet POSTFIX_EXPRESSION REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('size') - PsiElement(MINUSMINUS)('--') + OPERATION_REFERENCE + PsiElement(MINUSMINUS)('--') PsiWhiteSpace('\n ') POSTFIX_EXPRESSION REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('version') - PsiElement(PLUSPLUS)('++') + OPERATION_REFERENCE + PsiElement(PLUSPLUS)('++') PsiWhiteSpace('\n ') RETURN PsiElement(return)('return') @@ -2048,7 +2052,8 @@ JetFile: BinaryTree.jet PsiElement(LPAR)('(') CONDITION PREFIX_EXPRESSION - PsiElement(EXCL)('!') + OPERATION_REFERENCE + PsiElement(EXCL)('!') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('hasNext') PsiElement(RPAR)(')') @@ -2140,7 +2145,8 @@ JetFile: BinaryTree.jet PsiElement(LPAR)('(') CONDITION PREFIX_EXPRESSION - PsiElement(EXCL)('!') + OPERATION_REFERENCE + PsiElement(EXCL)('!') DOT_QIALIFIED_EXPRESSION REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('down') @@ -2400,7 +2406,8 @@ JetFile: BinaryTree.jet PsiWhiteSpace(' ') BINARY_EXPRESSION PREFIX_EXPRESSION - PsiElement(EXCL)('!') + OPERATION_REFERENCE + PsiElement(EXCL)('!') DOT_QIALIFIED_EXPRESSION REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('down') @@ -2412,7 +2419,8 @@ JetFile: BinaryTree.jet PsiElement(OROR)('||') PsiWhiteSpace(' ') PREFIX_EXPRESSION - PsiElement(EXCL)('!') + OPERATION_REFERENCE + PsiElement(EXCL)('!') DOT_QIALIFIED_EXPRESSION REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('up') @@ -2486,7 +2494,8 @@ JetFile: BinaryTree.jet POSTFIX_EXPRESSION REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('version') - PsiElement(PLUSPLUS)('++') + OPERATION_REFERENCE + PsiElement(PLUSPLUS)('++') PsiWhiteSpace('\n ') BINARY_EXPRESSION DOT_QIALIFIED_EXPRESSION diff --git a/idea/testData/psi/examples/Graph.txt b/idea/testData/psi/examples/Graph.txt index babf61a5d27..ceb9b136ef8 100644 --- a/idea/testData/psi/examples/Graph.txt +++ b/idea/testData/psi/examples/Graph.txt @@ -668,7 +668,8 @@ JetFile: Graph.jet PsiElement(LPAR)('(') CONDITION PREFIX_EXPRESSION - PsiElement(EXCL)('!') + OPERATION_REFERENCE + PsiElement(EXCL)('!') CALL_EXPRESSION DOT_QIALIFIED_EXPRESSION REFERENCE_EXPRESSION @@ -852,7 +853,8 @@ JetFile: Graph.jet PsiElement(LPAR)('(') CONDITION PREFIX_EXPRESSION - PsiElement(EXCL)('!') + OPERATION_REFERENCE + PsiElement(EXCL)('!') CALL_EXPRESSION DOT_QIALIFIED_EXPRESSION REFERENCE_EXPRESSION @@ -892,7 +894,8 @@ JetFile: Graph.jet PsiElement(LPAR)('(') CONDITION PREFIX_EXPRESSION - PsiElement(EXCL)('!') + OPERATION_REFERENCE + PsiElement(EXCL)('!') DOT_QIALIFIED_EXPRESSION REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('pending') diff --git a/idea/testData/psi/examples/UpdateOperation.txt b/idea/testData/psi/examples/UpdateOperation.txt index d9bed0bfc64..d0ffcd902f3 100644 --- a/idea/testData/psi/examples/UpdateOperation.txt +++ b/idea/testData/psi/examples/UpdateOperation.txt @@ -211,7 +211,8 @@ JetFile: UpdateOperation.jet PsiElement(EQ)('=') PsiWhiteSpace(' ') PREFIX_EXPRESSION - PsiElement(MINUS)('-') + OPERATION_REFERENCE + PsiElement(MINUS)('-') INTEGER_CONSTANT PsiElement(INTEGER_LITERAL)('1') PsiElement(RPAR)(')') diff --git a/idea/testData/psi/examples/collections/ArrayList.txt b/idea/testData/psi/examples/collections/ArrayList.txt index 64d5b258241..f36c9cdf72a 100644 --- a/idea/testData/psi/examples/collections/ArrayList.txt +++ b/idea/testData/psi/examples/collections/ArrayList.txt @@ -291,7 +291,8 @@ JetFile: ArrayList.jet POSTFIX_EXPRESSION REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('index') - PsiElement(PLUSPLUS)('++') + OPERATION_REFERENCE + PsiElement(PLUSPLUS)('++') PsiElement(RBRACKET)(']') PsiWhiteSpace('\n ') PsiElement(RBRACE)('}') @@ -709,7 +710,8 @@ JetFile: ArrayList.jet POSTFIX_EXPRESSION REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('used') - PsiElement(PLUSPLUS)('++') + OPERATION_REFERENCE + PsiElement(PLUSPLUS)('++') PsiElement(RBRACKET)(']') PsiWhiteSpace(' ') OPERATION_REFERENCE @@ -819,7 +821,8 @@ JetFile: ArrayList.jet POSTFIX_EXPRESSION REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('used') - PsiElement(PLUSPLUS)('++') + OPERATION_REFERENCE + PsiElement(PLUSPLUS)('++') PsiWhiteSpace('\n ') PsiElement(RBRACE)('}') PsiWhiteSpace(' ') diff --git a/idea/testData/psi/examples/collections/IIterator.txt b/idea/testData/psi/examples/collections/IIterator.txt index 2cbb1fbc055..f3377558b42 100644 --- a/idea/testData/psi/examples/collections/IIterator.txt +++ b/idea/testData/psi/examples/collections/IIterator.txt @@ -354,7 +354,8 @@ JetFile: IIterator.jet PsiElement(LPAR)('(') CONDITION PREFIX_EXPRESSION - PsiElement(EXCL)('!') + OPERATION_REFERENCE + PsiElement(EXCL)('!') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('hasNext') PsiElement(RPAR)(')') @@ -389,7 +390,8 @@ JetFile: IIterator.jet POSTFIX_EXPRESSION REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('count') - PsiElement(PLUSPLUS)('++') + OPERATION_REFERENCE + PsiElement(PLUSPLUS)('++') PsiWhiteSpace('\n ') PsiElement(RBRACE)('}') PsiWhiteSpace('\n ') diff --git a/idea/testData/psi/examples/collections/LinkedList.txt b/idea/testData/psi/examples/collections/LinkedList.txt index 511230f0ee7..9cc1d6bf7da 100644 --- a/idea/testData/psi/examples/collections/LinkedList.txt +++ b/idea/testData/psi/examples/collections/LinkedList.txt @@ -179,7 +179,8 @@ JetFile: LinkedList.jet POSTFIX_EXPRESSION REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('size') - PsiElement(PLUSPLUS)('++') + OPERATION_REFERENCE + PsiElement(PLUSPLUS)('++') PsiWhiteSpace('\n ') CALL_EXPRESSION REFERENCE_EXPRESSION @@ -682,7 +683,8 @@ JetFile: LinkedList.jet POSTFIX_EXPRESSION REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('size') - PsiElement(MINUSMINUS)('--') + OPERATION_REFERENCE + PsiElement(MINUSMINUS)('--') PsiWhiteSpace('\n ') RETURN PsiElement(return)('return') diff --git a/idea/testData/psi/examples/io/IOSamples.txt b/idea/testData/psi/examples/io/IOSamples.txt index c6e02360e2d..fec4dfdb834 100644 --- a/idea/testData/psi/examples/io/IOSamples.txt +++ b/idea/testData/psi/examples/io/IOSamples.txt @@ -355,7 +355,8 @@ JetFile: IOSamples.jet PsiElement(LPAR)('(') CONDITION PREFIX_EXPRESSION - PsiElement(EXCL)('!') + OPERATION_REFERENCE + PsiElement(EXCL)('!') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('nextUsed') PsiElement(RPAR)(')') @@ -435,7 +436,8 @@ JetFile: IOSamples.jet PsiElement(EXCLEQ)('!=') PsiWhiteSpace(' ') PREFIX_EXPRESSION - PsiElement(MINUS)('-') + OPERATION_REFERENCE + PsiElement(MINUS)('-') INTEGER_CONSTANT PsiElement(INTEGER_LITERAL)('1') PsiElement(RPAR)(')') @@ -488,7 +490,8 @@ JetFile: IOSamples.jet PsiElement(EXCLEQ)('!=') PsiWhiteSpace(' ') PREFIX_EXPRESSION - PsiElement(MINUS)('-') + OPERATION_REFERENCE + PsiElement(MINUS)('-') INTEGER_CONSTANT PsiElement(INTEGER_LITERAL)('1') PsiWhiteSpace(' \n ') diff --git a/idea/testData/psi/examples/priorityqueues/BinaryHeap.txt b/idea/testData/psi/examples/priorityqueues/BinaryHeap.txt index 07d152c1274..141bbbae9ca 100644 --- a/idea/testData/psi/examples/priorityqueues/BinaryHeap.txt +++ b/idea/testData/psi/examples/priorityqueues/BinaryHeap.txt @@ -784,7 +784,8 @@ JetFile: BinaryHeap.jet PsiElement(LPAR)('(') CONDITION PREFIX_EXPRESSION - PsiElement(EXCL)('!') + OPERATION_REFERENCE + PsiElement(EXCL)('!') DOT_QIALIFIED_EXPRESSION REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('current') diff --git a/idea/testData/resolve/ResolveOfInfixExpressions.jet b/idea/testData/resolve/ResolveOfInfixExpressions.jet index 266c851579f..571ab1b5ff0 100644 --- a/idea/testData/resolve/ResolveOfInfixExpressions.jet +++ b/idea/testData/resolve/ResolveOfInfixExpressions.jet @@ -23,10 +23,14 @@ import util.* ~get3~fun get(i : Object) : Any {return i } } +~Bar~class Bar : Foo { + ~not~fun not() : String {} +} + fun tt(t : T) : T { val x : List = 0 x`java::java.util.List.get()`[1] - val foo = new Foo + val foo = new Bar foo`!`[null, 1] foo`get2`[1, 1] foo`get1`[1] @@ -36,4 +40,5 @@ fun tt(t : T) : T { (x`java::java.util.List.set()`[1]) = null x`!`[null] = null (x`!`[null, 2]) = null + (`not`!foo)[1]`:std::Char` } diff --git a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java index 5f4f3ec9b75..86c05c728db 100644 --- a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java +++ b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java @@ -105,25 +105,25 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase { assertType("if (true) 1 else null", "Int?"); assertType("if (true) null else null", "Nothing?"); - assertType("if (true) 1 else '1'", "Any"); + assertType("if (true) 1 else '1'", "Comparable"); } public void testWhen() throws Exception { assertType("when (1) { is 1 => 2; } ", "Int"); - assertType("when (1) { is 1 => 2; is 1 => '2'} ", "Any"); - assertType("when (1) { is 1 => 2; is 1 => '2'; is 1 => null} ", "Any?"); - assertType("when (1) { is 1 => 2; is 1 => '2'; else => null} ", "Any?"); - assertType("when (1) { is 1 => 2; is 1 => '2'; else continue} ", "Any"); - assertType("when (1) { is 1 => 2; is 1 => '2'; is 1 when(e) {is 1 => null}} ", "Any?"); - assertType("when (1) { is 1 => 2; is 1 => '2'; is 1 => when(e) {is 1 => null}} ", "Any?"); + assertType("when (1) { is 1 => 2; is 1 => '2'} ", "Comparable"); + assertType("when (1) { is 1 => 2; is 1 => '2'; is 1 => null} ", "Comparable?"); + assertType("when (1) { is 1 => 2; is 1 => '2'; else => null} ", "Comparable?"); + assertType("when (1) { is 1 => 2; is 1 => '2'; else continue} ", "Comparable"); + assertType("when (1) { is 1 => 2; is 1 => '2'; is 1 when(e) {is 1 => null}} ", "Comparable?"); + assertType("when (1) { is 1 => 2; is 1 => '2'; is 1 => when(e) {is 1 => null}} ", "Comparable?"); } public void testTry() throws Exception { assertType("try {1} finally{2}", "Int"); assertType("try {1} catch (e : e) {'a'} finally{2}", "Int"); - assertType("try {1} catch (e : e) {'a'} finally{'2'}", "Any"); - assertType("try {1} catch (e : e) {'a'}", "Any"); - assertType("try {1} catch (e : e) {'a'} catch (e : e) {null}", "Any?"); + assertType("try {1} catch (e : e) {'a'} finally{'2'}", "Comparable"); + assertType("try {1} catch (e : e) {'a'}", "Comparable"); + assertType("try {1} catch (e : e) {'a'} catch (e : e) {null}", "Comparable?"); assertType("try {} catch (e : e) {}", "Unit"); } @@ -137,7 +137,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase { assertCommonSupertype("Int?", "Int", "Nothing?"); assertCommonSupertype("Nothing?", "Nothing?", "Nothing?"); - assertCommonSupertype("Any", "Int", "Char"); + assertCommonSupertype("Comparable", "Int", "Char"); assertCommonSupertype("Base_T<*>", "Base_T<*>", "Derived_T<*>"); assertCommonSupertype("Any", "Base_inT<*>", "Derived_T<*>");