From 3d8b5aa456c0937309885fd95ea908dba4fcc29a Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 17 Oct 2011 18:10:41 +0400 Subject: [PATCH] Visitors refactored. LabelResolver problem stays there --- .../jet/codegen/ExpressionCodegen.java | 2 +- .../jet/lang/JetSemanticServices.java | 6 +- .../jet/lang/psi/JetAnnotatedExpression.java | 2 +- .../jetbrains/jet/lang/psi/JetAnnotation.java | 2 +- .../jet/lang/psi/JetAnnotationEntry.java | 2 +- .../lang/psi/JetArrayAccessExpression.java | 2 +- .../jet/lang/psi/JetBinaryExpression.java | 2 +- .../psi/JetBinaryExpressionWithTypeRHS.java | 2 +- .../jet/lang/psi/JetBindingPattern.java | 2 +- .../jet/lang/psi/JetBlockExpression.java | 2 +- .../lang/psi/JetBlockStringTemplateEntry.java | 2 +- .../jet/lang/psi/JetBreakExpression.java | 2 +- .../jet/lang/psi/JetCallExpression.java | 2 +- .../jet/lang/psi/JetCatchClause.java | 2 +- .../org/jetbrains/jet/lang/psi/JetClass.java | 2 +- .../jetbrains/jet/lang/psi/JetClassBody.java | 2 +- .../jet/lang/psi/JetClassInitializer.java | 2 +- .../jet/lang/psi/JetClassObject.java | 2 +- .../jet/lang/psi/JetConstantExpression.java | 2 +- .../jet/lang/psi/JetConstructor.java | 2 +- .../jet/lang/psi/JetContinueExpression.java | 2 +- .../jet/lang/psi/JetDecomposerPattern.java | 2 +- .../jet/lang/psi/JetDelegationSpecifier.java | 2 +- .../lang/psi/JetDelegationSpecifierList.java | 2 +- .../JetDelegatorByExpressionSpecifier.java | 2 +- .../jet/lang/psi/JetDelegatorToSuperCall.java | 2 +- .../lang/psi/JetDelegatorToSuperClass.java | 2 +- .../jet/lang/psi/JetDelegatorToThisCall.java | 2 +- .../jet/lang/psi/JetDoWhileExpression.java | 2 +- .../lang/psi/JetDotQualifiedExpression.java | 2 +- .../jetbrains/jet/lang/psi/JetElement.java | 2 +- .../jetbrains/jet/lang/psi/JetEnumEntry.java | 2 +- .../psi/JetEscapeStringTemplateEntry.java | 2 +- .../jetbrains/jet/lang/psi/JetExpression.java | 2 +- .../jet/lang/psi/JetExpressionPattern.java | 2 +- .../jet/lang/psi/JetFinallySection.java | 2 +- .../jet/lang/psi/JetForExpression.java | 2 +- .../psi/JetFunctionLiteralExpression.java | 2 +- .../jet/lang/psi/JetFunctionType.java | 2 +- .../lang/psi/JetHashQualifiedExpression.java | 2 +- .../jet/lang/psi/JetIfExpression.java | 2 +- .../jet/lang/psi/JetImportDirective.java | 2 +- .../jet/lang/psi/JetInitializerList.java | 2 +- .../jet/lang/psi/JetIsExpression.java | 2 +- .../psi/JetLiteralStringTemplateEntry.java | 2 +- .../jet/lang/psi/JetModifierList.java | 2 +- .../jet/lang/psi/JetNamedFunction.java | 2 +- .../jetbrains/jet/lang/psi/JetNamespace.java | 2 +- .../jet/lang/psi/JetNamespaceBody.java | 2 +- .../jet/lang/psi/JetNullableType.java | 2 +- .../jet/lang/psi/JetObjectDeclaration.java | 2 +- .../lang/psi/JetObjectLiteralExpression.java | 2 +- .../jetbrains/jet/lang/psi/JetParameter.java | 2 +- .../jet/lang/psi/JetParameterList.java | 2 +- .../lang/psi/JetParenthesizedExpression.java | 2 +- .../jet/lang/psi/JetPostfixExpression.java | 2 +- .../jet/lang/psi/JetPredicateExpression.java | 2 +- .../jet/lang/psi/JetPrefixExpression.java | 2 +- .../jetbrains/jet/lang/psi/JetProperty.java | 2 +- .../jet/lang/psi/JetPropertyAccessor.java | 2 +- .../jet/lang/psi/JetReturnExpression.java | 2 +- .../lang/psi/JetRootNamespaceExpression.java | 2 +- .../lang/psi/JetSafeQualifiedExpression.java | 2 +- .../jetbrains/jet/lang/psi/JetSelfType.java | 2 +- .../jet/lang/psi/JetSimpleNameExpression.java | 2 +- .../psi/JetSimpleNameStringTemplateEntry.java | 2 +- .../JetStringTemplateEntryWithExpression.java | 2 +- .../lang/psi/JetStringTemplateExpression.java | 2 +- .../jet/lang/psi/JetThisExpression.java | 2 +- .../jet/lang/psi/JetThrowExpression.java | 2 +- .../jet/lang/psi/JetTreeVisitor.java | 160 +- .../jet/lang/psi/JetTryExpression.java | 2 +- .../jet/lang/psi/JetTupleExpression.java | 2 +- .../jet/lang/psi/JetTuplePattern.java | 2 +- .../jetbrains/jet/lang/psi/JetTupleType.java | 2 +- .../jet/lang/psi/JetTypeArgumentList.java | 2 +- .../jet/lang/psi/JetTypeConstraint.java | 2 +- .../jet/lang/psi/JetTypeConstraintList.java | 2 +- .../jet/lang/psi/JetTypeParameter.java | 2 +- .../jet/lang/psi/JetTypeParameterList.java | 2 +- .../jet/lang/psi/JetTypePattern.java | 2 +- .../jet/lang/psi/JetTypeProjection.java | 2 +- .../jet/lang/psi/JetTypeReference.java | 2 +- .../jetbrains/jet/lang/psi/JetTypedef.java | 2 +- .../jetbrains/jet/lang/psi/JetUserType.java | 2 +- .../jet/lang/psi/JetValueArgument.java | 2 +- .../jet/lang/psi/JetValueArgumentList.java | 2 +- .../jet/lang/psi/JetWhenConditionCall.java | 2 +- .../jet/lang/psi/JetWhenConditionInRange.java | 2 +- .../lang/psi/JetWhenConditionIsPattern.java | 2 +- .../jetbrains/jet/lang/psi/JetWhenEntry.java | 2 +- .../jet/lang/psi/JetWhenExpression.java | 2 +- .../jet/lang/psi/JetWhileExpression.java | 2 +- .../jet/lang/psi/JetWildcardPattern.java | 2 +- .../jet/lang/resolve/BodyResolver.java | 26 +- .../jet/lang/resolve/ControlFlowAnalyzer.java | 4 +- .../lang/resolve/TypeHierarchyResolver.java | 4 +- .../jet/lang/resolve/calls/AutoCastUtils.java | 13 - .../jet/lang/resolve/calls/CallResolver.java | 8 +- .../BasicExpressionTypingVisitor.java | 779 +++++++ .../ClosureExpressionsTypingVisitor.java | 162 ++ .../ControlStructureTypingVisitor.java | 414 ++++ .../expressions/ExpressionTyperServices.java | 484 ---- .../expressions/ExpressionTyperVisitor.java | 1944 ----------------- .../ExpressionTyperVisitorWithNamespaces.java | 33 - .../expressions/ExpressionTypingContext.java | 116 +- .../expressions/ExpressionTypingFacade.java | 17 + .../ExpressionTypingInternals.java | 27 + .../expressions/ExpressionTypingServices.java | 288 +++ .../expressions/ExpressionTypingUtils.java | 252 +++ .../expressions/ExpressionTypingVisitor.java | 17 + .../ExpressionTypingVisitorDispatcher.java | 198 ++ ...essionTypingVisitorWithWritableScope.java} | 41 +- .../types/expressions/FunctionBodyTyper.java | 7 + .../PatternMatchingTypingVisitor.java | 265 +++ .../jetbrains/jet/resolve/JetResolveTest.java | 18 +- 116 files changed, 2703 insertions(+), 2764 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java delete mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTyperServices.java delete mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTyperVisitor.java delete mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTyperVisitorWithNamespaces.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingFacade.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingInternals.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitor.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java rename compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/{ExpressionTyperVisitorWithWritableScope.java => ExpressionTypingVisitorWithWritableScope.java} (77%) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/FunctionBodyTyper.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index f231cdf3426..a7137d43e8a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -94,7 +94,7 @@ public class ExpressionCodegen extends JetVisitor { public StackValue genQualified(StackValue receiver, JetElement selector) { markLineNumber(selector); - return selector.visit(this, receiver); + return selector.accept(this, receiver); } public StackValue gen(JetElement expr) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/JetSemanticServices.java b/compiler/frontend/src/org/jetbrains/jet/lang/JetSemanticServices.java index a5d1f318757..28b3b7b5c24 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/JetSemanticServices.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/JetSemanticServices.java @@ -7,7 +7,7 @@ import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.ClassDescriptorResolver; import org.jetbrains.jet.lang.types.JetStandardLibrary; import org.jetbrains.jet.lang.types.JetTypeChecker; -import org.jetbrains.jet.lang.types.expressions.ExpressionTyperServices; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; /** * @author abreslav @@ -46,8 +46,8 @@ public class JetSemanticServices { } @NotNull - public ExpressionTyperServices getTypeInferrerServices(@NotNull BindingTrace trace) { - return new ExpressionTyperServices(this, trace); + public ExpressionTypingServices getTypeInferrerServices(@NotNull BindingTrace trace) { + return new ExpressionTypingServices(this, trace); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetAnnotatedExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetAnnotatedExpression.java index 0d06de6d8d6..139b9c20cba 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetAnnotatedExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetAnnotatedExpression.java @@ -22,7 +22,7 @@ public class JetAnnotatedExpression extends JetExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitAnnotatedExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetAnnotation.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetAnnotation.java index 29619099473..1103c52ac47 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetAnnotation.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetAnnotation.java @@ -20,7 +20,7 @@ public class JetAnnotation extends JetElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitAnnotation(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetAnnotationEntry.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetAnnotationEntry.java index 77a4634e791..591544de38f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetAnnotationEntry.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetAnnotationEntry.java @@ -22,7 +22,7 @@ public class JetAnnotationEntry extends JetElement implements JetCallElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitAnnotationEntry(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetArrayAccessExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetArrayAccessExpression.java index a690f1454fb..ec971f4796c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetArrayAccessExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetArrayAccessExpression.java @@ -32,7 +32,7 @@ public class JetArrayAccessExpression extends JetReferenceExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitArrayAccessExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBinaryExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBinaryExpression.java index 33cfe223c08..5d60411e203 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBinaryExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBinaryExpression.java @@ -21,7 +21,7 @@ public class JetBinaryExpression extends JetExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitBinaryExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBinaryExpressionWithTypeRHS.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBinaryExpressionWithTypeRHS.java index 4c182794d96..c0249025048 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBinaryExpressionWithTypeRHS.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBinaryExpressionWithTypeRHS.java @@ -20,7 +20,7 @@ public class JetBinaryExpressionWithTypeRHS extends JetExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitBinaryWithTypeRHSExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBindingPattern.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBindingPattern.java index 16a604244c0..bcaadfc9fdd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBindingPattern.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBindingPattern.java @@ -29,7 +29,7 @@ public class JetBindingPattern extends JetPattern { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitBindingPattern(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBlockExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBlockExpression.java index 79248df6e36..cf8074088aa 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBlockExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBlockExpression.java @@ -20,7 +20,7 @@ public class JetBlockExpression extends JetExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitBlockExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBlockStringTemplateEntry.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBlockStringTemplateEntry.java index 3982036894c..5ffceecad4d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBlockStringTemplateEntry.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBlockStringTemplateEntry.java @@ -17,7 +17,7 @@ public class JetBlockStringTemplateEntry extends JetStringTemplateEntryWithExpre } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitBlockStringTemplateEntry(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBreakExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBreakExpression.java index 0d7592872cf..cd2037985fb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBreakExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBreakExpression.java @@ -17,7 +17,7 @@ public class JetBreakExpression extends JetLabelQualifiedExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitBreakExpression(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetCallExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetCallExpression.java index 84d08e200a4..79eef89077e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetCallExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetCallExpression.java @@ -22,7 +22,7 @@ public class JetCallExpression extends JetExpression implements JetCallElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitCallExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetCatchClause.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetCatchClause.java index 0b581e6aa4c..03112fbd965 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetCatchClause.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetCatchClause.java @@ -21,7 +21,7 @@ public class JetCatchClause extends JetElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitCatchSection(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClass.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClass.java index 176693cc17c..0b1b54b0509 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClass.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClass.java @@ -40,7 +40,7 @@ public class JetClass extends JetTypeParameterListOwner implements JetClassOrObj } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitClass(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassBody.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassBody.java index 0dec1a6dca4..5b4e67347f7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassBody.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassBody.java @@ -30,7 +30,7 @@ public class JetClassBody extends JetElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitClassBody(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassInitializer.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassInitializer.java index 7f014f93787..a2a93ee1f48 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassInitializer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassInitializer.java @@ -17,7 +17,7 @@ public class JetClassInitializer extends JetDeclaration { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitAnonymousInitializer(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassObject.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassObject.java index 92dd0b20077..4147cc3dd20 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassObject.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassObject.java @@ -19,7 +19,7 @@ public class JetClassObject extends JetDeclaration { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitClassObject(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetConstantExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetConstantExpression.java index 2bfff817e77..1465a02e92c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetConstantExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetConstantExpression.java @@ -17,7 +17,7 @@ public class JetConstantExpression extends JetExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitConstantExpression(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetConstructor.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetConstructor.java index 0971e9553a6..70f9846a356 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetConstructor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetConstructor.java @@ -23,7 +23,7 @@ public class JetConstructor extends JetDeclaration implements JetDeclarationWith } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitConstructor(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetContinueExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetContinueExpression.java index 4ce802eeafd..7dec7aedd95 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetContinueExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetContinueExpression.java @@ -17,7 +17,7 @@ public class JetContinueExpression extends JetLabelQualifiedExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitContinueExpression(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDecomposerPattern.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDecomposerPattern.java index c4e2bd801a4..ead61daf914 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDecomposerPattern.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDecomposerPattern.java @@ -28,7 +28,7 @@ public class JetDecomposerPattern extends JetPattern { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitDecomposerPattern(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegationSpecifier.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegationSpecifier.java index c5e8aab0c0a..915eb1f9cc9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegationSpecifier.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegationSpecifier.java @@ -19,7 +19,7 @@ public class JetDelegationSpecifier extends JetElement{ } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitDelegationSpecifier(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegationSpecifierList.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegationSpecifierList.java index cdf615c4dad..4cb02aca008 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegationSpecifierList.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegationSpecifierList.java @@ -20,7 +20,7 @@ public class JetDelegationSpecifierList extends JetElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitDelegationSpecifierList(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegatorByExpressionSpecifier.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegatorByExpressionSpecifier.java index ef5da2b1cf5..fc5740e0acc 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegatorByExpressionSpecifier.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegatorByExpressionSpecifier.java @@ -18,7 +18,7 @@ public class JetDelegatorByExpressionSpecifier extends JetDelegationSpecifier { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitDelegationByExpressionSpecifier(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegatorToSuperCall.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegatorToSuperCall.java index 91e9487a881..494c6cc196e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegatorToSuperCall.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegatorToSuperCall.java @@ -22,7 +22,7 @@ public class JetDelegatorToSuperCall extends JetDelegationSpecifier implements J } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitDelegationToSuperCallSpecifier(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegatorToSuperClass.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegatorToSuperClass.java index ef712c5eeb1..2167f6345d7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegatorToSuperClass.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegatorToSuperClass.java @@ -17,7 +17,7 @@ public class JetDelegatorToSuperClass extends JetDelegationSpecifier { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitDelegationToSuperClassSpecifier(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegatorToThisCall.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegatorToThisCall.java index 9b5501880ce..ef4c561c17d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegatorToThisCall.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDelegatorToThisCall.java @@ -23,7 +23,7 @@ public class JetDelegatorToThisCall extends JetDelegationSpecifier implements Je } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitDelegationToThisCall(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDoWhileExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDoWhileExpression.java index f2cf29fd203..35099289068 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDoWhileExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDoWhileExpression.java @@ -19,7 +19,7 @@ public class JetDoWhileExpression extends JetLoopExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitDoWhileExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDotQualifiedExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDotQualifiedExpression.java index aafeb45cb6e..97ee45d3567 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDotQualifiedExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetDotQualifiedExpression.java @@ -17,7 +17,7 @@ public class JetDotQualifiedExpression extends JetQualifiedExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitDotQualifiedExpression(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetElement.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetElement.java index 28b5c490b9a..32b7364b2ce 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetElement.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetElement.java @@ -52,7 +52,7 @@ public class JetElement extends ASTWrapperPsiElement { visitor.visitJetElement(this); } - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitJetElement(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetEnumEntry.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetEnumEntry.java index a79f256c18c..53e8c4c798e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetEnumEntry.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetEnumEntry.java @@ -52,7 +52,7 @@ public class JetEnumEntry extends JetClass { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitEnumEntry(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetEscapeStringTemplateEntry.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetEscapeStringTemplateEntry.java index d483a9ba8ba..b6e02d80088 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetEscapeStringTemplateEntry.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetEscapeStringTemplateEntry.java @@ -18,7 +18,7 @@ public class JetEscapeStringTemplateEntry extends JetStringTemplateEntry { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitEscapeStringTemplateEntry(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetExpression.java index 82864490542..aec7c357d8c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetExpression.java @@ -18,7 +18,7 @@ public abstract class JetExpression extends JetElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetExpressionPattern.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetExpressionPattern.java index fdd02ead63c..f5d19ae808a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetExpressionPattern.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetExpressionPattern.java @@ -23,7 +23,7 @@ public class JetExpressionPattern extends JetPattern { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitExpressionPattern(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetFinallySection.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetFinallySection.java index 3c62dfebd7d..a84b0784185 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetFinallySection.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetFinallySection.java @@ -18,7 +18,7 @@ public class JetFinallySection extends JetElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitFinallySection(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetForExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetForExpression.java index ef650988dc2..b9a2958ec86 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetForExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetForExpression.java @@ -19,7 +19,7 @@ public class JetForExpression extends JetLoopExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitForExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetFunctionLiteralExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetFunctionLiteralExpression.java index efed8a90e56..a9d6ebd25bf 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetFunctionLiteralExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetFunctionLiteralExpression.java @@ -20,7 +20,7 @@ public class JetFunctionLiteralExpression extends JetExpression implements JetDe } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitFunctionLiteralExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetFunctionType.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetFunctionType.java index 572212e6392..aaeffa8262b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetFunctionType.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetFunctionType.java @@ -45,7 +45,7 @@ public class JetFunctionType extends JetTypeElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitFunctionType(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetHashQualifiedExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetHashQualifiedExpression.java index 8f48c5d5a9e..07edb5c27cb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetHashQualifiedExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetHashQualifiedExpression.java @@ -17,7 +17,7 @@ public class JetHashQualifiedExpression extends JetQualifiedExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitHashQualifiedExpression(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetIfExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetIfExpression.java index 59b6ba9207f..87e1d40d7fe 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetIfExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetIfExpression.java @@ -19,7 +19,7 @@ public class JetIfExpression extends JetExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitIfExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetImportDirective.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetImportDirective.java index aa289179417..fbf5d660496 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetImportDirective.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetImportDirective.java @@ -20,7 +20,7 @@ public class JetImportDirective extends JetElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitImportDirective(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetInitializerList.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetInitializerList.java index 7c161114e0f..f8c90eb3723 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetInitializerList.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetInitializerList.java @@ -20,7 +20,7 @@ public class JetInitializerList extends JetElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitInitializerList(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetIsExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetIsExpression.java index a88fe3dd204..53c35a86f45 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetIsExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetIsExpression.java @@ -20,7 +20,7 @@ public class JetIsExpression extends JetExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitIsExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetLiteralStringTemplateEntry.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetLiteralStringTemplateEntry.java index 0f3317acbc5..5933068ce2e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetLiteralStringTemplateEntry.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetLiteralStringTemplateEntry.java @@ -17,7 +17,7 @@ public class JetLiteralStringTemplateEntry extends JetStringTemplateEntry { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitLiteralStringTemplateEntry(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetModifierList.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetModifierList.java index 2c5e47472c5..f7dcb83d990 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetModifierList.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetModifierList.java @@ -25,7 +25,7 @@ public class JetModifierList extends JetElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitModifierList(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamedFunction.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamedFunction.java index 5d791fbe2a4..34e96ce83b9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamedFunction.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamedFunction.java @@ -19,7 +19,7 @@ public class JetNamedFunction extends JetFunction { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitNamedFunction(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamespace.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamespace.java index c73621199b9..c39ea7481d9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamespace.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamespace.java @@ -24,7 +24,7 @@ public class JetNamespace extends JetNamedDeclaration { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitNamespace(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamespaceBody.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamespaceBody.java index 9004b90ddc5..8d67525d104 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamespaceBody.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNamespaceBody.java @@ -24,7 +24,7 @@ public class JetNamespaceBody extends JetElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitNamespaceBody(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNullableType.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNullableType.java index 0e1e049da29..5884b0c1904 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNullableType.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetNullableType.java @@ -31,7 +31,7 @@ public class JetNullableType extends JetTypeElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitNullableType(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetObjectDeclaration.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetObjectDeclaration.java index e3b91196931..27bea8777bd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetObjectDeclaration.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetObjectDeclaration.java @@ -84,7 +84,7 @@ public class JetObjectDeclaration extends JetNamedDeclaration implements JetClas } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitObjectDeclaration(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetObjectLiteralExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetObjectLiteralExpression.java index d62bbc143b3..e844ceba418 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetObjectLiteralExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetObjectLiteralExpression.java @@ -18,7 +18,7 @@ public class JetObjectLiteralExpression extends JetExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitObjectLiteralExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetParameter.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetParameter.java index f37cb380e55..44c6cbfc276 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetParameter.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetParameter.java @@ -20,7 +20,7 @@ public class JetParameter extends JetNamedDeclaration { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitParameter(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetParameterList.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetParameterList.java index 7241f612545..4521e52c9d9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetParameterList.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetParameterList.java @@ -20,7 +20,7 @@ public class JetParameterList extends JetElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitParameterList(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetParenthesizedExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetParenthesizedExpression.java index 778deab905b..c17b0f82006 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetParenthesizedExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetParenthesizedExpression.java @@ -18,7 +18,7 @@ public class JetParenthesizedExpression extends JetExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitParenthesizedExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPostfixExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPostfixExpression.java index 01b31f87a63..e98eeb230d6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPostfixExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPostfixExpression.java @@ -24,7 +24,7 @@ public class JetPostfixExpression extends JetUnaryExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitPostfixExpression(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPredicateExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPredicateExpression.java index 8f4f83737de..b4841a7026f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPredicateExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPredicateExpression.java @@ -17,7 +17,7 @@ public class JetPredicateExpression extends JetQualifiedExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitPredicateExpression(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPrefixExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPrefixExpression.java index d728fc9a519..105bde689f8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPrefixExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPrefixExpression.java @@ -19,7 +19,7 @@ public class JetPrefixExpression extends JetUnaryExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitPrefixExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetProperty.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetProperty.java index 6e5b0f476ec..ccacaa8a4d4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetProperty.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetProperty.java @@ -31,7 +31,7 @@ public class JetProperty extends JetTypeParameterListOwner implements JetModifie } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitProperty(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPropertyAccessor.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPropertyAccessor.java index 6cf67771acb..f2d86e0037c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPropertyAccessor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPropertyAccessor.java @@ -24,7 +24,7 @@ public class JetPropertyAccessor extends JetDeclaration implements JetDeclaratio } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitPropertyAccessor(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetReturnExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetReturnExpression.java index 49634944ae2..396a0f22515 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetReturnExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetReturnExpression.java @@ -18,7 +18,7 @@ public class JetReturnExpression extends JetLabelQualifiedExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitReturnExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetRootNamespaceExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetRootNamespaceExpression.java index 0cb69e2fbb0..1a0684687e8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetRootNamespaceExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetRootNamespaceExpression.java @@ -17,7 +17,7 @@ public class JetRootNamespaceExpression extends JetExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitRootNamespaceExpression(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSafeQualifiedExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSafeQualifiedExpression.java index e2e6bba5c1a..9925e0b287b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSafeQualifiedExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSafeQualifiedExpression.java @@ -17,7 +17,7 @@ public class JetSafeQualifiedExpression extends JetQualifiedExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitSafeQualifiedExpression(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSelfType.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSelfType.java index 84ae4b5a7e0..a0fb8eb5eec 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSelfType.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSelfType.java @@ -26,7 +26,7 @@ public class JetSelfType extends JetTypeElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitSelfType(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.java index 1f1720abbf5..c40c07518a3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameExpression.java @@ -62,7 +62,7 @@ public class JetSimpleNameExpression extends JetReferenceExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitSimpleNameExpression(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameStringTemplateEntry.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameStringTemplateEntry.java index fd0384608e1..0c6be87a502 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameStringTemplateEntry.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetSimpleNameStringTemplateEntry.java @@ -18,7 +18,7 @@ public class JetSimpleNameStringTemplateEntry extends JetStringTemplateEntryWith } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitSimpleNameStringTemplateEntry(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetStringTemplateEntryWithExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetStringTemplateEntryWithExpression.java index 4e86ff3103b..4b4ed92ac4e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetStringTemplateEntryWithExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetStringTemplateEntryWithExpression.java @@ -17,7 +17,7 @@ public abstract class JetStringTemplateEntryWithExpression extends JetStringTemp } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitStringTemplateEntryWithExpression(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetStringTemplateExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetStringTemplateExpression.java index e63f1f94c60..6c8957642fa 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetStringTemplateExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetStringTemplateExpression.java @@ -17,7 +17,7 @@ public class JetStringTemplateExpression extends JetExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitStringTemplateExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetThisExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetThisExpression.java index b3e000ee32a..eb176aa19bd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetThisExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetThisExpression.java @@ -20,7 +20,7 @@ public class JetThisExpression extends JetLabelQualifiedExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitThisExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetThrowExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetThrowExpression.java index 20015feb07b..17b1ae020df 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetThrowExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetThrowExpression.java @@ -18,7 +18,7 @@ public class JetThrowExpression extends JetExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitThrowExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTreeVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTreeVisitor.java index 8b88df1f4ff..d343f8bccf8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTreeVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTreeVisitor.java @@ -10,11 +10,11 @@ public class JetTreeVisitor extends JetVisitor { public Void visitNamespace(JetNamespace namespace, D data) { List importDirectives = namespace.getImportDirectives(); for (JetImportDirective directive : importDirectives) { - directive.visit(this, data); + directive.accept(this, data); } List declarations = namespace.getDeclarations(); for (JetDeclaration declaration : declarations) { - declaration.visit(this, data); + declaration.accept(this, data); } return null; } @@ -23,7 +23,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitClass(JetClass klass, D data) { List declarations = klass.getDeclarations(); for (JetDeclaration declaration : declarations) { - declaration.visit(this, data); + declaration.accept(this, data); } return null; } @@ -32,7 +32,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitClassObject(JetClassObject classObject, D data) { JetObjectDeclaration objectDeclaration = classObject.getObjectDeclaration(); if (objectDeclaration != null) { - objectDeclaration.visit(this, data); + objectDeclaration.accept(this, data); } return null; } @@ -53,11 +53,11 @@ public class JetTreeVisitor extends JetVisitor { public Void visitProperty(JetProperty property, D data) { List accessors = property.getAccessors(); for (JetPropertyAccessor accessor : accessors) { - accessor.visit(this, data); + accessor.accept(this, data); } JetExpression initializer = property.getInitializer(); if (initializer != null) { - initializer.visit(this, data); + initializer.accept(this, data); } return null; } @@ -70,7 +70,7 @@ public class JetTreeVisitor extends JetVisitor { @Override public Void visitJetFile(JetFile file, D data) { JetNamespace rootNamespace = file.getRootNamespace(); - return rootNamespace.visit(this, data); + return rootNamespace.accept(this, data); } @Override @@ -82,11 +82,11 @@ public class JetTreeVisitor extends JetVisitor { public Void visitClassBody(JetClassBody classBody, D data) { List declarations = classBody.getDeclarations(); for (JetDeclaration declaration : declarations) { - declaration.visit(this, data); + declaration.accept(this, data); } List secondaryConstructors = classBody.getSecondaryConstructors(); for (JetConstructor constructor : secondaryConstructors) { - constructor.visit(this, data); + constructor.accept(this, data); } return null; } @@ -95,7 +95,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitNamespaceBody(JetNamespaceBody body, D data) { List declarations = body.getDeclarations(); for (JetDeclaration declaration : declarations) { - declaration.visit(this, data); + declaration.accept(this, data); } return null; } @@ -119,7 +119,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitTypeParameterList(JetTypeParameterList list, D data) { List parameters = list.getParameters(); for (JetTypeParameter parameter : parameters) { - parameter.visit(this, data); + parameter.accept(this, data); } return null; } @@ -133,11 +133,11 @@ public class JetTreeVisitor extends JetVisitor { public Void visitEnumEntry(JetEnumEntry enumEntry, D data) { List delegationSpecifiers = enumEntry.getDelegationSpecifiers(); for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) { - delegationSpecifier.visit(this, data); + delegationSpecifier.accept(this, data); } JetModifierList modifierList = enumEntry.getModifierList(); if (modifierList != null) { - modifierList.visit(this, data); + modifierList.accept(this, data); } return null; } @@ -146,7 +146,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitParameterList(JetParameterList list, D data) { List parameters = list.getParameters(); for (JetParameter parameter : parameters) { - parameter.visit(this, data); + parameter.accept(this, data); } return null; } @@ -160,7 +160,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitDelegationSpecifierList(JetDelegationSpecifierList list, D data) { List delegationSpecifiers = list.getDelegationSpecifiers(); for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) { - delegationSpecifier.visit(this, data); + delegationSpecifier.accept(this, data); } return null; } @@ -199,7 +199,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitValueArgumentList(JetValueArgumentList list, D data) { List arguments = list.getArguments(); for (JetValueArgument argument : arguments) { - argument.visit(this, data); + argument.accept(this, data); } return null; } @@ -213,7 +213,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitLoopExpression(JetLoopExpression loopExpression, D data) { JetExpression body = loopExpression.getBody(); if (body != null) { - body.visit(this, data); + body.accept(this, data); } return null; } @@ -242,7 +242,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitPrefixExpression(JetPrefixExpression expression, D data) { JetExpression baseExpression = expression.getBaseExpression(); if (baseExpression != null) { - baseExpression.visit(this, data); + baseExpression.accept(this, data); } return null; } @@ -250,7 +250,7 @@ public class JetTreeVisitor extends JetVisitor { @Override public Void visitPostfixExpression(JetPostfixExpression expression, D data) { JetExpression baseExpression = expression.getBaseExpression(); - baseExpression.visit(this, data); + baseExpression.accept(this, data); return null; } @@ -258,17 +258,17 @@ public class JetTreeVisitor extends JetVisitor { public Void visitUnaryExpression(JetUnaryExpression expression, D data) { JetExpression baseExpression = expression.getBaseExpression(); assert baseExpression != null; - baseExpression.visit(this, data); + baseExpression.accept(this, data); return null; } @Override public Void visitBinaryExpression(JetBinaryExpression expression, D data) { JetExpression left = expression.getLeft(); - left.visit(this, data); + left.accept(this, data); JetExpression right = expression.getRight(); if (right != null) { - right.visit(this, data); + right.accept(this, data); } return super.visitBinaryExpression(expression, data); } @@ -277,7 +277,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitReturnExpression(JetReturnExpression expression, D data) { JetExpression returnedExpression = expression.getReturnedExpression(); if (returnedExpression != null) { - returnedExpression.visit(this, data); + returnedExpression.accept(this, data); } return null; } @@ -286,7 +286,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitLabelQualifiedExpression(JetLabelQualifiedExpression expression, D data) { JetExpression labeledExpression = expression.getLabeledExpression(); if (labeledExpression != null) { - labeledExpression.visit(this, data); + labeledExpression.accept(this, data); } return null; } @@ -295,7 +295,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitThrowExpression(JetThrowExpression expression, D data) { JetExpression thrownExpression = expression.getThrownExpression(); if (thrownExpression != null) { - thrownExpression.visit(this, data); + thrownExpression.accept(this, data); } return null; } @@ -314,15 +314,15 @@ public class JetTreeVisitor extends JetVisitor { public Void visitIfExpression(JetIfExpression expression, D data) { JetExpression condition = expression.getCondition(); if (condition != null) { - condition.visit(this, data); + condition.accept(this, data); } JetExpression then = expression.getThen(); if (then != null) { - then.visit(this, data); + then.accept(this, data); } JetExpression anElse = expression.getElse(); if (anElse != null) { - anElse.visit(this, data); + anElse.accept(this, data); } return null; } @@ -331,11 +331,11 @@ public class JetTreeVisitor extends JetVisitor { public Void visitWhenExpression(JetWhenExpression expression, D data) { List entries = expression.getEntries(); for (JetWhenEntry entry : entries) { - entry.visit(this, data); + entry.accept(this, data); } JetExpression subjectExpression = expression.getSubjectExpression(); if (subjectExpression != null) { - subjectExpression.visit(this, data); + subjectExpression.accept(this, data); } return null; } @@ -343,14 +343,14 @@ public class JetTreeVisitor extends JetVisitor { @Override public Void visitTryExpression(JetTryExpression expression, D data) { JetBlockExpression tryBlock = expression.getTryBlock(); - tryBlock.visit(this, data); + tryBlock.accept(this, data); List catchClauses = expression.getCatchClauses(); for (JetCatchClause catchClause : catchClauses) { - catchClause.visit(this, data); + catchClause.accept(this, data); } JetFinallySection finallyBlock = expression.getFinallyBlock(); if (finallyBlock != null) { - finallyBlock.visit(this, data); + finallyBlock.accept(this, data); } return null; } @@ -359,11 +359,11 @@ public class JetTreeVisitor extends JetVisitor { public Void visitForExpression(JetForExpression expression, D data) { JetParameter loopParameter = expression.getLoopParameter(); if (loopParameter != null) { - loopParameter.visit(this, data); + loopParameter.accept(this, data); } JetExpression loopRange = expression.getLoopRange(); if (loopRange != null) { - loopRange.visit(this, data); + loopRange.accept(this, data); } visitLoopExpression(expression, data); return null; @@ -373,7 +373,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitWhileExpression(JetWhileExpression expression, D data) { JetExpression condition = expression.getCondition(); if (condition != null) { - condition.visit(this, data); + condition.accept(this, data); } visitLoopExpression(expression, data); return null; @@ -383,7 +383,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitDoWhileExpression(JetDoWhileExpression expression, D data) { JetExpression condition = expression.getCondition(); if (condition != null) { - condition.visit(this, data); + condition.accept(this, data); } visitLoopExpression(expression, data); return null; @@ -392,7 +392,7 @@ public class JetTreeVisitor extends JetVisitor { @Override public Void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression, D data) { JetFunctionLiteral functionLiteral = expression.getFunctionLiteral(); - functionLiteral.visit(this, data); + functionLiteral.accept(this, data); visitDeclarationWithBody(expression, data); return null; } @@ -400,7 +400,7 @@ public class JetTreeVisitor extends JetVisitor { @Override public Void visitAnnotatedExpression(JetAnnotatedExpression expression, D data) { JetExpression baseExpression = expression.getBaseExpression(); - baseExpression.visit(this, data); + baseExpression.accept(this, data); return null; } @@ -408,7 +408,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitCallExpression(JetCallExpression expression, D data) { JetExpression calleeExpression = expression.getCalleeExpression(); if (calleeExpression != null) { - calleeExpression.visit(this, data); + calleeExpression.accept(this, data); } return null; } @@ -416,10 +416,10 @@ public class JetTreeVisitor extends JetVisitor { @Override public Void visitArrayAccessExpression(JetArrayAccessExpression expression, D data) { JetExpression arrayExpression = expression.getArrayExpression(); - arrayExpression.visit(this, data); + arrayExpression.accept(this, data); List indexExpressions = expression.getIndexExpressions(); for (JetExpression indexExpression : indexExpressions) { - indexExpression.visit(this, data); + indexExpression.accept(this, data); } return null; } @@ -427,10 +427,10 @@ public class JetTreeVisitor extends JetVisitor { @Override public Void visitQualifiedExpression(JetQualifiedExpression expression, D data) { JetExpression receiver = expression.getReceiverExpression(); - receiver.visit(this, data); + receiver.accept(this, data); JetExpression selector = expression.getSelectorExpression(); if (selector != null) { - selector.visit(this, data); + selector.accept(this, data); } return null; } @@ -462,7 +462,7 @@ public class JetTreeVisitor extends JetVisitor { @Override public Void visitObjectLiteralExpression(JetObjectLiteralExpression expression, D data) { JetObjectDeclaration objectDeclaration = expression.getObjectDeclaration(); - objectDeclaration.visit(this, data); + objectDeclaration.accept(this, data); return null; } @@ -475,7 +475,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitBlockExpression(JetBlockExpression expression, D data) { List statements = expression.getStatements(); for (JetElement statement : statements) { - statement.visit(this, data); + statement.accept(this, data); } return null; } @@ -484,11 +484,11 @@ public class JetTreeVisitor extends JetVisitor { public Void visitCatchSection(JetCatchClause catchClause, D data) { JetParameter catchParameter = catchClause.getCatchParameter(); if (catchParameter != null) { - catchParameter.visit(this, data); + catchParameter.accept(this, data); } JetExpression catchBody = catchClause.getCatchBody(); if (catchBody != null) { - catchBody.visit(this, data); + catchBody.accept(this, data); } return null; } @@ -496,7 +496,7 @@ public class JetTreeVisitor extends JetVisitor { @Override public Void visitFinallySection(JetFinallySection finallySection, D data) { JetBlockExpression finalExpression = finallySection.getFinalExpression(); - finalExpression.visit(this, data); + finalExpression.accept(this, data); return null; } @@ -504,7 +504,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitTypeArgumentList(JetTypeArgumentList typeArgumentList, D data) { List arguments = typeArgumentList.getArguments(); for (JetTypeProjection argument : arguments) { - argument.visit(this, data); + argument.accept(this, data); } return null; } @@ -512,10 +512,10 @@ public class JetTreeVisitor extends JetVisitor { @Override public Void visitThisExpression(JetThisExpression expression, D data) { JetReferenceExpression thisReference = expression.getThisReference(); - thisReference.visit(this, data); + thisReference.accept(this, data); JetTypeReference superTypeQualifier = expression.getSuperTypeQualifier(); if (superTypeQualifier != null) { - superTypeQualifier.visit(this, data); + superTypeQualifier.accept(this, data); } visitLabelQualifiedExpression(expression, data); return null; @@ -525,7 +525,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitParenthesizedExpression(JetParenthesizedExpression expression, D data) { JetExpression innerExpression = expression.getExpression(); if (innerExpression != null) { - innerExpression.visit(this, data); + innerExpression.accept(this, data); } return null; } @@ -534,7 +534,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitInitializerList(JetInitializerList list, D data) { List initializers = list.getInitializers(); for (JetDelegationSpecifier initializer : initializers) { - initializer.visit(this, data); + initializer.accept(this, data); } return null; } @@ -542,7 +542,7 @@ public class JetTreeVisitor extends JetVisitor { @Override public Void visitAnonymousInitializer(JetClassInitializer initializer, D data) { JetExpression body = initializer.getBody(); - body.visit(this, data); + body.accept(this, data); return null; } @@ -556,7 +556,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitTypeConstraintList(JetTypeConstraintList list, D data) { List constraints = list.getConstraints(); for (JetTypeConstraint constraint : constraints) { - constraint.visit(this, data); + constraint.accept(this, data); } return null; } @@ -565,7 +565,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitTypeConstraint(JetTypeConstraint constraint, D data) { JetSimpleNameExpression subjectTypeParameterName = constraint.getSubjectTypeParameterName(); if (subjectTypeParameterName != null) { - subjectTypeParameterName.visit(this, data); + subjectTypeParameterName.accept(this, data); } return null; } @@ -593,10 +593,10 @@ public class JetTreeVisitor extends JetVisitor { @Override public Void visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression, D data) { JetExpression left = expression.getLeft(); - left.visit(this, data); + left.accept(this, data); JetTypeReference right = expression.getRight(); if (right != null) { - right.visit(this, data); + right.accept(this, data); } return null; } @@ -605,7 +605,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitStringTemplateExpression(JetStringTemplateExpression expression, D data) { JetStringTemplateEntry[] entries = expression.getEntries(); for (JetStringTemplateEntry entry : entries) { - entry.visit(this, data); + entry.accept(this, data); } return null; } @@ -629,11 +629,11 @@ public class JetTreeVisitor extends JetVisitor { public Void visitWhenEntry(JetWhenEntry jetWhenEntry, D data) { JetExpression expression = jetWhenEntry.getExpression(); if (expression != null) { - expression.visit(this, data); + expression.accept(this, data); } JetWhenCondition[] conditions = jetWhenEntry.getConditions(); for (JetWhenCondition condition : conditions) { - condition.visit(this, data); + condition.accept(this, data); } return null; } @@ -641,12 +641,12 @@ public class JetTreeVisitor extends JetVisitor { @Override public Void visitIsExpression(JetIsExpression expression, D data) { JetExpression leftHandSide = expression.getLeftHandSide(); - leftHandSide.visit(this, data); + leftHandSide.accept(this, data); JetSimpleNameExpression operationReference = expression.getOperationReference(); - operationReference.visit(this, data); + operationReference.accept(this, data); JetPattern pattern = expression.getPattern(); if (pattern != null) { - pattern.visit(this, data); + pattern.accept(this, data); } return null; } @@ -655,7 +655,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitWhenConditionCall(JetWhenConditionCall condition, D data) { JetExpression callSuffixExpression = condition.getCallSuffixExpression(); if (callSuffixExpression != null) { - callSuffixExpression.visit(this, data); + callSuffixExpression.accept(this, data); } return null; } @@ -664,7 +664,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitWhenConditionIsPattern(JetWhenConditionIsPattern condition, D data) { JetPattern pattern = condition.getPattern(); if (pattern != null) { - pattern.visit(this, data); + pattern.accept(this, data); } return null; } @@ -672,10 +672,10 @@ public class JetTreeVisitor extends JetVisitor { @Override public Void visitWhenConditionInRange(JetWhenConditionInRange condition, D data) { JetSimpleNameExpression operationReference = condition.getOperationReference(); - operationReference.visit(this, data); + operationReference.accept(this, data); JetExpression rangeExpression = condition.getRangeExpression(); if (rangeExpression != null) { - rangeExpression.visit(this, data); + rangeExpression.accept(this, data); } return null; } @@ -694,7 +694,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitExpressionPattern(JetExpressionPattern pattern, D data) { JetExpression expression = pattern.getExpression(); if (expression != null) { - expression.visit(this, data); + expression.accept(this, data); } return null; } @@ -703,7 +703,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitTuplePattern(JetTuplePattern pattern, D data) { List entries = pattern.getEntries(); for (JetTuplePatternEntry entry : entries) { - entry.visit(this, data); + entry.accept(this, data); } return null; } @@ -711,10 +711,10 @@ public class JetTreeVisitor extends JetVisitor { @Override public Void visitDecomposerPattern(JetDecomposerPattern pattern, D data) { JetTuplePattern argumentList = pattern.getArgumentList(); - argumentList.visit(this, data); + argumentList.accept(this, data); JetExpression decomposerExpression = pattern.getDecomposerExpression(); if (decomposerExpression != null) { - decomposerExpression.visit(this, data); + decomposerExpression.accept(this, data); } return null; } @@ -723,11 +723,11 @@ public class JetTreeVisitor extends JetVisitor { public Void visitObjectDeclaration(JetObjectDeclaration objectDeclaration, D data) { List declarations = objectDeclaration.getDeclarations(); for (JetDeclaration declaration : declarations) { - declaration.visit(this, data); + declaration.accept(this, data); } JetDelegationSpecifierList delegationSpecifierList = objectDeclaration.getDelegationSpecifierList(); if (delegationSpecifierList != null) { - delegationSpecifierList.visit(this, data); + delegationSpecifierList.accept(this, data); } return null; } @@ -736,10 +736,10 @@ public class JetTreeVisitor extends JetVisitor { public Void visitBindingPattern(JetBindingPattern pattern, D data) { JetWhenCondition condition = pattern.getCondition(); if (condition != null) { - condition.visit(this, data); + condition.accept(this, data); } JetProperty variableDeclaration = pattern.getVariableDeclaration(); - variableDeclaration.visit(this, data); + variableDeclaration.accept(this, data); return null; } @@ -747,7 +747,7 @@ public class JetTreeVisitor extends JetVisitor { public Void visitStringTemplateEntry(JetStringTemplateEntry entry, D data) { JetExpression expression = entry.getExpression(); if (expression != null) { - expression.visit(this, data); + expression.accept(this, data); } return null; } @@ -785,11 +785,11 @@ public class JetTreeVisitor extends JetVisitor { private Void visitDeclarationWithBody(JetDeclarationWithBody declaration, D data) { JetExpression bodyExpression = declaration.getBodyExpression(); if (bodyExpression != null) { - bodyExpression.visit(this, data); + bodyExpression.accept(this, data); } List valueParameters = declaration.getValueParameters(); for (JetParameter valueParameter : valueParameters) { - valueParameter.visit(this, data); + valueParameter.accept(this, data); } return null; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTryExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTryExpression.java index 260c91b0edb..9ea26611104 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTryExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTryExpression.java @@ -21,7 +21,7 @@ public class JetTryExpression extends JetExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitTryExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTupleExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTupleExpression.java index 3d7f5f1db2a..8f8f0591898 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTupleExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTupleExpression.java @@ -20,7 +20,7 @@ public class JetTupleExpression extends JetExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitTupleExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTuplePattern.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTuplePattern.java index e49b5e4382d..ec579524111 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTuplePattern.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTuplePattern.java @@ -20,7 +20,7 @@ public class JetTuplePattern extends JetPattern { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitTuplePattern(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTupleType.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTupleType.java index ac399480d51..7c85bd6e652 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTupleType.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTupleType.java @@ -26,7 +26,7 @@ public class JetTupleType extends JetTypeElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitTupleType(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeArgumentList.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeArgumentList.java index 94e26b989c7..3ffa10bbd68 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeArgumentList.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeArgumentList.java @@ -20,7 +20,7 @@ public class JetTypeArgumentList extends JetElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitTypeArgumentList(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeConstraint.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeConstraint.java index 90800e0f06d..d80890275c4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeConstraint.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeConstraint.java @@ -21,7 +21,7 @@ public class JetTypeConstraint extends JetElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitTypeConstraint(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeConstraintList.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeConstraintList.java index fc0c340a9b5..96f2ca115dc 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeConstraintList.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeConstraintList.java @@ -20,7 +20,7 @@ public class JetTypeConstraintList extends JetElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitTypeConstraintList(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeParameter.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeParameter.java index 5eb5c4a1077..49cefebb7ab 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeParameter.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeParameter.java @@ -21,7 +21,7 @@ public class JetTypeParameter extends JetNamedDeclaration { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitTypeParameter(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeParameterList.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeParameterList.java index ff36bf50b78..a21d3168750 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeParameterList.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeParameterList.java @@ -24,7 +24,7 @@ public class JetTypeParameterList extends JetElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitTypeParameterList(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypePattern.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypePattern.java index 6e5a7bb3d4d..1c8ccf27699 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypePattern.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypePattern.java @@ -23,7 +23,7 @@ public class JetTypePattern extends JetPattern { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitTypePattern(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeProjection.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeProjection.java index ba46a0f20d7..a182f57135a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeProjection.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeProjection.java @@ -33,7 +33,7 @@ public class JetTypeProjection extends JetDeclaration { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitTypeProjection(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeReference.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeReference.java index 1554f3971ff..faf32b925fd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeReference.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypeReference.java @@ -23,7 +23,7 @@ public class JetTypeReference extends JetElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitTypeReference(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypedef.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypedef.java index b2aabee2c4e..751fcffefb3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypedef.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetTypedef.java @@ -19,7 +19,7 @@ public class JetTypedef extends JetTypeParameterListOwner { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitTypedef(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetUserType.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetUserType.java index 37d24fe1989..5c754b83ed1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetUserType.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetUserType.java @@ -28,7 +28,7 @@ public class JetUserType extends JetTypeElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitUserType(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetValueArgument.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetValueArgument.java index 6a60a1088af..97cd551c0ed 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetValueArgument.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetValueArgument.java @@ -20,7 +20,7 @@ public class JetValueArgument extends JetElement implements ValueArgument { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitArgument(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetValueArgumentList.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetValueArgumentList.java index f8d90abc36f..8d8f3ff4420 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetValueArgumentList.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetValueArgumentList.java @@ -20,7 +20,7 @@ public class JetValueArgumentList extends JetElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitValueArgumentList(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenConditionCall.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenConditionCall.java index bca851832d2..c74e0ea6acb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenConditionCall.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenConditionCall.java @@ -34,7 +34,7 @@ public class JetWhenConditionCall extends JetWhenCondition { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitWhenConditionCall(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenConditionInRange.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenConditionInRange.java index ba59a80409e..3294c74864e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenConditionInRange.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenConditionInRange.java @@ -40,7 +40,7 @@ public class JetWhenConditionInRange extends JetWhenCondition { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitWhenConditionInRange(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenConditionIsPattern.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenConditionIsPattern.java index 3b91e459b1f..69d2caca197 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenConditionIsPattern.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenConditionIsPattern.java @@ -28,7 +28,7 @@ public class JetWhenConditionIsPattern extends JetWhenCondition { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitWhenConditionIsPattern(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenEntry.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenEntry.java index b6342d90725..d4adc5210a1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenEntry.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenEntry.java @@ -28,7 +28,7 @@ public class JetWhenEntry extends JetElement { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitWhenEntry(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenExpression.java index 7e2a85c303a..97c736e507c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenExpression.java @@ -31,7 +31,7 @@ public class JetWhenExpression extends JetExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitWhenExpression(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhileExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhileExpression.java index 3d4670881df..228190bdfc7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhileExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhileExpression.java @@ -19,7 +19,7 @@ public class JetWhileExpression extends JetLoopExpression { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitWhileExpression(this, data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWildcardPattern.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWildcardPattern.java index f0fdaf33197..f0cdaccbb85 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWildcardPattern.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWildcardPattern.java @@ -17,7 +17,7 @@ public class JetWildcardPattern extends JetPattern { } @Override - public R visit(@NotNull JetVisitor visitor, D data) { + public R accept(@NotNull JetVisitor visitor, D data) { return visitor.visitWildcardPattern(this, data); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index f93aa8f4bb0..1eba532f34c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -9,12 +9,14 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.calls.CallMaker; +import org.jetbrains.jet.lang.resolve.calls.CallResolver; +import org.jetbrains.jet.lang.resolve.calls.DataFlowInfo; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.*; -import org.jetbrains.jet.lang.types.expressions.ExpressionTyperServices; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.util.lazy.ReenteringLazyValueComputationException; import org.jetbrains.jet.util.slicedmap.WritableSlice; @@ -127,7 +129,7 @@ public class BodyResolver { final JetScope scopeForConstructor = primaryConstructor == null ? null : getInnerScopeForConstructor(primaryConstructor, descriptor.getScopeForMemberResolution(), true); - final ExpressionTyperServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors); // TODO : flow + final ExpressionTypingServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors); // TODO : flow final Map supertypes = Maps.newLinkedHashMap(); JetVisitorVoid visitor = new JetVisitorVoid() { @@ -174,7 +176,7 @@ public class BodyResolver { JetTypeReference typeReference = call.getTypeReference(); if (typeReference != null) { if (descriptor.getUnsubstitutedPrimaryConstructor() != null) { - JetType supertype = typeInferrer.getCallResolver().resolveCall( + JetType supertype = new CallResolver(context.getSemanticServices(), DataFlowInfo.getEmpty()).resolveCall( context.getTrace(), scopeForConstructor, CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, call), NO_EXPECTED_TYPE); if (supertype != null) { @@ -294,7 +296,7 @@ public class BodyResolver { ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor(); assert primaryConstructor != null; final JetScope scopeForConstructor = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true); - ExpressionTyperServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(createFieldAssignTrackingTrace()); // TODO : flow + ExpressionTypingServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(createFieldAssignTrackingTrace()); // TODO : flow for (JetClassInitializer anonymousInitializer : anonymousInitializers) { typeInferrer.getType(scopeForConstructor, anonymousInitializer.getBody(), NO_EXPECTED_TYPE); } @@ -320,7 +322,7 @@ public class BodyResolver { private void resolveSecondaryConstructorBody(JetConstructor declaration, final ConstructorDescriptor descriptor, final JetScope declaringScope) { final JetScope functionInnerScope = getInnerScopeForConstructor(descriptor, declaringScope, false); - final ExpressionTyperServices typeInferrerForInitializers = context.getSemanticServices().getTypeInferrerServices(traceForConstructors); + final CallResolver callResolver = new CallResolver(context.getSemanticServices(), DataFlowInfo.getEmpty()); // TODO: dataFlowInfo JetClass containingClass = PsiTreeUtil.getParentOfType(declaration, JetClass.class); assert containingClass != null : "This must be guaranteed by the parser"; @@ -338,7 +340,7 @@ public class BodyResolver { public void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call) { JetTypeReference typeReference = call.getTypeReference(); if (typeReference != null) { - typeInferrerForInitializers.getCallResolver().resolveCall(context.getTrace(), functionInnerScope, + callResolver.resolveCall(context.getTrace(), functionInnerScope, CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, call), NO_EXPECTED_TYPE); } } @@ -349,7 +351,7 @@ public class BodyResolver { // TODO : check: if a this() call is present, no other initializers are allowed ClassDescriptor classDescriptor = descriptor.getContainingDeclaration(); - typeInferrerForInitializers.getCallResolver().resolveCall(context.getTrace(), + callResolver.resolveCall(context.getTrace(), functionInnerScope, CallMaker.makeCall(ReceiverDescriptor.NO_RECEIVER, null, call), NO_EXPECTED_TYPE); // call.getThisReference(), @@ -384,9 +386,9 @@ public class BodyResolver { if (bodyExpression != null) { //context.getClassDescriptorResolver().computeFlowData(declaration, bodyExpression); //JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(declaration, bodyExpression); - ExpressionTyperServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors); + ExpressionTypingServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors); - typeInferrer.checkFunctionReturnType(functionInnerScope, declaration, descriptor, JetStandardClasses.getUnitType()); + typeInferrer.checkFunctionReturnType(functionInnerScope, declaration, JetStandardClasses.getUnitType()); } } @@ -522,7 +524,7 @@ public class BodyResolver { private void resolvePropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, JetExpression initializer, JetScope scope) { //JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(property, initializer); // TODO : flow JET-15 - ExpressionTyperServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors); + ExpressionTypingServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors); JetType type = typeInferrer.getType(getPropertyDeclarationInnerScope(scope, propertyDescriptor), initializer, NO_EXPECTED_TYPE); JetType expectedType = propertyDescriptor.getInType(); @@ -558,12 +560,12 @@ public class BodyResolver { JetExpression bodyExpression = function.getBodyExpression(); if (bodyExpression != null) { //JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(function.asElement(), bodyExpression); - ExpressionTyperServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace); + ExpressionTypingServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace); typeInferrer.checkFunctionReturnType(declaringScope, function, functionDescriptor); } - ExpressionTyperServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace); + ExpressionTypingServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace); List valueParameters = function.getValueParameters(); for (int i = 0; i < valueParameters.size(); i++) { ValueParameterDescriptor valueParameterDescriptor = functionDescriptor.getValueParameters().get(i); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java index 549bbdb129b..e799320ebd4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java @@ -10,7 +10,7 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.JetStandardClasses; import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lang.types.expressions.ExpressionTyperServices; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; import java.util.List; import java.util.Map; @@ -24,7 +24,7 @@ import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; */ public class ControlFlowAnalyzer { private TopDownAnalysisContext context; - private ExpressionTyperServices typeInferrer; + private ExpressionTypingServices typeInferrer; public ControlFlowAnalyzer(TopDownAnalysisContext context) { this.context = context; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index dce162ab638..7613f54431f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -15,7 +15,7 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; import org.jetbrains.jet.lang.resolve.scopes.WriteThroughScope; import org.jetbrains.jet.lang.types.*; -import org.jetbrains.jet.lang.types.expressions.ExpressionTyperServices; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; import org.jetbrains.jet.lexer.JetTokens; import java.util.*; @@ -218,7 +218,7 @@ public class TypeHierarchyResolver { if (importDirective.isAllUnder()) { JetExpression importedReference = importDirective.getImportedReference(); if (importedReference != null) { - ExpressionTyperServices typeInferrerServices = context.getSemanticServices().getTypeInferrerServices(context.getTrace()); + ExpressionTypingServices typeInferrerServices = context.getSemanticServices().getTypeInferrerServices(context.getTrace()); JetType type = typeInferrerServices.getTypeWithNamespaces(namespaceScope, importedReference); if (type != null) { namespaceScope.importScope(type.getMemberScope()); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/AutoCastUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/AutoCastUtils.java index a12b47f8305..63d47a2746f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/AutoCastUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/AutoCastUtils.java @@ -82,7 +82,6 @@ public class AutoCastUtils { public static JetType castExpression(@NotNull JetExpression expression, @NotNull JetType expectedType, @NotNull DataFlowInfo dataFlowInfo, @NotNull BindingTrace trace) { JetTypeChecker typeChecker = JetTypeChecker.INSTANCE; VariableDescriptor variableDescriptor = getVariableDescriptorFromSimpleName(trace.getBindingContext(), expression); -// boolean appropriateTypeFound = false; if (variableDescriptor != null) { List possibleTypes = Lists.newArrayList(dataFlowInfo.getPossibleTypesForVariable(variableDescriptor)); Collections.reverse(possibleTypes); @@ -97,24 +96,12 @@ public class AutoCastUtils { return possibleType; } } -// if (!appropriateTypeFound) { -// JetType notnullType = dataFlowInfo.getOutType(variableDescriptor); -// if (notnullType != null && typeChecker.isSubtypeOf(notnullType, expectedType)) { -// appropriateTypeFound = true; -// } -// } } return null; } @Nullable public static VariableDescriptor getVariableDescriptorFromSimpleName(@NotNull BindingContext bindingContext, @NotNull JetExpression expression) { -// if (expression instanceof JetBinaryExpressionWithTypeRHS) { -// JetBinaryExpressionWithTypeRHS expression = (JetBinaryExpressionWithTypeRHS) expression; -// if (expression.getOperationSign().getReferencedNameElementType() == JetTokens.COLON) { -// return getVariableDescriptorFromSimpleName(bindingContext, expression.getLeft()); -// } -// } JetExpression receiver = JetPsiUtil.deparenthesize(expression); VariableDescriptor variableDescriptor = null; if (receiver instanceof JetSimpleNameExpression) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index a68d72ec506..4395382f451 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -15,7 +15,7 @@ import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.*; -import org.jetbrains.jet.lang.types.expressions.ExpressionTyperServices; +import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; import org.jetbrains.jet.lang.types.expressions.OperatorConventions; import org.jetbrains.jet.lang.types.inference.ConstraintSystem; import org.jetbrains.jet.lexer.JetTokens; @@ -384,7 +384,7 @@ public class CallResolver { for (JetExpression expression : valueArgument.getArgumentExpressions()) { // JetExpression expression = valueArgument.getArgumentExpression(); // TODO : more attempts, with different expected types - ExpressionTyperServices temporaryServices = new ExpressionTyperServices(semanticServices, temporaryTrace); + ExpressionTypingServices temporaryServices = new ExpressionTypingServices(semanticServices, temporaryTrace); JetType type = temporaryServices.getType(scope, expression, NO_EXPECTED_TYPE); if (type != null) { constraintSystem.addSubtypingConstraint(type, valueParameterDescriptor.getOutType()); @@ -509,7 +509,7 @@ public class CallResolver { } private void checkTypesWithNoCallee(BindingTrace trace, JetScope scope, Call call) { - ExpressionTyperServices typeInferrerServices = new ExpressionTyperServices(semanticServices, trace); + ExpressionTypingServices typeInferrerServices = new ExpressionTypingServices(semanticServices, trace); for (ValueArgument valueArgument : call.getValueArguments()) { JetExpression argumentExpression = valueArgument.getArgumentExpression(); if (argumentExpression != null) { @@ -602,7 +602,7 @@ public class CallResolver { List argumentExpressions = resolvedArgument.getArgumentExpressions(); for (JetExpression argumentExpression : argumentExpressions) { - ExpressionTyperServices temporaryServices = new ExpressionTyperServices(semanticServices, candidateCall.getTrace()); + ExpressionTypingServices temporaryServices = new ExpressionTypingServices(semanticServices, candidateCall.getTrace()); JetType type = temporaryServices.getType(scope, argumentExpression, parameterType); if (type == null) { candidateCall.argumentHasNoType(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java new file mode 100644 index 00000000000..775f518124a --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -0,0 +1,779 @@ +package org.jetbrains.jet.lang.types.expressions; + +import com.google.common.collect.Lists; +import com.intellij.lang.ASTNode; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.JetNodeTypes; +import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.*; +import org.jetbrains.jet.lang.resolve.calls.CallMaker; +import org.jetbrains.jet.lang.resolve.calls.DataFlowInfo; +import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; +import org.jetbrains.jet.lang.resolve.constants.*; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; +import org.jetbrains.jet.lang.types.*; +import org.jetbrains.jet.lexer.JetTokens; + +import java.util.*; + +import static org.jetbrains.jet.lang.diagnostics.Errors.*; +import static org.jetbrains.jet.lang.resolve.BindingContext.*; +import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER; +import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; +import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.*; + +/** +* @author abreslav +*/ +public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { + protected BasicExpressionTypingVisitor(@NotNull ExpressionTypingInternals facade) { + super(facade); + } + + @Override + public JetType visitSimpleNameExpression(JetSimpleNameExpression expression, ExpressionTypingContext context) { + // TODO : other members + // TODO : type substitutions??? + String referencedName = expression.getReferencedName(); + if (expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER + && referencedName != null) { + PropertyDescriptor property = context.scope.getPropertyByFieldReference(referencedName); + if (property == null) { + context.trace.report(UNRESOLVED_REFERENCE.on(expression)); + } + else { + context.trace.record(REFERENCE_TARGET, expression, property); + return checkType(property.getOutType(), expression, context); + } + } + else { + return getSelectorReturnType(NO_RECEIVER, null, expression, context); // TODO : Extensions to this + } + return null; + } + + private JetType lookupNamespaceOrClassObject(JetSimpleNameExpression expression, String referencedName, ExpressionTypingContext context) { + ClassifierDescriptor classifier = context.scope.getClassifier(referencedName); + if (classifier != null) { + JetType classObjectType = classifier.getClassObjectType(); + JetType result = null; + if (classObjectType != null) { + if (context.namespacesAllowed || classifier.isClassObjectAValue()) { + result = classObjectType; + } + else { + context.trace.report(NO_CLASS_OBJECT.on(expression, classifier)); + } + context.trace.record(REFERENCE_TARGET, expression, classifier); + if (result == null) { + return ErrorUtils.createErrorType("No class object in " + expression.getReferencedName()); + } + return checkType(result, expression, context); + } + } + JetType[] result = new JetType[1]; + TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace); + if (furtherNameLookup(expression, referencedName, result, context.replaceBindingTrace(temporaryTrace))) { + temporaryTrace.commit(); + return checkType(result[0], expression, context); + } + // To report NO_CLASS_OBJECT when no namespace found + if (classifier != null) { + context.trace.report(NO_CLASS_OBJECT.on(expression, classifier)); + context.trace.record(REFERENCE_TARGET, expression, classifier); + return ErrorUtils.createErrorType("No class object in " + expression.getReferencedName()); + } + temporaryTrace.commit(); + return result[0]; + } + + protected boolean furtherNameLookup(@NotNull JetSimpleNameExpression expression, @NotNull String referencedName, @NotNull JetType[] result, ExpressionTypingContext context) { + if (context.namespacesAllowed) { + result[0] = lookupNamespaceType(expression, referencedName, context); + return result[0] != null; + } + NamespaceType namespaceType = lookupNamespaceType(expression, referencedName, context); + if (namespaceType != null) { + context.trace.report(EXPRESSION_EXPECTED_NAMESPACE_FOUND.on(expression)); + result[0] = ErrorUtils.createErrorType("Type for " + referencedName); + } + return false; + } + + @Nullable + protected NamespaceType lookupNamespaceType(@NotNull JetSimpleNameExpression expression, @NotNull String referencedName, ExpressionTypingContext context) { + NamespaceDescriptor namespace = context.scope.getNamespace(referencedName); + if (namespace == null) { + return null; + } + context.trace.record(REFERENCE_TARGET, expression, namespace); + return namespace.getNamespaceType(); + } + + @Override + public JetType visitParenthesizedExpression(JetParenthesizedExpression expression, ExpressionTypingContext context) { + JetExpression innerExpression = expression.getExpression(); + if (innerExpression == null) { + return null; + } + return checkType(facade.getType(innerExpression, context.replaceScope(context.scope)), expression, context); + } + + @Override + public JetType visitConstantExpression(JetConstantExpression expression, ExpressionTypingContext context) { + ASTNode node = expression.getNode(); + IElementType elementType = node.getElementType(); + String text = node.getText(); + JetStandardLibrary standardLibrary = context.semanticServices.getStandardLibrary(); + CompileTimeConstantResolver compileTimeConstantResolver = context.getCompileTimeConstantResolver(); + + CompileTimeConstant value; + if (elementType == JetNodeTypes.INTEGER_CONSTANT) { + value = compileTimeConstantResolver.getIntegerValue(text, context.expectedType); + } + else if (elementType == JetNodeTypes.FLOAT_CONSTANT) { + value = compileTimeConstantResolver.getFloatValue(text, context.expectedType); + } + else if (elementType == JetNodeTypes.BOOLEAN_CONSTANT) { + value = compileTimeConstantResolver.getBooleanValue(text, context.expectedType); + } + else if (elementType == JetNodeTypes.CHARACTER_CONSTANT) { + value = compileTimeConstantResolver.getCharValue(text, context.expectedType); + } + else if (elementType == JetNodeTypes.RAW_STRING_CONSTANT) { + value = compileTimeConstantResolver.getRawStringValue(text, context.expectedType); + } + else if (elementType == JetNodeTypes.NULL) { + value = compileTimeConstantResolver.getNullValue(context.expectedType); + } + else { + throw new IllegalArgumentException("Unsupported constant: " + expression); + } + if (value instanceof ErrorValue) { + ErrorValue errorValue = (ErrorValue) value; + context.trace.report(ERROR_COMPILE_TIME_VALUE.on(node, errorValue.getMessage())); + return getDefaultType(context.semanticServices, elementType); + } + else { + context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, value); + return checkType(value.getType(standardLibrary), expression, context); + } + } + + @Override + public JetType visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression, ExpressionTypingContext context) { + JetTypeReference right = expression.getRight(); + JetType result = null; + if (right != null) { + JetType targetType = context.getTypeResolver().resolveType(context.scope, right); + + if (isTypeFlexible(expression.getLeft())) { + TemporaryBindingTrace temporaryTraceWithExpectedType = TemporaryBindingTrace.create(context.trace); + boolean success = checkBinaryWithTypeRHS(expression, context, targetType, targetType, temporaryTraceWithExpectedType); + if (success) { + temporaryTraceWithExpectedType.commit(); + } + else { + TemporaryBindingTrace temporaryTraceWithoutExpectedType = TemporaryBindingTrace.create(context.trace); + checkBinaryWithTypeRHS(expression, context, targetType, NO_EXPECTED_TYPE, temporaryTraceWithoutExpectedType); + temporaryTraceWithoutExpectedType.commit(); + } + } + else { + TemporaryBindingTrace temporaryTraceWithoutExpectedType = TemporaryBindingTrace.create(context.trace); + checkBinaryWithTypeRHS(expression, context, targetType, NO_EXPECTED_TYPE, temporaryTraceWithoutExpectedType); + temporaryTraceWithoutExpectedType.commit(); + } + + IElementType operationType = expression.getOperationSign().getReferencedNameElementType(); + result = operationType == JetTokens.AS_SAFE ? TypeUtils.makeNullable(targetType) : targetType; + } + else { + facade.getType(expression.getLeft(), context.replaceExpectedType(NO_EXPECTED_TYPE)); + } + return checkType(result, expression, context); + } + + private boolean checkBinaryWithTypeRHS(JetBinaryExpressionWithTypeRHS expression, ExpressionTypingContext context, @NotNull JetType targetType, @NotNull JetType expectedType, TemporaryBindingTrace temporaryTrace) { + ExpressionTypingContext newContext = context.replaceExpectedType(expectedType).replaceBindingTrace(temporaryTrace); + + JetType actualType = facade.getType(expression.getLeft(), newContext); + if (actualType == null) return false; + + JetSimpleNameExpression operationSign = expression.getOperationSign(); + IElementType operationType = operationSign.getReferencedNameElementType(); + if (operationType == JetTokens.COLON) { + if (targetType != NO_EXPECTED_TYPE && !context.semanticServices.getTypeChecker().isSubtypeOf(actualType, targetType)) { + context.trace.report(TYPE_MISMATCH.on(expression.getLeft(), targetType, actualType)); + return false; + } + return true; + } + else if (operationType == JetTokens.AS_KEYWORD || operationType == JetTokens.AS_SAFE) { + checkForCastImpossibility(expression, actualType, targetType, context); + return true; + } + else { + context.trace.report(UNSUPPORTED.on(operationSign, "binary operation with type RHS")); + return false; + } + } + + private void checkForCastImpossibility(JetBinaryExpressionWithTypeRHS expression, JetType actualType, JetType targetType, ExpressionTypingContext context) { + if (actualType == null || targetType == NO_EXPECTED_TYPE) return; + + JetTypeChecker typeChecker = context.semanticServices.getTypeChecker(); + if (!typeChecker.isSubtypeOf(targetType, actualType)) { + if (typeChecker.isSubtypeOf(actualType, targetType)) { + context.trace.report(USELESS_CAST_STATIC_ASSERT_IS_FINE.on(expression, expression.getOperationSign())); + } + else { + // See JET-58 Make 'as never succeeds' a warning, or even never check for Java (external) types + context.trace.report(CAST_NEVER_SUCCEEDS.on(expression.getOperationSign())); + } + } + else { + if (typeChecker.isSubtypeOf(actualType, targetType)) { + context.trace.report(USELESS_CAST.on(expression, expression.getOperationSign())); + } + } + } + + @Override + public JetType visitTupleExpression(JetTupleExpression expression, ExpressionTypingContext context) { + List entries = expression.getEntries(); + List types = new ArrayList(); + for (JetExpression entry : entries) { + types.add(context.getServices().safeGetType(context.scope, entry, NO_EXPECTED_TYPE)); // TODO + } + if (context.expectedType != NO_EXPECTED_TYPE && JetStandardClasses.isTupleType(context.expectedType)) { + List enrichedTypes = checkArgumentTypes(types, entries, context.expectedType.getArguments(), context); + if (enrichedTypes != types) { + return JetStandardClasses.getTupleType(enrichedTypes); + } + } + // TODO : labels + return checkType(JetStandardClasses.getTupleType(types), expression, context); + } + + @NotNull + private List checkArgumentTypes(@NotNull List argumentTypes, @NotNull List arguments, @NotNull List expectedArgumentTypes, @NotNull ExpressionTypingContext context) { + if (arguments.size() == 0 || argumentTypes.size() != arguments.size() || expectedArgumentTypes.size() != arguments.size()) { + return argumentTypes; + } + List result = Lists.newArrayListWithCapacity(arguments.size()); + for (int i = 0, argumentTypesSize = argumentTypes.size(); i < argumentTypesSize; i++) { + result.add(checkType(argumentTypes.get(i), arguments.get(i), context.replaceExpectedType(expectedArgumentTypes.get(i).getType()))); + } + return result; + } + + @Override + public JetType visitThisExpression(JetThisExpression expression, ExpressionTypingContext context) { + JetType result = null; + ReceiverDescriptor thisReceiver = null; + String labelName = expression.getLabelName(); + if (labelName != null) { + thisReceiver = context.labelResolver.resolveThisLabel(expression, context, thisReceiver, labelName); + } + else { + thisReceiver = context.scope.getImplicitReceiver(); + + DeclarationDescriptor declarationDescriptorForUnqualifiedThis = context.scope.getDeclarationDescriptorForUnqualifiedThis(); + if (declarationDescriptorForUnqualifiedThis != null) { + context.trace.record(REFERENCE_TARGET, expression.getThisReference(), declarationDescriptorForUnqualifiedThis); + } + } + + if (thisReceiver != null) { + if (!thisReceiver.exists()) { + context.trace.report(NO_THIS.on(expression)); + } + else { + JetTypeReference superTypeQualifier = expression.getSuperTypeQualifier(); + if (superTypeQualifier != null) { + JetTypeElement superTypeElement = superTypeQualifier.getTypeElement(); + // Errors are reported by the parser + if (superTypeElement instanceof JetUserType) { + JetUserType typeElement = (JetUserType) superTypeElement; + + ClassifierDescriptor classifierCandidate = context.getTypeResolver().resolveClass(context.scope, typeElement); + if (classifierCandidate instanceof ClassDescriptor) { + ClassDescriptor superclass = (ClassDescriptor) classifierCandidate; + + JetType thisType = thisReceiver.getType(); + Collection supertypes = thisType.getConstructor().getSupertypes(); + TypeSubstitutor substitutor = TypeSubstitutor.create(thisType); + for (JetType declaredSupertype : supertypes) { + if (declaredSupertype.getConstructor().equals(superclass.getTypeConstructor())) { + result = substitutor.safeSubstitute(declaredSupertype, Variance.INVARIANT); + break; + } + } + if (result == null) { + context.trace.report(NOT_A_SUPERTYPE.on(superTypeElement)); + } + } + } + } + else { + result = thisReceiver.getType(); + } + if (result != null) { + context.trace.record(BindingContext.EXPRESSION_TYPE, expression.getThisReference(), result); + } + } + } + return checkType(result, expression, context); + } + + @Override + public JetType visitBlockExpression(JetBlockExpression expression, ExpressionTypingContext context) { + return context.getServices().getBlockReturnedType(context.scope, expression, CoercionStrategy.NO_COERCION, context); + } + + @Override + public JetType visitHashQualifiedExpression(JetHashQualifiedExpression expression, ExpressionTypingContext context) { + context.trace.report(UNSUPPORTED.on(expression, getClass().getCanonicalName())); + return null; + } + + @Override + public JetType visitQualifiedExpression(JetQualifiedExpression expression, ExpressionTypingContext contextWithExpectedType) { + ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE); + // TODO : functions as values + JetExpression selectorExpression = expression.getSelectorExpression(); + JetExpression receiverExpression = expression.getReceiverExpression(); + JetType receiverType = facade.getType(receiverExpression, + context + .replaceExpectedType(NO_EXPECTED_TYPE) + .replaceExpectedReturnType(NO_EXPECTED_TYPE) + .replaceNamespacesAllowed(true)); + if (selectorExpression == null) return null; + if (receiverType == null) receiverType = ErrorUtils.createErrorType("Type for " + expression.getText()); + + if (selectorExpression instanceof JetSimpleNameExpression) { + propagateConstantValues(expression, context, (JetSimpleNameExpression) selectorExpression); + } + + JetType selectorReturnType = getSelectorReturnType(new ExpressionReceiver(receiverExpression, receiverType), expression.getOperationTokenNode(), selectorExpression, context); + + //TODO move further + if (expression.getOperationSign() == JetTokens.SAFE_ACCESS) { + if (selectorReturnType != null && !selectorReturnType.isNullable() && !JetStandardClasses.isUnit(selectorReturnType)) { + selectorReturnType = TypeUtils.makeNullable(selectorReturnType); + } + } + + JetType result; + if (expression.getOperationSign() == JetTokens.QUEST) { + if (selectorReturnType != null && !isBoolean(context.semanticServices, selectorReturnType)) { + // TODO : more comprehensible error message + context.trace.report(TYPE_MISMATCH.on(selectorExpression, context.semanticServices.getStandardLibrary().getBooleanType(), selectorReturnType)); + } + result = TypeUtils.makeNullable(receiverType); + } + else { + result = selectorReturnType; + } + // TODO : this is suspicious: remove this code? + if (result != null) { + context.trace.record(BindingContext.EXPRESSION_TYPE, selectorExpression, result); + } + return checkType(result, expression, contextWithExpectedType); + } + + private void propagateConstantValues(JetQualifiedExpression expression, ExpressionTypingContext context, JetSimpleNameExpression selectorExpression) { + JetExpression receiverExpression = expression.getReceiverExpression(); + CompileTimeConstant receiverValue = context.trace.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, receiverExpression); + CompileTimeConstant wholeExpressionValue = context.trace.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, expression); + if (wholeExpressionValue == null && receiverValue != null && !(receiverValue instanceof ErrorValue) && receiverValue.getValue() instanceof Number) { + Number value = (Number) receiverValue.getValue(); + String referencedName = selectorExpression.getReferencedName(); + if (OperatorConventions.NUMBER_CONVERSIONS.contains(referencedName)) { + if ("dbl".equals(referencedName)) { + context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new DoubleValue(value.doubleValue())); + } + else if ("flt".equals(referencedName)) { + context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new FloatValue(value.floatValue())); + } + else if ("lng".equals(referencedName)) { + context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new LongValue(value.longValue())); + } + else if ("sht".equals(referencedName)) { + context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new ShortValue(value.shortValue())); + } + else if ("byt".equals(referencedName)) { + context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new ByteValue(value.byteValue())); + } + else if ("int".equals(referencedName)) { + context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new IntValue(value.intValue())); + } + } + } + } + + @Nullable + public JetType getSelectorReturnType(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetExpression selectorExpression, @NotNull ExpressionTypingContext context) { + if (selectorExpression instanceof JetCallExpression) { + JetCallExpression callExpression = (JetCallExpression) selectorExpression; + return context.resolveCall(receiver, callOperationNode, callExpression); + } + else if (selectorExpression instanceof JetSimpleNameExpression) { + JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) selectorExpression; + + TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace); + VariableDescriptor variableDescriptor = context.replaceBindingTrace(temporaryTrace).resolveSimpleProperty(receiver, callOperationNode, nameExpression); + if (variableDescriptor != null) { + temporaryTrace.commit(); + return checkType(variableDescriptor.getOutType(), nameExpression, context); + } + ExpressionTypingContext newContext = receiver.exists() ? context.replaceScope(receiver.getType().getMemberScope()) : context; + JetType jetType = lookupNamespaceOrClassObject(nameExpression, nameExpression.getReferencedName(), newContext); + if (jetType == null) { + context.trace.report(UNRESOLVED_REFERENCE.on(nameExpression)); + } + return checkType(jetType, nameExpression, context); + } + else if (selectorExpression instanceof JetQualifiedExpression) { + JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) selectorExpression; + JetExpression newReceiverExpression = qualifiedExpression.getReceiverExpression(); + JetType newReceiverType = getSelectorReturnType(receiver, callOperationNode, newReceiverExpression, context.replaceExpectedType(NO_EXPECTED_TYPE)); + JetExpression newSelectorExpression = qualifiedExpression.getSelectorExpression(); + if (newReceiverType != null && newSelectorExpression != null) { + return getSelectorReturnType(new ExpressionReceiver(newReceiverExpression, newReceiverType), qualifiedExpression.getOperationTokenNode(), newSelectorExpression, context); + } + } + else { + // TODO : not a simple name -> resolve in scope, expect property type or a function type + context.trace.report(UNSUPPORTED.on(selectorExpression, "getSelectorReturnType")); + } + return null; + } + + @Override + public JetType visitCallExpression(JetCallExpression expression, ExpressionTypingContext context) { + JetType expressionType = context.resolveCall(NO_RECEIVER, null, expression); + return checkType(expressionType, expression, context); + } + + @Override + public JetType visitUnaryExpression(JetUnaryExpression expression, ExpressionTypingContext context) { + JetExpression baseExpression = expression.getBaseExpression(); + if (baseExpression == null) return null; + JetSimpleNameExpression operationSign = expression.getOperationSign(); + if (JetTokens.LABELS.contains(operationSign.getReferencedNameElementType())) { + String referencedName = operationSign.getReferencedName(); + referencedName = referencedName == null ? " " : referencedName; + context.labelResolver.enterLabeledElement(referencedName.substring(1), baseExpression); + // TODO : Some processing for the label? + JetType type = checkType(facade.getType(baseExpression, context.replaceExpectedReturnType(context.expectedType)), expression, context); + context.labelResolver.exitLabeledElement(baseExpression); + return type; + } + IElementType operationType = operationSign.getReferencedNameElementType(); + String name = OperatorConventions.UNARY_OPERATION_NAMES.get(operationType); + if (name == null) { + context.trace.report(UNSUPPORTED.on(operationSign, "visitUnaryExpression")); + return null; + } + ExpressionReceiver receiver = getExpressionReceiver(facade, baseExpression, context.replaceExpectedType(NO_EXPECTED_TYPE).replaceScope(context.scope)); + if (receiver == null) return null; + + FunctionDescriptor functionDescriptor = context.resolveCallWithGivenName( + CallMaker.makeCall(receiver, expression), + expression.getOperationSign(), + name, + receiver); + + if (functionDescriptor == null) return null; + JetType returnType = functionDescriptor.getReturnType(); + JetType result; + if (operationType == JetTokens.PLUSPLUS || operationType == JetTokens.MINUSMINUS) { + if (context.semanticServices.getTypeChecker().isSubtypeOf(returnType, JetStandardClasses.getUnitType())) { + result = JetStandardClasses.getUnitType(); + } + else { + JetType receiverType = receiver.getType(); + if (!context.semanticServices.getTypeChecker().isSubtypeOf(returnType, receiverType)) { + context.trace.report(RESULT_TYPE_MISMATCH.on(operationSign, name, receiverType, returnType)); + } + else { + context.trace.record(BindingContext.VARIABLE_REASSIGNMENT, expression); + } + // TODO : Maybe returnType? + result = receiverType; + } + } + else { + result = returnType; + } + + return checkType(result, expression, context); + } + + @Override + public JetType visitBinaryExpression(JetBinaryExpression expression, ExpressionTypingContext contextWithExpectedType) { + ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE); + JetSimpleNameExpression operationSign = expression.getOperationReference(); + + JetExpression left = expression.getLeft(); + JetExpression right = expression.getRight(); + + JetType result = null; + IElementType operationType = operationSign.getReferencedNameElementType(); + if (operationType == JetTokens.IDENTIFIER) { + String referencedName = operationSign.getReferencedName(); + if (referencedName != null) { + result = getTypeForBinaryCall(context.scope, referencedName, context, expression); + } + } + else if (OperatorConventions.BINARY_OPERATION_NAMES.containsKey(operationType)) { + result = getTypeForBinaryCall(context.scope, OperatorConventions.BINARY_OPERATION_NAMES.get(operationType), context, expression); + } + else if (operationType == JetTokens.EQ) { + result = visitAssignment(expression, contextWithExpectedType); + } + else if (OperatorConventions.ASSIGNMENT_OPERATIONS.containsKey(operationType)) { + result = visitAssignmentOperation(expression, contextWithExpectedType); + } + else if (OperatorConventions.COMPARISON_OPERATIONS.contains(operationType)) { + JetType compareToReturnType = getTypeForBinaryCall(context.scope, "compareTo", context, expression); + if (compareToReturnType != null) { + TypeConstructor constructor = compareToReturnType.getConstructor(); + JetStandardLibrary standardLibrary = context.semanticServices.getStandardLibrary(); + TypeConstructor intTypeConstructor = standardLibrary.getInt().getTypeConstructor(); + if (constructor.equals(intTypeConstructor)) { + result = standardLibrary.getBooleanType(); + } else { + context.trace.report(COMPARE_TO_TYPE_MISMATCH.on(operationSign, compareToReturnType)); + } + } + } + else if (OperatorConventions.EQUALS_OPERATIONS.contains(operationType)) { + String name = "equals"; + if (right != null) { + ExpressionReceiver receiver = ExpressionTypingUtils.safeGetExpressionReceiver(facade, left, context.replaceScope(context.scope)); + OverloadResolutionResults resolutionResults = context.resolveExactSignature( + receiver, "equals", + Collections.singletonList(JetStandardClasses.getNullableAnyType())); + if (resolutionResults.isSuccess()) { + FunctionDescriptor equals = resolutionResults.getResult().getResultingDescriptor(); + context.trace.record(REFERENCE_TARGET, operationSign, equals); + if (ensureBooleanResult(operationSign, name, equals.getReturnType(), context)) { + ensureNonemptyIntersectionOfOperandTypes(expression, context); + } + } + else { + if (resolutionResults.isAmbiguity()) { + context.trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(operationSign, resolutionResults.getResults())); + } + else { + context.trace.report(EQUALS_MISSING.on(operationSign)); + } + } + } + result = context.semanticServices.getStandardLibrary().getBooleanType(); + } + else if (operationType == JetTokens.EQEQEQ || operationType == JetTokens.EXCLEQEQEQ) { + ensureNonemptyIntersectionOfOperandTypes(expression, context); + + // TODO : Check comparison pointlessness + result = context.semanticServices.getStandardLibrary().getBooleanType(); + } + else if (OperatorConventions.IN_OPERATIONS.contains(operationType)) { + if (right == null) { + result = ErrorUtils.createErrorType("No right argument"); // TODO + return null; + } + checkInExpression(expression, expression.getOperationReference(), expression.getLeft(), expression.getRight(), context); + result = context.semanticServices.getStandardLibrary().getBooleanType(); + } + else if (operationType == JetTokens.ANDAND || operationType == JetTokens.OROR) { + JetType leftType = facade.getType(left, context.replaceScope(context.scope)); + WritableScopeImpl leftScope = newWritableScopeImpl(context).setDebugName("Left scope of && or ||"); + DataFlowInfo flowInfoLeft = extractDataFlowInfoFromCondition(left, operationType == JetTokens.ANDAND, leftScope, context); // TODO: This gets computed twice: here and in extractDataFlowInfoFromCondition() for the whole condition + WritableScopeImpl rightScope = operationType == JetTokens.ANDAND ? leftScope : newWritableScopeImpl(context).setDebugName("Right scope of && or ||"); + JetType rightType = right == null ? null : facade.getType(right, context.replaceDataFlowInfo(flowInfoLeft).replaceScope(rightScope)); + if (leftType != null && !isBoolean(context.semanticServices, leftType)) { + context.trace.report(TYPE_MISMATCH.on(left, context.semanticServices.getStandardLibrary().getBooleanType(), leftType)); + } + if (rightType != null && !isBoolean(context.semanticServices, rightType)) { + context.trace.report(TYPE_MISMATCH.on(right, context.semanticServices.getStandardLibrary().getBooleanType(), rightType)); + } + result = context.semanticServices.getStandardLibrary().getBooleanType(); + } + else if (operationType == JetTokens.ELVIS) { + JetType leftType = facade.getType(left, context.replaceScope(context.scope)); + JetType rightType = right == null ? null : facade.getType(right, contextWithExpectedType.replaceScope(context.scope)); + if (leftType != null) { + if (!leftType.isNullable()) { + context.trace.report(USELESS_ELVIS.on(expression, left, leftType)); + } + if (rightType != null) { + checkType(TypeUtils.makeNullableAsSpecified(leftType, rightType.isNullable()), left, contextWithExpectedType); + return TypeUtils.makeNullableAsSpecified(context.semanticServices.getTypeChecker().commonSupertype(leftType, rightType), rightType.isNullable()); + } + } + } + else { + context.trace.report(UNSUPPORTED.on(operationSign, "Unknown operation")); + } + return checkType(result, expression, contextWithExpectedType); + } + + public void checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @NotNull JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context) { + String name = "contains"; + ExpressionReceiver receiver = safeGetExpressionReceiver(facade, right, context.replaceExpectedType(NO_EXPECTED_TYPE)); + FunctionDescriptor functionDescriptor = context.resolveCallWithGivenName( + CallMaker.makeCallWithExpressions(callElement, receiver, null, operationSign, Collections.singletonList(left)), + operationSign, + name, receiver); + JetType containsType = functionDescriptor != null ? functionDescriptor.getReturnType() : null; + ensureBooleanResult(operationSign, name, containsType, context); + } + + private void ensureNonemptyIntersectionOfOperandTypes(JetBinaryExpression expression, ExpressionTypingContext context) { + JetSimpleNameExpression operationSign = expression.getOperationReference(); + JetExpression left = expression.getLeft(); + JetExpression right = expression.getRight(); + + // TODO : duplicated effort for == and != + JetType leftType = facade.getType(left, context.replaceScope(context.scope)); + if (leftType != null && right != null) { + JetType rightType = facade.getType(right, context.replaceScope(context.scope)); + + if (rightType != null) { + JetType intersect = TypeUtils.intersect(context.semanticServices.getTypeChecker(), new HashSet(Arrays.asList(leftType, rightType))); + if (intersect == null) { + context.trace.report(EQUALITY_NOT_APPLICABLE.on(expression, operationSign, leftType, rightType)); + } + } + } + } + + protected JetType visitAssignmentOperation(JetBinaryExpression expression, ExpressionTypingContext context) { + return assignmentIsNotAnExpressionError(expression, context); + } + + protected JetType visitAssignment(JetBinaryExpression expression, ExpressionTypingContext context) { + return assignmentIsNotAnExpressionError(expression, context); + } + + private JetType assignmentIsNotAnExpressionError(JetBinaryExpression expression, ExpressionTypingContext context) { + context.trace.report(ASSIGNMENT_IN_EXPRESSION_CONTEXT.on(expression)); + return null; + } + + @Override + public JetType visitArrayAccessExpression(JetArrayAccessExpression expression, ExpressionTypingContext contextWithExpectedType) { + ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE); + JetExpression arrayExpression = expression.getArrayExpression(); + ExpressionReceiver receiver = getExpressionReceiver(facade, arrayExpression, context.replaceScope(context.scope)); + + if (receiver != null) { + FunctionDescriptor functionDescriptor = context.resolveCallWithGivenName( + CallMaker.makeCallWithExpressions(expression, receiver, null, expression, expression.getIndexExpressions()), + expression, + "get", + receiver); + if (functionDescriptor != null) { + return checkType(functionDescriptor.getReturnType(), expression, contextWithExpectedType); + } + } + return null; + } + + @Nullable + protected JetType getTypeForBinaryCall(JetScope scope, String name, ExpressionTypingContext context, JetBinaryExpression binaryExpression) { + ExpressionReceiver receiver = safeGetExpressionReceiver(facade, binaryExpression.getLeft(), context.replaceScope(scope)); + FunctionDescriptor functionDescriptor = context.replaceScope(scope).resolveCallWithGivenName( + CallMaker.makeCall(receiver, binaryExpression), + binaryExpression.getOperationReference(), + name, + receiver); + if (functionDescriptor != null) { + return functionDescriptor.getReturnType(); + } + return null; + } + + @Override + public JetType visitDeclaration(JetDeclaration dcl, ExpressionTypingContext context) { + context.trace.report(DECLARATION_IN_ILLEGAL_CONTEXT.on(dcl)); + return null; + } + + @Override + public JetType visitRootNamespaceExpression(JetRootNamespaceExpression expression, ExpressionTypingContext context) { + if (context.namespacesAllowed) { + return ExpressionTypingUtils.checkType(JetModuleUtil.getRootNamespaceType(expression), expression, context); + } + context.trace.report(NAMESPACE_IS_NOT_AN_EXPRESSION.on(expression)); + return null; + } + + + @Override + public JetType visitStringTemplateExpression(JetStringTemplateExpression expression, ExpressionTypingContext contextWithExpectedType) { + final ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(NO_EXPECTED_TYPE); + final StringBuilder builder = new StringBuilder(); + final CompileTimeConstant[] value = new CompileTimeConstant[1]; + for (JetStringTemplateEntry entry : expression.getEntries()) { + entry.accept(new JetVisitorVoid() { + + @Override + public void visitStringTemplateEntryWithExpression(JetStringTemplateEntryWithExpression entry) { + JetExpression entryExpression = entry.getExpression(); + if (entryExpression != null) { + facade.getType(entryExpression, context.replaceScope(context.scope)); + } + value[0] = CompileTimeConstantResolver.OUT_OF_RANGE; + } + + @Override + public void visitLiteralStringTemplateEntry(JetLiteralStringTemplateEntry entry) { + builder.append(entry.getText()); + } + + @Override + public void visitEscapeStringTemplateEntry(JetEscapeStringTemplateEntry entry) { + // TODO : Check escape + String text = entry.getText(); + assert text.length() == 2 && text.charAt(0) == '\\'; + char escaped = text.charAt(1); + + Character character = CompileTimeConstantResolver.translateEscape(escaped); + if (character == null) { + context.trace.report(ILLEGAL_ESCAPE_SEQUENCE.on(entry)); + value[0] = CompileTimeConstantResolver.OUT_OF_RANGE; + } + else { + builder.append(character); + } + } + }); + } + if (value[0] != CompileTimeConstantResolver.OUT_OF_RANGE) { + context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new StringValue(builder.toString())); + } + return checkType(context.semanticServices.getStandardLibrary().getStringType(), expression, contextWithExpectedType); + } + + @Override + public JetType visitAnnotatedExpression(JetAnnotatedExpression expression, ExpressionTypingContext data) { + return facade.getType(expression.getBaseExpression(), data); + } + + @Override + public JetType visitJetElement(JetElement element, ExpressionTypingContext context) { + context.trace.report(UNSUPPORTED.on(element, getClass().getCanonicalName())); + return null; + } +} \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java new file mode 100644 index 00000000000..1a0f7412042 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ClosureExpressionsTypingVisitor.java @@ -0,0 +1,162 @@ +package org.jetbrains.jet.lang.types.expressions; + +import com.google.common.collect.Lists; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.ObservableBindingTrace; +import org.jetbrains.jet.lang.resolve.TopDownAnalyzer; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; +import org.jetbrains.jet.lang.types.*; +import org.jetbrains.jet.util.lazy.LazyValueWithDefault; +import org.jetbrains.jet.util.slicedmap.WritableSlice; + +import java.util.Collections; +import java.util.List; + +import static org.jetbrains.jet.lang.diagnostics.Errors.CANNOT_INFER_PARAMETER_TYPE; +import static org.jetbrains.jet.lang.resolve.BindingContext.*; +import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER; + +/** + * @author abreslav + */ +public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor { + protected ClosureExpressionsTypingVisitor(@NotNull ExpressionTypingInternals facade) { + super(facade); + } + + @Override + public JetType visitObjectLiteralExpression(final JetObjectLiteralExpression expression, final ExpressionTypingContext context) { + final JetType[] result = new JetType[1]; + ObservableBindingTrace.RecordHandler handler = new ObservableBindingTrace.RecordHandler() { + + @Override + public void handleRecord(WritableSlice slice, PsiElement declaration, final ClassDescriptor descriptor) { + if (slice == CLASS && declaration == expression.getObjectDeclaration()) { + JetType defaultType = DeferredType.create(context.trace, new LazyValueWithDefault(ErrorUtils.createErrorType("Recursive dependency")) { + @Override + protected JetType compute() { + return descriptor.getDefaultType(); + } + }); + result[0] = defaultType; + if (!context.trace.get(PROCESSED, expression)) { + context.trace.record(EXPRESSION_TYPE, expression, defaultType); + context.trace.record(PROCESSED, expression); + } + } + } + }; + ObservableBindingTrace traceAdapter = new ObservableBindingTrace(context.trace); + traceAdapter.addHandler(CLASS, handler); + TopDownAnalyzer.processObject(context.semanticServices, traceAdapter, context.scope, context.scope.getContainingDeclaration(), expression.getObjectDeclaration()); + return ExpressionTypingUtils.checkType(result[0], expression, context); + } + + @Override + public JetType visitFunctionLiteralExpression(JetFunctionLiteralExpression expression, ExpressionTypingContext context) { + JetFunctionLiteral functionLiteral = expression.getFunctionLiteral(); + + JetTypeReference receiverTypeRef = functionLiteral.getReceiverTypeRef(); + final JetType receiverType; + if (receiverTypeRef != null) { + receiverType = context.getTypeResolver().resolveType(context.scope, receiverTypeRef); + } else { + ReceiverDescriptor implicitReceiver = context.scope.getImplicitReceiver(); + receiverType = implicitReceiver.exists() ? implicitReceiver.getType() : null; + } + + FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl( + context.scope.getContainingDeclaration(), Collections.emptyList(), ""); + + List parameterTypes = Lists.newArrayList(); + List valueParameterDescriptors = Lists.newArrayList(); + List declaredValueParameters = functionLiteral.getValueParameters(); + JetType expectedType = context.expectedType; + + boolean functionTypeExpected = expectedType != TypeUtils.NO_EXPECTED_TYPE && JetStandardClasses.isFunctionType(expectedType); + List expectedValueParameters = (functionTypeExpected) + ? JetStandardClasses.getValueParameters(functionDescriptor, expectedType) + : null; + + if (functionTypeExpected && declaredValueParameters.isEmpty() && expectedValueParameters.size() == 1) { + ValueParameterDescriptor valueParameterDescriptor = expectedValueParameters.get(0); + ValueParameterDescriptor it = new ValueParameterDescriptorImpl( + functionDescriptor, 0, Collections.emptyList(), "it", valueParameterDescriptor.getInType(), valueParameterDescriptor.getOutType(), valueParameterDescriptor.hasDefaultValue(), valueParameterDescriptor.isVararg() + ); + valueParameterDescriptors.add(it); + parameterTypes.add(it.getOutType()); + context.trace.record(AUTO_CREATED_IT, it); + } + else { + for (int i = 0; i < declaredValueParameters.size(); i++) { + JetParameter declaredParameter = declaredValueParameters.get(i); + JetTypeReference typeReference = declaredParameter.getTypeReference(); + + JetType type; + if (typeReference != null) { + type = context.getTypeResolver().resolveType(context.scope, typeReference); + } + else { + if (expectedValueParameters != null && i < expectedValueParameters.size()) { + type = expectedValueParameters.get(i).getOutType(); + } + else { + context.trace.report(CANNOT_INFER_PARAMETER_TYPE.on(declaredParameter)); + type = ErrorUtils.createErrorType("Cannot be inferred"); + } + } + ValueParameterDescriptor valueParameterDescriptor = context.getClassDescriptorResolver().resolveValueParameterDescriptor(functionDescriptor, declaredParameter, i, type); + parameterTypes.add(valueParameterDescriptor.getOutType()); + valueParameterDescriptors.add(valueParameterDescriptor); + } + } + + JetType effectiveReceiverType; + if (receiverTypeRef == null) { + if (functionTypeExpected) { + effectiveReceiverType = JetStandardClasses.getReceiverType(expectedType); + } + else { + effectiveReceiverType = null; + } + } + else { + effectiveReceiverType = receiverType; + } + functionDescriptor.initialize(effectiveReceiverType, NO_RECEIVER, Collections.emptyList(), valueParameterDescriptors, null, Modality.FINAL, Visibility.LOCAL); + context.trace.record(BindingContext.FUNCTION, expression, functionDescriptor); + + JetType returnType = TypeUtils.NO_EXPECTED_TYPE; + JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace); + JetTypeReference returnTypeRef = functionLiteral.getReturnTypeRef(); + if (returnTypeRef != null) { + returnType = context.getTypeResolver().resolveType(context.scope, returnTypeRef); + context.getServices().checkFunctionReturnType(expression, context.replaceScope(functionInnerScope).replaceExpectedReturnType(returnType).replaceDataFlowInfo(context.dataFlowInfo)); + } + else { + if (functionTypeExpected) { + returnType = JetStandardClasses.getReturnType(expectedType); + } + returnType = context.getServices().getBlockReturnedType(functionInnerScope, functionLiteral.getBodyExpression(), CoercionStrategy.COERCION_TO_UNIT, context.replaceExpectedType(returnType)); + } + JetType safeReturnType = returnType == null ? ErrorUtils.createErrorType("") : returnType; + functionDescriptor.setReturnType(safeReturnType); + + if (functionTypeExpected) { + JetType expectedReturnType = JetStandardClasses.getReturnType(expectedType); + if (JetStandardClasses.isUnit(expectedReturnType)) { + functionDescriptor.setReturnType(expectedReturnType); + return ExpressionTypingUtils.checkType(JetStandardClasses.getFunctionType(Collections.emptyList(), effectiveReceiverType, parameterTypes, expectedReturnType), expression, context); + } + + } + return ExpressionTypingUtils.checkType(JetStandardClasses.getFunctionType(Collections.emptyList(), effectiveReceiverType, parameterTypes, safeReturnType), expression, context); + } + +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java new file mode 100644 index 00000000000..8d915dbe9b0 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java @@ -0,0 +1,414 @@ +package org.jetbrains.jet.lang.types.expressions; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.VariableDescriptor; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.calls.DataFlowInfo; +import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.resolve.scopes.WritableScope; +import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; +import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver; +import org.jetbrains.jet.lang.types.ErrorUtils; +import org.jetbrains.jet.lang.types.JetStandardClasses; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static org.jetbrains.jet.lang.diagnostics.Errors.*; +import static org.jetbrains.jet.lang.resolve.BindingContext.*; +import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.*; + +/** + * @author abreslav + */ +public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { + + protected ControlStructureTypingVisitor(@NotNull ExpressionTypingInternals facade) { + super(facade); + } + + private JetType getTypeWithNewScopeAndDataFlowInfo(@NotNull JetScope scope, @NotNull JetExpression expression, @NotNull DataFlowInfo newDataFlowInfo, @NotNull ExpressionTypingContext context) { + return facade.getType(expression, context.replaceScope(scope).replaceDataFlowInfo(newDataFlowInfo)); + } + + private void checkCondition(@NotNull JetScope scope, @Nullable JetExpression condition, ExpressionTypingContext context) { + if (condition != null) { + JetType conditionType = facade.getType(condition, context.replaceScope(scope)); + + if (conditionType != null && !isBoolean(context.semanticServices, conditionType)) { +// context.trace.getErrorHandler().genericError(condition.getNode(), "Condition must be of type Boolean, but was of type " + conditionType); + context.trace.report(TYPE_MISMATCH_IN_CONDITION.on(condition, conditionType)); + } + } + } + + //////////////////////////////////////////////////////////////////////////////////////////////////// + + + @Override + public JetType visitIfExpression(JetIfExpression expression, ExpressionTypingContext contextWithExpectedType) { + ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); + JetExpression condition = expression.getCondition(); + checkCondition(context.scope, condition, context); + + JetExpression elseBranch = expression.getElse(); + JetExpression thenBranch = expression.getThen(); + + WritableScopeImpl thenScope = newWritableScopeImpl(context).setDebugName("Then scope"); + DataFlowInfo thenInfo = extractDataFlowInfoFromCondition(condition, true, thenScope, context); + DataFlowInfo elseInfo = extractDataFlowInfoFromCondition(condition, false, null, context); + + if (elseBranch == null) { + if (thenBranch != null) { + JetType type = getTypeWithNewScopeAndDataFlowInfo(thenScope, thenBranch, thenInfo, context); + if (type != null && JetStandardClasses.isNothing(type)) { + facade.setResultingDataFlowInfo(elseInfo); +// resultScope = elseScope; + } + return checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType); + } + return null; + } + if (thenBranch == null) { + JetType type = getTypeWithNewScopeAndDataFlowInfo(context.scope, elseBranch, elseInfo, context); + if (type != null && JetStandardClasses.isNothing(type)) { + facade.setResultingDataFlowInfo(thenInfo); +// resultScope = thenScope; + } + return checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType); + } + JetType thenType = getTypeWithNewScopeAndDataFlowInfo(thenScope, thenBranch, thenInfo, contextWithExpectedType); + JetType elseType = getTypeWithNewScopeAndDataFlowInfo(context.scope, elseBranch, elseInfo, contextWithExpectedType); + + JetType result; + if (thenType == null) { + result = elseType; + } + else if (elseType == null) { + result = thenType; + } + else { + result = context.semanticServices.getTypeChecker().commonSupertype(Arrays.asList(thenType, elseType)); + } + + boolean jumpInThen = thenType != null && JetStandardClasses.isNothing(thenType); + boolean jumpInElse = elseType != null && JetStandardClasses.isNothing(elseType); + + if (jumpInThen && !jumpInElse) { + facade.setResultingDataFlowInfo(elseInfo); + } + else if (jumpInElse && !jumpInThen) { + facade.setResultingDataFlowInfo(thenInfo); + } + return result; + } + + @Override + public JetType visitWhileExpression(JetWhileExpression expression, ExpressionTypingContext contextWithExpectedType) { + ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); + JetExpression condition = expression.getCondition(); + checkCondition(context.scope, condition, context); + JetExpression body = expression.getBody(); + if (body != null) { + WritableScopeImpl scopeToExtend = newWritableScopeImpl(context).setDebugName("Scope extended in while's condition"); + DataFlowInfo conditionInfo = condition == null ? context.dataFlowInfo : extractDataFlowInfoFromCondition(condition, true, scopeToExtend, context); + getTypeWithNewScopeAndDataFlowInfo(scopeToExtend, body, conditionInfo, context); + } + if (!containsBreak(expression, context)) { + facade.setResultingDataFlowInfo(extractDataFlowInfoFromCondition(condition, false, null, context)); + } + return checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType); + } + + private boolean containsBreak(final JetLoopExpression loopExpression, final ExpressionTypingContext context) { + final boolean[] result = new boolean[1]; + result[0] = false; + //todo breaks in inline function literals + loopExpression.accept(new JetTreeVisitor() { + @Override + public Void visitBreakExpression(JetBreakExpression breakExpression, JetLoopExpression outerLoop) { + JetSimpleNameExpression targetLabel = breakExpression.getTargetLabel(); + PsiElement element = targetLabel != null ? context.trace.get(LABEL_TARGET, targetLabel) : null; + if (element == loopExpression || (targetLabel == null && outerLoop == loopExpression)) { + result[0] = true; + } + return null; + } + + @Override + public Void visitLoopExpression(JetLoopExpression loopExpression, JetLoopExpression outerLoop) { + return super.visitLoopExpression(loopExpression, loopExpression); + } + }, loopExpression); + + return result[0]; + } + + @Override + public JetType visitDoWhileExpression(JetDoWhileExpression expression, ExpressionTypingContext contextWithExpectedType) { + ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); + JetExpression body = expression.getBody(); + JetScope conditionScope = context.scope; + if (body instanceof JetFunctionLiteralExpression) { + JetFunctionLiteralExpression function = (JetFunctionLiteralExpression) body; + if (!function.getFunctionLiteral().hasParameterSpecification()) { + WritableScope writableScope = newWritableScopeImpl(context).setDebugName("do..while body scope"); + conditionScope = writableScope; + context.getServices().getBlockReturnedTypeWithWritableScope(writableScope, function.getFunctionLiteral().getBodyExpression().getStatements(), CoercionStrategy.NO_COERCION, context); + context.trace.record(BindingContext.BLOCK, function); + } else { + facade.getType(body, context.replaceScope(context.scope)); + } + } + else if (body != null) { + WritableScope writableScope = newWritableScopeImpl(context).setDebugName("do..while body scope"); + conditionScope = writableScope; + context.getServices().getBlockReturnedTypeWithWritableScope(writableScope, Collections.singletonList(body), CoercionStrategy.NO_COERCION, context); + } + JetExpression condition = expression.getCondition(); + checkCondition(conditionScope, condition, context); + if (!containsBreak(expression, context)) { + facade.setResultingDataFlowInfo(extractDataFlowInfoFromCondition(condition, false, null, context)); + } + return checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType); + } + + @Override + public JetType visitForExpression(JetForExpression expression, ExpressionTypingContext contextWithExpectedType) { + ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); + JetParameter loopParameter = expression.getLoopParameter(); + JetExpression loopRange = expression.getLoopRange(); + JetType expectedParameterType = null; + if (loopRange != null) { + ExpressionReceiver loopRangeReceiver = getExpressionReceiver(facade, loopRange, context.replaceScope(context.scope)); + if (loopRangeReceiver != null) { + expectedParameterType = checkIterableConvention(loopRangeReceiver, context); + } + } + + WritableScope loopScope = newWritableScopeImpl(context).setDebugName("Scope with for-loop index"); + + if (loopParameter != null) { + JetTypeReference typeReference = loopParameter.getTypeReference(); + VariableDescriptor variableDescriptor; + if (typeReference != null) { + variableDescriptor = context.getClassDescriptorResolver().resolveLocalVariableDescriptor(context.scope.getContainingDeclaration(), context.scope, loopParameter); + JetType actualParameterType = variableDescriptor.getOutType(); + if (expectedParameterType != null && + actualParameterType != null && + !context.semanticServices.getTypeChecker().isSubtypeOf(expectedParameterType, actualParameterType)) { +// context.trace.getErrorHandler().genericError(typeReference.getNode(), "The loop iterates over values of type " + expectedParameterType + " but the parameter is declared to be " + actualParameterType); + context.trace.report(TYPE_MISMATCH_IN_FOR_LOOP.on(typeReference, expectedParameterType, actualParameterType)); + } + } + else { + if (expectedParameterType == null) { + expectedParameterType = ErrorUtils.createErrorType("Error"); + } + variableDescriptor = context.getClassDescriptorResolver().resolveLocalVariableDescriptor(context.scope.getContainingDeclaration(), loopParameter, expectedParameterType); + } + loopScope.addVariableDescriptor(variableDescriptor); + } + + JetExpression body = expression.getBody(); + if (body != null) { + facade.getType(body, context.replaceScope(loopScope)); + } + + return checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType); + } + + @Nullable + private JetType checkIterableConvention(@NotNull ExpressionReceiver loopRange, ExpressionTypingContext context) { + JetExpression loopRangeExpression = loopRange.getExpression(); + OverloadResolutionResults iteratorResolutionResults = context.resolveExactSignature(loopRange, "iterator", Collections.emptyList()); + if (iteratorResolutionResults.isSuccess()) { + FunctionDescriptor iteratorFunction = iteratorResolutionResults.getResult().getResultingDescriptor(); + + context.trace.record(LOOP_RANGE_ITERATOR, loopRangeExpression, iteratorFunction); + + JetType iteratorType = iteratorFunction.getReturnType(); + FunctionDescriptor hasNextFunction = checkHasNextFunctionSupport(loopRangeExpression, iteratorType, context); + boolean hasNextFunctionSupported = hasNextFunction != null; + VariableDescriptor hasNextProperty = checkHasNextPropertySupport(loopRangeExpression, iteratorType, context); + boolean hasNextPropertySupported = hasNextProperty != null; + if (hasNextFunctionSupported && hasNextPropertySupported && !ErrorUtils.isErrorType(iteratorType)) { + // TODO : overload resolution rules impose priorities here??? +// context.trace.getErrorHandler().genericError(reportErrorsOn, "An ambiguity between 'iterator().hasNext()' function and 'iterator().hasNext' property"); + context.trace.report(HAS_NEXT_PROPERTY_AND_FUNCTION_AMBIGUITY.on(loopRangeExpression)); + } + else if (!hasNextFunctionSupported && !hasNextPropertySupported) { +// context.trace.getErrorHandler().genericError(reportErrorsOn, "Loop range must have an 'iterator().hasNext()' function or an 'iterator().hasNext' property"); + context.trace.report(HAS_NEXT_MISSING.on(loopRangeExpression)); + } + else { + context.trace.record(LOOP_RANGE_HAS_NEXT, loopRange.getExpression(), hasNextFunctionSupported ? hasNextFunction : hasNextProperty); + } + + OverloadResolutionResults nextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "next", Collections.emptyList()); + if (nextResolutionResults.isAmbiguity()) { +// context.trace.getErrorHandler().genericError(reportErrorsOn, "Method 'iterator().next()' is ambiguous for this expression"); + context.trace.report(NEXT_AMBIGUITY.on(loopRangeExpression)); + } else if (nextResolutionResults.isNothing()) { +// context.trace.getErrorHandler().genericError(reportErrorsOn, "Loop range must have an 'iterator().next()' method"); + context.trace.report(NEXT_MISSING.on(loopRangeExpression)); + } else { + FunctionDescriptor nextFunction = nextResolutionResults.getResult().getResultingDescriptor(); + context.trace.record(LOOP_RANGE_NEXT, loopRange.getExpression(), nextFunction); + return nextFunction.getReturnType(); + } + } + else { + if (iteratorResolutionResults.isAmbiguity()) { +// StringBuffer stringBuffer = new StringBuffer("Method 'iterator()' is ambiguous for this expression: "); +// for (FunctionDescriptor functionDescriptor : iteratorResolutionResults.getResults()) { +// stringBuffer.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append(" "); +// } +// errorMessage = stringBuffer.toString(); + context.trace.report(ITERATOR_AMBIGUITY.on(loopRangeExpression, iteratorResolutionResults.getResults())); + } + else { +// context.trace.getErrorHandler().genericError(reportErrorsOn, errorMessage); + context.trace.report(ITERATOR_MISSING.on(loopRangeExpression)); + } + } + return null; + } + + @Nullable + private FunctionDescriptor checkHasNextFunctionSupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, ExpressionTypingContext context) { + OverloadResolutionResults hasNextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "hasNext", Collections.emptyList()); + if (hasNextResolutionResults.isAmbiguity()) { +// context.trace.getErrorHandler().genericError(loopRange.getNode(), "Method 'iterator().hasNext()' is ambiguous for this expression"); + context.trace.report(HAS_NEXT_FUNCTION_AMBIGUITY.on(loopRange)); + } else if (hasNextResolutionResults.isNothing()) { + return null; + } else { + assert hasNextResolutionResults.isSuccess(); + JetType hasNextReturnType = hasNextResolutionResults.getResult().getResultingDescriptor().getReturnType(); + if (!isBoolean(context.semanticServices, hasNextReturnType)) { +// context.trace.getErrorHandler().genericError(loopRange.getNode(), "The 'iterator().hasNext()' method of the loop range must return Boolean, but returns " + hasNextReturnType); + context.trace.report(HAS_NEXT_FUNCTION_TYPE_MISMATCH.on(loopRange, hasNextReturnType)); + } + } + return hasNextResolutionResults.getResult().getResultingDescriptor(); + } + + @Nullable + private VariableDescriptor checkHasNextPropertySupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, ExpressionTypingContext context) { + VariableDescriptor hasNextProperty = iteratorType.getMemberScope().getVariable("hasNext"); + // TODO :extension properties + if (hasNextProperty == null) { + return null; + } else { + JetType hasNextReturnType = hasNextProperty.getOutType(); + if (hasNextReturnType == null) { + // TODO : accessibility +// context.trace.getErrorHandler().genericError(loopRange.getNode(), "The 'iterator().hasNext' property of the loop range must be readable"); + context.trace.report(HAS_NEXT_MUST_BE_READABLE.on(loopRange)); + } + else if (!isBoolean(context.semanticServices, hasNextReturnType)) { +// context.trace.getErrorHandler().genericError(loopRange.getNode(), "The 'iterator().hasNext' property of the loop range must return Boolean, but returns " + hasNextReturnType); + context.trace.report(HAS_NEXT_PROPERTY_TYPE_MISMATCH.on(loopRange, hasNextReturnType)); + } + } + return hasNextProperty; + } + + @Override + public JetType visitTryExpression(JetTryExpression expression, ExpressionTypingContext context) { + JetExpression tryBlock = expression.getTryBlock(); + List catchClauses = expression.getCatchClauses(); + JetFinallySection finallyBlock = expression.getFinallyBlock(); + List types = new ArrayList(); + for (JetCatchClause catchClause : catchClauses) { + JetParameter catchParameter = catchClause.getCatchParameter(); + JetExpression catchBody = catchClause.getCatchBody(); + if (catchParameter != null) { + VariableDescriptor variableDescriptor = context.getClassDescriptorResolver().resolveLocalVariableDescriptor(context.scope.getContainingDeclaration(), context.scope, catchParameter); + if (catchBody != null) { + WritableScope catchScope = newWritableScopeImpl(context).setDebugName("Catch scope"); + catchScope.addVariableDescriptor(variableDescriptor); + JetType type = facade.getType(catchBody, context.replaceScope(catchScope)); + if (type != null) { + types.add(type); + } + } + } + } + if (finallyBlock != null) { + types.clear(); // Do not need the list for the check, but need the code above to typecheck catch bodies + JetType type = facade.getType(finallyBlock.getFinalExpression(), context.replaceScope(context.scope)); + if (type != null) { + types.add(type); + } + } + JetType type = facade.getType(tryBlock, context.replaceScope(context.scope)); + if (type != null) { + types.add(type); + } + if (types.isEmpty()) { + return null; + } + else { + return context.semanticServices.getTypeChecker().commonSupertype(types); + } + } + + @Override + public JetType visitThrowExpression(JetThrowExpression expression, ExpressionTypingContext context) { + JetExpression thrownExpression = expression.getThrownExpression(); + if (thrownExpression != null) { + JetType type = facade.getType(thrownExpression, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).replaceScope(context.scope)); + // TODO : check that it inherits Throwable + } + return checkType(JetStandardClasses.getNothingType(), expression, context); + } + + @Override + public JetType visitReturnExpression(JetReturnExpression expression, ExpressionTypingContext context) { + context.labelResolver.recordLabel(expression, context); + if (context.expectedReturnType == TypeUtils.FORBIDDEN) { +// context.trace.getErrorHandler().genericError(expression.getNode(), "'return' is not allowed here"); + context.trace.report(RETURN_NOT_ALLOWED.on(expression)); + return null; + } + JetExpression returnedExpression = expression.getReturnedExpression(); + + JetType returnedType = JetStandardClasses.getUnitType(); + if (returnedExpression != null) { + facade.getType(returnedExpression, context.replaceExpectedType(context.expectedReturnType).replaceScope(context.scope)); + } + else { + if (context.expectedReturnType != TypeUtils.NO_EXPECTED_TYPE && !JetStandardClasses.isUnit(context.expectedReturnType)) { +// context.trace.getErrorHandler().genericError(expression.getNode(), "This function must return a value of type " + context.expectedReturnType); + context.trace.report(RETURN_TYPE_MISMATCH.on(expression, context.expectedReturnType)); + } + } + return checkType(JetStandardClasses.getNothingType(), expression, context); + } + + @Override + public JetType visitBreakExpression(JetBreakExpression expression, ExpressionTypingContext context) { + context.labelResolver.recordLabel(expression, context); + return checkType(JetStandardClasses.getNothingType(), expression, context); + } + + @Override + public JetType visitContinueExpression(JetContinueExpression expression, ExpressionTypingContext context) { + context.labelResolver.recordLabel(expression, context); + return checkType(JetStandardClasses.getNothingType(), expression, context); + } + + +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTyperServices.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTyperServices.java deleted file mode 100644 index fe5fa2f4a42..00000000000 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTyperServices.java +++ /dev/null @@ -1,484 +0,0 @@ -package org.jetbrains.jet.lang.types.expressions; - -import com.google.common.collect.Lists; -import com.intellij.psi.PsiElement; -import com.intellij.psi.tree.IElementType; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.JetSemanticServices; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; -import org.jetbrains.jet.lang.descriptors.FunctionDescriptorUtil; -import org.jetbrains.jet.lang.descriptors.VariableDescriptor; -import org.jetbrains.jet.lang.diagnostics.Diagnostic; -import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement; -import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.*; -import org.jetbrains.jet.lang.resolve.calls.AutoCastUtils; -import org.jetbrains.jet.lang.resolve.calls.CallResolver; -import org.jetbrains.jet.lang.resolve.calls.DataFlowInfo; -import org.jetbrains.jet.lang.resolve.scopes.JetScope; -import org.jetbrains.jet.lang.resolve.scopes.WritableScope; -import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; -import org.jetbrains.jet.lang.types.*; -import org.jetbrains.jet.lexer.JetTokens; - -import java.util.*; - -import static org.jetbrains.jet.lang.diagnostics.Errors.TYPE_MISMATCH; -import static org.jetbrains.jet.lang.resolve.BindingContext.*; - -/** -* @author abreslav -*/ -public class ExpressionTyperServices { - private final JetSemanticServices semanticServices; - private final BindingTrace trace; - - private final ExpressionTyperVisitor expressionTyperVisitor; - private final CallResolver callResolver; - - public ExpressionTyperServices(JetSemanticServices semanticServices, BindingTrace trace) { - this.semanticServices = semanticServices; - this.trace = trace; - this.expressionTyperVisitor = new ExpressionTyperVisitor(); - this.callResolver = new CallResolver(semanticServices, DataFlowInfo.getEmpty()); - } - - public ExpressionTyperVisitorWithWritableScope newTypeInferrerVisitorWithWritableScope(WritableScope scope) { - return new ExpressionTyperVisitorWithWritableScope(scope); - } - - @NotNull - public JetType safeGetType(@NotNull JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType) { - JetType type = getType(scope, expression, expectedType); - if (type != null) { - return type; - } - return ErrorUtils.createErrorType("Type for " + expression.getText()); - } - - @Nullable - public JetType getType(@NotNull final JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType) { - return expressionTyperVisitor.getType(expression, ExpressionTypingContext.newRootContext(semanticServices, trace, scope, DataFlowInfo.getEmpty(), expectedType, TypeUtils.FORBIDDEN)); - } - - public JetType getTypeWithNamespaces(@NotNull final JetScope scope, @NotNull JetExpression expression) { - return ExpressionTyperVisitorWithNamespaces.INSTANCE.getType(expression, ExpressionTypingContext.newRootContext(semanticServices, trace, scope, DataFlowInfo.getEmpty(), TypeUtils.NO_EXPECTED_TYPE, TypeUtils.NO_EXPECTED_TYPE)); - } - - public CallResolver getCallResolver() { - return callResolver; - } - -// TODO JetElement -> JetWhenConditionCall || JetQualifiedExpression -// private void checkNullSafety(@Nullable JetType receiverType, @NotNull ASTNode operationTokenNode, @Nullable FunctionDescriptor callee, @NotNull JetElement element) { -// if (receiverType != null && callee != null) { -// boolean namespaceType = receiverType instanceof NamespaceType; -// boolean nullableReceiver = !namespaceType && receiverType.isNullable(); -// ReceiverDescriptor calleeReceiver = callee.getReceiverParameter(); -// boolean calleeForbidsNullableReceiver = !calleeReceiver.exists() || !calleeReceiver.getType().isNullable(); -// -// IElementType operationSign = operationTokenNode.getElementType(); -// if (nullableReceiver && calleeForbidsNullableReceiver && operationSign == JetTokens.DOT) { -//// trace.getErrorHandler().genericError(operationTokenNode, "Only safe calls (?.) are allowed on a nullable receiver of type " + receiverType); -// trace.report(UNSAFE_CALL.on(operationTokenNode, receiverType)); -// } -// else if ((!nullableReceiver || !calleeForbidsNullableReceiver) && operationSign == JetTokens.SAFE_ACCESS) { -// if (namespaceType) { -//// trace.getErrorHandler().genericError(operationTokenNode, "Safe calls are not allowed on namespaces"); -// trace.report(SAFE_CALLS_ARE_NOT_ALLOWED_ON_NAMESPACES.on(operationTokenNode)); -// } -// else { -//// trace.getErrorHandler().genericWarning(operationTokenNode, "Unnecessary safe call on a non-null receiver of type " + receiverType); -// -// trace.report(UNNECESSARY_SAFE_CALL.on(element, operationTokenNode, receiverType)); -// -// } -// } -// } -// } - - public void checkFunctionReturnType(@NotNull JetScope outerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor) { - checkFunctionReturnType(outerScope, function, functionDescriptor, DataFlowInfo.getEmpty()); - } - - /*package*/ void checkFunctionReturnType(@NotNull JetScope outerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor, DataFlowInfo dataFlowInfo) { - JetType expectedReturnType = functionDescriptor.getReturnType(); - if (!function.hasBlockBody() && !function.hasDeclaredReturnType()) { - expectedReturnType = TypeUtils.NO_EXPECTED_TYPE; - } - JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace); - checkFunctionReturnType(functionInnerScope, function, functionDescriptor, expectedReturnType, dataFlowInfo); -// Map typeMap = collectReturnedExpressionsWithTypes(outerScope, function, functionDescriptor, expectedReturnType); -// if (typeMap.isEmpty()) { -// return; // The function returns Nothing -// } -// for (Map.Entry entry : typeMap.entrySet()) { -// JetType actualType = entry.castValue(); -// JetElement element = entry.getKey(); -// JetTypeChecker typeChecker = semanticServices.getTypeChecker(); -// if (!typeChecker.isSubtypeOf(actualType, expectedReturnType)) { -// if (typeChecker.isConvertibleBySpecialConversion(actualType, expectedReturnType)) { -// if (expectedReturnType.getConstructor().equals(JetStandardClasses.getUnitType().getConstructor()) -// && element.getParent() instanceof JetReturnExpression) { -// context.trace.getErrorHandler().genericError(element.getNode(), "This function must return a value of type Unit"); -// } -// } -// else { -// if (element == function) { -// JetExpression bodyExpression = function.getBodyExpression(); -// assert bodyExpression != null; -// context.trace.getErrorHandler().genericError(bodyExpression.getNode(), "This function must return a value of type " + expectedReturnType); -// } -// else if (element instanceof JetExpression) { -// JetExpression expression = (JetExpression) element; -// context.trace.report(TYPE_MISMATCH.on(expression, expectedReturnType, actualType)); -// } -// else { -// context.trace.getErrorHandler().genericError(element.getNode(), "This function must return a value of type " + expectedReturnType); -// } -// } -// } -// } - } - - public void checkFunctionReturnType(JetScope functionInnerScope, JetDeclarationWithBody function, FunctionDescriptor functionDescriptor, @NotNull final JetType expectedReturnType) { - checkFunctionReturnType(functionInnerScope, function, functionDescriptor, expectedReturnType, DataFlowInfo.getEmpty()); - } - - /*package*/ void checkFunctionReturnType(JetScope functionInnerScope, JetDeclarationWithBody function, FunctionDescriptor functionDescriptor, @NotNull final JetType expectedReturnType, @NotNull DataFlowInfo dataFlowInfo) { - JetExpression bodyExpression = function.getBodyExpression(); - if (bodyExpression == null) return; - - final boolean blockBody = function.hasBlockBody(); - final ExpressionTypingContext context = - blockBody - ? ExpressionTypingContext.newRootContext(semanticServices, trace, functionInnerScope, dataFlowInfo, TypeUtils.NO_EXPECTED_TYPE, expectedReturnType) - : ExpressionTypingContext.newRootContext(semanticServices, trace, functionInnerScope, dataFlowInfo, expectedReturnType, TypeUtils.FORBIDDEN); - - if (function instanceof JetFunctionLiteralExpression) { - JetFunctionLiteralExpression functionLiteralExpression = (JetFunctionLiteralExpression) function; - getBlockReturnedType(functionInnerScope, functionLiteralExpression.getBodyExpression(), CoercionStrategy.COERCION_TO_UNIT, context); - } - else { - expressionTyperVisitor.getType(bodyExpression, context); - } - -// List unreachableElements = Lists.newArrayList(); -// flowInformationProvider.collectUnreachableExpressions(function.asElement(), unreachableElements); - - // This is needed in order to highlight only '1 < 2' and not '1', '<' and '2' as well -// final Set rootUnreachableElements = JetPsiUtil.findRootExpressions(unreachableElements); - - // TODO : (return 1) || (return 2) -- only || and right of it is unreachable - // TODO : try {return 1} finally {return 2}. Currently 'return 1' is reported as unreachable, - // though it'd better be reported more specifically - -// for (JetElement element : rootUnreachableElements) { -// //trace.report(UNREACHABLE_CODE.on(element)); -// } - -// List returnedExpressions = Lists.newArrayList(); -// flowInformationProvider.collectReturnExpressions(function.asElement(), returnedExpressions); - -// boolean nothingReturned = returnedExpressions.isEmpty(); - - //returnedExpressions.remove(function); // This will be the only "expression" if the body is empty -// Map typeMap = collectReturnedExpressionsWithTypes(trace, functionInnerScope, function, functionDescriptor); -// Set returnedExpressions = typeMap.keySet(); -// -// -// if (expectedReturnType != NO_EXPECTED_TYPE && !JetStandardClasses.isUnit(expectedReturnType) && returnedExpressions.isEmpty()) { -// trace.report(RETURN_TYPE_MISMATCH.on(bodyExpression, expectedReturnType)); -// } - -// if (expectedReturnType != NO_EXPECTED_TYPE && !JetStandardClasses.isUnit(expectedReturnType) && returnedExpressions.isEmpty() && !nothingReturned) { -//// trace.getErrorHandler().genericError(bodyExpression.getNode(), "This function must return a value of type " + expectedReturnType); -// trace.report(RETURN_TYPE_MISMATCH.on(bodyExpression, expectedReturnType)); -// } -// -// for (JetExpression returnedExpression : returnedExpressions) { -// returnedExpression.accept(new JetVisitorVoid() { -// @Override -// public void visitReturnExpression(JetReturnExpression expression) { -// if (!blockBody) { -//// trace.getErrorHandler().genericError(expression.getNode(), "Returns are not allowed for functions with expression body. Use block body in '{...}'"); -// trace.report(RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY.on(expression)); -// } -// } -// -// @Override -// public void visitExpression(JetExpression expression) { -// if (blockBody && !JetStandardClasses.isUnit(expectedReturnType) && !rootUnreachableElements.contains(expression)) { -// //TODO move to pseudocode -// JetType type = expressionTyperVisitor.getType(expression, context.replaceExpectedType(NO_EXPECTED_TYPE)); -// if (type == null || !JetStandardClasses.isNothing(type)) { -//// trace.getErrorHandler().genericError(expression.getNode(), "A 'return' expression required in a function with a block body ('{...}')"); -// trace.report(NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY.on(expression)); -// } -// } -// } -// }); -// } - } - - @Nullable - /*package*/ JetType getBlockReturnedType(@NotNull JetScope outerScope, @NotNull JetBlockExpression expression, @NotNull CoercionStrategy coercionStrategyForLastExpression, ExpressionTypingContext context) { - List block = expression.getStatements(); - if (block.isEmpty()) { - return checkType(JetStandardClasses.getUnitType(), expression, context); - } - - DeclarationDescriptor containingDescriptor = outerScope.getContainingDeclaration(); - WritableScope scope = new WritableScopeImpl(outerScope, containingDescriptor, new TraceBasedRedeclarationHandler(context.trace)).setDebugName("getBlockReturnedType"); - return getBlockReturnedTypeWithWritableScope(scope, block, coercionStrategyForLastExpression, context); - } - - @NotNull - public JetType inferFunctionReturnType(@NotNull JetScope outerScope, JetDeclarationWithBody function, FunctionDescriptor functionDescriptor) { - Map typeMap = collectReturnedExpressionsWithTypes(trace, outerScope, function, functionDescriptor); - Collection types = typeMap.values(); - return types.isEmpty() - ? JetStandardClasses.getNothingType() - : semanticServices.getTypeChecker().commonSupertype(types); - } - - private Map collectReturnedExpressionsWithTypes( - final @NotNull BindingTrace trace, - JetScope outerScope, - final JetDeclarationWithBody function, - FunctionDescriptor functionDescriptor) { - JetExpression bodyExpression = function.getBodyExpression(); - assert bodyExpression != null; - JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace); - expressionTyperVisitor.getType(bodyExpression, ExpressionTypingContext.newRootContext(semanticServices, trace, functionInnerScope, DataFlowInfo.getEmpty(), TypeUtils.NO_EXPECTED_TYPE, TypeUtils.FORBIDDEN)); - //todo function literals - final Collection returnedExpressions = new ArrayList(); - if (function.hasBlockBody()) { - //now this code is never invoked!, it should be invoked for inference of return type of function literal with local returns - bodyExpression.visit(new JetTreeVisitor() { - @Override - public Void visitReturnExpression(JetReturnExpression expression, JetDeclarationWithBody outerFunction) { - JetSimpleNameExpression targetLabel = expression.getTargetLabel(); - PsiElement element = targetLabel != null ? trace.get(LABEL_TARGET, targetLabel) : null; - if (element == function || (targetLabel == null && outerFunction == function)) { - returnedExpressions.add(expression); - } - return null; - } - - @Override - public Void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression, JetDeclarationWithBody outerFunction) { - return super.visitFunctionLiteralExpression(expression, expression.getFunctionLiteral()); - } - - @Override - public Void visitNamedFunction(JetNamedFunction function, JetDeclarationWithBody outerFunction) { - return super.visitNamedFunction(function, function); - } - }, function); - } - else { - returnedExpressions.add(bodyExpression); - } - Map typeMap = new HashMap(); - for (JetExpression returnedExpression : returnedExpressions) { - JetType cachedType = trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, returnedExpression); - trace.record(STATEMENT, returnedExpression, false); - if (cachedType != null) { - typeMap.put(returnedExpression, cachedType); - } - } - return typeMap; - } - - /*package*/ JetType getBlockReturnedTypeWithWritableScope(@NotNull WritableScope scope, @NotNull List block, @NotNull CoercionStrategy coercionStrategyForLastExpression, ExpressionTypingContext context) { - if (block.isEmpty()) { - return JetStandardClasses.getUnitType(); - } - - ExpressionTyperVisitorWithWritableScope blockLevelVisitor = newTypeInferrerVisitorWithWritableScope(scope); - ExpressionTypingContext newContext = ExpressionTypingContext.newRootContext(semanticServices, trace, scope, context.dataFlowInfo, TypeUtils.NO_EXPECTED_TYPE, context.expectedReturnType); - - JetType result = null; - for (Iterator iterator = block.iterator(); iterator.hasNext(); ) { - final JetElement statement = iterator.next(); - trace.record(STATEMENT, statement); - final JetExpression statementExpression = (JetExpression) statement; - //TODO constructor assert context.expectedType != FORBIDDEN : "" - if (!iterator.hasNext()) { - if (context.expectedType != TypeUtils.NO_EXPECTED_TYPE) { - if (coercionStrategyForLastExpression == CoercionStrategy.COERCION_TO_UNIT && JetStandardClasses.isUnit(context.expectedType)) { - // This implements coercion to Unit - TemporaryBindingTrace temporaryTraceExpectingUnit = TemporaryBindingTrace.create(trace); - final boolean[] mismatch = new boolean[1]; - ObservableBindingTrace errorInterceptingTrace = makeTraceInterceptingTypeMismatch(temporaryTraceExpectingUnit, statementExpression, mismatch); - newContext = ExpressionTypingContext.newRootContext(semanticServices, errorInterceptingTrace, scope, newContext.dataFlowInfo, context.expectedType, context.expectedReturnType); - result = blockLevelVisitor.getType(statementExpression, newContext); - if (mismatch[0]) { - TemporaryBindingTrace temporaryTraceNoExpectedType = TemporaryBindingTrace.create(trace); - mismatch[0] = false; - ObservableBindingTrace interceptingTrace = makeTraceInterceptingTypeMismatch(temporaryTraceNoExpectedType, statementExpression, mismatch); - newContext = ExpressionTypingContext.newRootContext(semanticServices, interceptingTrace, scope, newContext.dataFlowInfo, TypeUtils.NO_EXPECTED_TYPE, context.expectedReturnType); - result = blockLevelVisitor.getType(statementExpression, newContext); - if (mismatch[0]) { - temporaryTraceExpectingUnit.commit(); - } - else { - temporaryTraceNoExpectedType.commit(); - } - } - else { - temporaryTraceExpectingUnit.commit(); - } - } - else { - newContext = ExpressionTypingContext.newRootContext(semanticServices, trace, scope, newContext.dataFlowInfo, context.expectedType, context.expectedReturnType); - result = blockLevelVisitor.getType(statementExpression, newContext); - } - } - else { - result = blockLevelVisitor.getType(statementExpression, newContext); - if (coercionStrategyForLastExpression == CoercionStrategy.COERCION_TO_UNIT) { - boolean mightBeUnit = false; - if (statementExpression instanceof JetDeclaration) { - mightBeUnit = true; - } - if (statementExpression instanceof JetBinaryExpression) { - JetBinaryExpression binaryExpression = (JetBinaryExpression) statementExpression; - IElementType operationType = binaryExpression.getOperationToken(); - if (operationType == JetTokens.EQ || OperatorConventions.ASSIGNMENT_OPERATIONS.containsKey(operationType)) { - mightBeUnit = true; - } - } - if (mightBeUnit) { - // ExpressionTyperVisitorWithWritableScope should return only null or Unit for declarations and assignments - assert result == null || JetStandardClasses.isUnit(result); - result = JetStandardClasses.getUnitType(); - } - } - } - } - else { - result = blockLevelVisitor.getType(statementExpression, newContext); - } - - DataFlowInfo newDataFlowInfo = blockLevelVisitor.getResultingDataFlowInfo(); - if (newDataFlowInfo == null) { - newDataFlowInfo = context.dataFlowInfo; - } - if (newDataFlowInfo != context.dataFlowInfo) { - newContext = ExpressionTypingContext.newRootContext(semanticServices, trace, scope, newDataFlowInfo, TypeUtils.NO_EXPECTED_TYPE, context.expectedReturnType); - } - blockLevelVisitor.resetResult(); // TODO : maybe it's better to recreate the visitors with the same scope? - } - return result; - } - - private ObservableBindingTrace makeTraceInterceptingTypeMismatch(final BindingTrace trace, final JetExpression expressionToWatch, final boolean[] mismatchFound) { - return new ObservableBindingTrace(trace) { - - @Override - public void report(@NotNull Diagnostic diagnostic) { - if (diagnostic.getFactory() == TYPE_MISMATCH && ((DiagnosticWithPsiElement) diagnostic).getPsiElement() == expressionToWatch) { - mismatchFound[0] = true; - } - super.report(diagnostic); - } - }; - } - -// //TODO -// private JetType enrichOutType(JetExpression expression, JetType initialType, @NotNull ExpressionTypingContext context) { -// if (expression == null) return initialType; -// VariableDescriptor variableDescriptor = getVariableDescriptorFromSimpleName(expression, context); -// if (variableDescriptor != null) { -// return context.dataFlowInfo.getOutType(variableDescriptor); -// } -// return initialType; -// } - -// @Nullable -// private JetType checkType(@Nullable JetType expressionType, @NotNull JetExpression expression, @NotNull ExpressionTypingContext context) { -// if (expressionType != null && context.expectedType != null && context.expectedType != NO_EXPECTED_TYPE) { -// if (!semanticServices.getTypeChecker().isSubtypeOf(expressionType, context.expectedType)) { -// context.trace.report(TYPE_MISMATCH.on(expression, context.expectedType, expressionType)); -// } -// } -// return expressionType; -// } - - @Nullable - /*package*/ JetType checkType(@Nullable JetType expressionType, @NotNull JetExpression expression, @NotNull ExpressionTypingContext context) { - if (expressionType == null || context.expectedType == null || context.expectedType == TypeUtils.NO_EXPECTED_TYPE || - semanticServices.getTypeChecker().isSubtypeOf(expressionType, context.expectedType)) { - return expressionType; - } -// VariableDescriptor variableDescriptor = AutoCastUtils.getVariableDescriptorFromSimpleName(context.trace.getBindingContext(), expression); -// boolean appropriateTypeFound = false; -// if (variableDescriptor != null) { -// List possibleTypes = Lists.newArrayList(context.dataFlowInfo.getPossibleTypesForVariable(variableDescriptor)); -// Collections.reverse(possibleTypes); -// for (JetType possibleType : possibleTypes) { -// if (semanticServices.getTypeChecker().isSubtypeOf(possibleType, context.expectedType)) { -// appropriateTypeFound = true; -// break; -// } -// } -// if (!appropriateTypeFound) { -// JetType notnullType = context.dataFlowInfo.getOutType(variableDescriptor); -// if (notnullType != null && semanticServices.getTypeChecker().isSubtypeOf(notnullType, context.expectedType)) { -// appropriateTypeFound = true; -// } -// } -// } - if (AutoCastUtils.castExpression(expression, context.expectedType, context.dataFlowInfo, context.trace) == null) { -// context.trace.getErrorHandler().typeMismatch(expression, context.expectedType, expressionType); - context.trace.report(TYPE_MISMATCH.on(expression, context.expectedType, expressionType)); - return expressionType; - } -// checkAutoCast(expression, context.expectedType, variableDescriptor, context.trace); - return context.expectedType; - } - -// private void checkAutoCast(JetExpression expression, JetType type, VariableDescriptor variableDescriptor, BindingTrace trace) { -// if (variableDescriptor.isVar()) { -//// trace.getErrorHandler().genericError(expression.getNode(), "Automatic cast to " + type + " is impossible, because variable " + variableDescriptor.getName() + " is mutable"); -// trace.report(AUTOCAST_IMPOSSIBLE.on(expression, type, variableDescriptor)); -// } else { -// trace.record(BindingContext.AUTOCAST, expression, type); -// } -// } - - @NotNull - /*package*/ List checkArgumentTypes(@NotNull List argumentTypes, @NotNull List arguments, @NotNull List expectedArgumentTypes, @NotNull ExpressionTypingContext context) { - if (arguments.size() == 0 || argumentTypes.size() != arguments.size() || expectedArgumentTypes.size() != arguments.size()) { - return argumentTypes; - } - List result = Lists.newArrayListWithCapacity(arguments.size()); - for (int i = 0, argumentTypesSize = argumentTypes.size(); i < argumentTypesSize; i++) { - result.add(checkType(argumentTypes.get(i), arguments.get(i), context.replaceExpectedType(expectedArgumentTypes.get(i).getType()))); - } - return result; - } - - @Nullable - /*package*/ VariableDescriptor getVariableDescriptorFromSimpleName(@NotNull JetExpression receiverExpression, @NotNull ExpressionTypingContext context) { - if (receiverExpression instanceof JetBinaryExpressionWithTypeRHS) { - JetBinaryExpressionWithTypeRHS expression = (JetBinaryExpressionWithTypeRHS) receiverExpression; - if (expression.getOperationSign().getReferencedNameElementType() == JetTokens.COLON) { - return getVariableDescriptorFromSimpleName(expression.getLeft(), context); - } - } - VariableDescriptor variableDescriptor = null; - if (receiverExpression instanceof JetSimpleNameExpression) { - JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) receiverExpression; - DeclarationDescriptor declarationDescriptor = context.trace.getBindingContext().get(REFERENCE_TARGET, nameExpression); - if (declarationDescriptor instanceof VariableDescriptor) { - variableDescriptor = (VariableDescriptor) declarationDescriptor; - } - } - return variableDescriptor; - } -} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTyperVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTyperVisitor.java deleted file mode 100644 index 3e1b90f0d63..00000000000 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTyperVisitor.java +++ /dev/null @@ -1,1944 +0,0 @@ -package org.jetbrains.jet.lang.types.expressions; - -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import com.intellij.lang.ASTNode; -import com.intellij.psi.PsiElement; -import com.intellij.psi.tree.IElementType; -import com.intellij.psi.tree.TokenSet; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.JetNodeTypes; -import org.jetbrains.jet.lang.JetSemanticServices; -import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; -import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.*; -import org.jetbrains.jet.lang.resolve.calls.CallMaker; -import org.jetbrains.jet.lang.resolve.calls.DataFlowInfo; -import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; -import org.jetbrains.jet.lang.resolve.constants.*; -import org.jetbrains.jet.lang.resolve.scopes.JetScope; -import org.jetbrains.jet.lang.resolve.scopes.WritableScope; -import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; -import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; -import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; -import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver; -import org.jetbrains.jet.lang.types.*; -import org.jetbrains.jet.lexer.JetTokens; -import org.jetbrains.jet.util.lazy.LazyValueWithDefault; -import org.jetbrains.jet.util.lazy.ReenteringLazyValueComputationException; -import org.jetbrains.jet.util.slicedmap.WritableSlice; - -import java.util.*; - -import static org.jetbrains.jet.lang.diagnostics.Errors.*; -import static org.jetbrains.jet.lang.resolve.BindingContext.*; -import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor.NO_RECEIVER; - -/** -* @author abreslav -*/ -public class ExpressionTyperVisitor extends JetVisitor { - protected DataFlowInfo resultDataFlowInfo; - - @Nullable - public DataFlowInfo getResultingDataFlowInfo() { - return resultDataFlowInfo; - } - - @NotNull - public final JetType safeGetType(@NotNull JetExpression expression, ExpressionTypingContext context) { - JetType type = getType(expression, context); - if (type != null) { - return type; - } - return ErrorUtils.createErrorType("Type for " + expression.getText()); - } - - @Nullable - public final ExpressionReceiver getExpressionReceiver(@NotNull JetExpression expression, ExpressionTypingContext context) { - JetType type = getType(expression, context); - if (type == null) { - return null; - } - return new ExpressionReceiver(expression, type); - } - - @NotNull - public final ExpressionReceiver safeGetExpressionReceiver(@NotNull JetExpression expression, ExpressionTypingContext context) { - return new ExpressionReceiver(expression, safeGetType(expression, context)); - } - - @Nullable - public final JetType getType(@NotNull JetExpression expression, ExpressionTypingContext context) { - if (context.trace.get(BindingContext.PROCESSED, expression)) { - return context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression); - } - JetType result; - try { - result = expression.visit(this, context); - // Some recursive definitions (object expressions) must put their types in the cache manually: - if (context.trace.get(BindingContext.PROCESSED, expression)) { - return context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression); - } - - if (result instanceof DeferredType) { - result = ((DeferredType) result).getActualType(); - } - if (result != null) { - context.trace.record(BindingContext.EXPRESSION_TYPE, expression, result); -// if (JetStandardClasses.isNothing(result) && !result.isNullable()) { -// markDominatedExpressionsAsUnreachable(expression, context); -// } - } -// } - } - catch (ReenteringLazyValueComputationException e) { -// context.trace.getErrorHandler().genericError(expression.getNode(), "Type checking has run into a recursive problem"); // TODO : message - context.trace.report(TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM.on(expression)); - result = null; - } - - if (!context.trace.get(BindingContext.PROCESSED, expression)) { - context.trace.record(BindingContext.RESOLUTION_SCOPE, expression, context.scope); - } - context.trace.record(BindingContext.PROCESSED, expression); - return result; - } - - private JetType getTypeWithNewScopeAndDataFlowInfo(@NotNull JetScope scope, @NotNull JetExpression expression, @NotNull DataFlowInfo newDataFlowInfo, @NotNull ExpressionTypingContext context) { - return getType(expression, context.replaceScope(scope).replaceDataFlowInfo(newDataFlowInfo)); - } - - - public void resetResult() { -// result = null; - resultDataFlowInfo = null; -// resultScope = null; - } - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -// private void markDominatedExpressionsAsUnreachable(JetExpression expression, ExpressionTypingContext context) { -// List dominated = new ArrayList(); -// flowInformationProvider.collectDominatedExpressions(expression, dominated); -// Set rootExpressions = JetPsiUtil.findRootExpressions(dominated); -// for (JetElement rootExpression : rootExpressions) { -//// context.trace.getErrorHandler().genericError(rootExpression.getNode(), -//// "This code is unreachable, because '" + expression.getText() + "' never terminates normally"); -// context.trace.report(UNREACHABLE_BECAUSE_OF_NOTHING.on(rootExpression, expression.getText())); -// } -// } - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - @Override - public JetType visitSimpleNameExpression(JetSimpleNameExpression expression, ExpressionTypingContext context) { - // TODO : other members - // TODO : type substitutions??? - String referencedName = expression.getReferencedName(); - if (expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER - && referencedName != null) { - PropertyDescriptor property = context.scope.getPropertyByFieldReference(referencedName); - if (property == null) { - context.trace.report(UNRESOLVED_REFERENCE.on(expression)); - } - else { - context.trace.record(REFERENCE_TARGET, expression, property); - return context.getServices().checkType(property.getOutType(), expression, context); - } - } - else { - return getSelectorReturnType(NO_RECEIVER, null, expression, context); // TODO : Extensions to this -// assert JetTokens.IDENTIFIER == expression.getReferencedNameElementType(); -// if (referencedName != null) { -// VariableDescriptor variable = context.scope.getVariable(referencedName); -// if (variable != null) { -// context.trace.record(REFERENCE_TARGET, expression, variable); -// JetType result = variable.getOutType(); -// if (result == null) { -// context.trace.getErrorHandler().genericError(expression.getNode(), "This variable is not readable in this context"); -// } -// return context.getServices().checkType(result, expression, context); -// } -// else { -// return lookupNamespaceOrClassObject(expression, referencedName, context); -// ClassifierDescriptor classifier = context.scope.getClassifier(referencedName); -// if (classifier != null) { -// JetType classObjectType = classifier.getClassObjectType(); -// JetType result = null; -// if (classObjectType != null && (isNamespacePosition() || classifier.isClassObjectAValue())) { -// result = classObjectType; -// } -// else { -// context.trace.getErrorHandler().genericError(expression.getNode(), "Classifier " + classifier.getName() + " does not have a class object"); -// } -// context.trace.record(REFERENCE_TARGET, expression, classifier); -// return context.getServices().checkType(result, expression, context); -// } -// else { -// JetType[] result = new JetType[1]; -// if (furtherNameLookup(expression, referencedName, result, context)) { -// return context.getServices().checkType(result[0], expression, context); -// } -// -// } -// } -// context.trace.report(UNRESOLVED_REFERENCE.on(expression)); -// } - } - return null; - } - - private JetType lookupNamespaceOrClassObject(JetSimpleNameExpression expression, String referencedName, ExpressionTypingContext context) { - ClassifierDescriptor classifier = context.scope.getClassifier(referencedName); - if (classifier != null) { - JetType classObjectType = classifier.getClassObjectType(); - JetType result = null; - if (classObjectType != null) { - if (isNamespacePosition() || classifier.isClassObjectAValue()) { - result = classObjectType; - } - else { -// context.trace.getErrorHandler().genericError(expression.getNode(), "Classifier " + classifier.getName() + " does not have a class object"); - context.trace.report(NO_CLASS_OBJECT.on(expression, classifier)); - } - context.trace.record(REFERENCE_TARGET, expression, classifier); - if (result == null) { - return ErrorUtils.createErrorType("No class object in " + expression.getReferencedName()); - } - return context.getServices().checkType(result, expression, context); - } - } - JetType[] result = new JetType[1]; - TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace); - if (furtherNameLookup(expression, referencedName, result, context.replaceBindingTrace(temporaryTrace))) { - temporaryTrace.commit(); - return context.getServices().checkType(result[0], expression, context); - } - // To report NO_CLASS_OBJECT when no namespace found - if (classifier != null) { - context.trace.report(NO_CLASS_OBJECT.on(expression, classifier)); - context.trace.record(REFERENCE_TARGET, expression, classifier); - return ErrorUtils.createErrorType("No class object in " + expression.getReferencedName()); - } - temporaryTrace.commit(); - return result[0]; - } - - public boolean isNamespacePosition() { - return false; - } - - protected boolean furtherNameLookup(@NotNull JetSimpleNameExpression expression, @NotNull String referencedName, @NotNull JetType[] result, ExpressionTypingContext context) { - NamespaceType namespaceType = lookupNamespaceType(expression, referencedName, context); - if (namespaceType != null) { -// context.trace.getErrorHandler().genericError(expression.getNode(), "Expression expected, but a namespace name found"); - context.trace.report(EXPRESSION_EXPECTED_NAMESPACE_FOUND.on(expression)); - result[0] = ErrorUtils.createErrorType("Type for " + referencedName); - } - return false; - } - - @Nullable - protected NamespaceType lookupNamespaceType(@NotNull JetSimpleNameExpression expression, @NotNull String referencedName, ExpressionTypingContext context) { - NamespaceDescriptor namespace = context.scope.getNamespace(referencedName); - if (namespace == null) { - return null; - } - context.trace.record(REFERENCE_TARGET, expression, namespace); - return namespace.getNamespaceType(); - } - - @Override - public JetType visitObjectLiteralExpression(final JetObjectLiteralExpression expression, final ExpressionTypingContext context) { - final JetType[] result = new JetType[1]; - ObservableBindingTrace.RecordHandler handler = new ObservableBindingTrace.RecordHandler() { - - @Override - public void handleRecord(WritableSlice slice, PsiElement declaration, final ClassDescriptor descriptor) { - if (slice == CLASS && declaration == expression.getObjectDeclaration()) { - JetType defaultType = DeferredType.create(context.trace, new LazyValueWithDefault(ErrorUtils.createErrorType("Recursive dependency")) { - @Override - protected JetType compute() { - return descriptor.getDefaultType(); - } - }); - result[0] = defaultType; - if (!context.trace.get(PROCESSED, expression)) { - context.trace.record(EXPRESSION_TYPE, expression, defaultType); - context.trace.record(PROCESSED, expression); - } - } - } - }; - ObservableBindingTrace traceAdapter = new ObservableBindingTrace(context.trace); - traceAdapter.addHandler(CLASS, handler); - TopDownAnalyzer.processObject(context.semanticServices, traceAdapter, context.scope, context.scope.getContainingDeclaration(), expression.getObjectDeclaration()); - return context.getServices().checkType(result[0], expression, context); - } - - @Override - public JetType visitFunctionLiteralExpression(JetFunctionLiteralExpression expression, ExpressionTypingContext context) { - JetFunctionLiteral functionLiteral = expression.getFunctionLiteral(); - - JetTypeReference receiverTypeRef = functionLiteral.getReceiverTypeRef(); - final JetType receiverType; - if (receiverTypeRef != null) { - receiverType = context.getTypeResolver().resolveType(context.scope, receiverTypeRef); - } else { - ReceiverDescriptor implicitReceiver = context.scope.getImplicitReceiver(); - receiverType = implicitReceiver.exists() ? implicitReceiver.getType() : null; - } - - FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl( - context.scope.getContainingDeclaration(), Collections.emptyList(), ""); - - List parameterTypes = new ArrayList(); - List valueParameterDescriptors = Lists.newArrayList(); - List declaredValueParameters = functionLiteral.getValueParameters(); - JetType expectedType = context.expectedType; - - boolean functionTypeExpected = expectedType != TypeUtils.NO_EXPECTED_TYPE && JetStandardClasses.isFunctionType(expectedType); - List expectedValueParameters = (functionTypeExpected) - ? JetStandardClasses.getValueParameters(functionDescriptor, expectedType) - : null; - - if (functionTypeExpected && declaredValueParameters.isEmpty() && expectedValueParameters.size() == 1) { - ValueParameterDescriptor valueParameterDescriptor = expectedValueParameters.get(0); - ValueParameterDescriptor it = new ValueParameterDescriptorImpl( - functionDescriptor, 0, Collections.emptyList(), "it", valueParameterDescriptor.getInType(), valueParameterDescriptor.getOutType(), valueParameterDescriptor.hasDefaultValue(), valueParameterDescriptor.isVararg() - ); - valueParameterDescriptors.add(it); - parameterTypes.add(it.getOutType()); - context.trace.record(AUTO_CREATED_IT, it); - } - else { - for (int i = 0; i < declaredValueParameters.size(); i++) { - JetParameter declaredParameter = declaredValueParameters.get(i); - JetTypeReference typeReference = declaredParameter.getTypeReference(); - - JetType type; - if (typeReference != null) { - type = context.getTypeResolver().resolveType(context.scope, typeReference); - } - else { - if (expectedValueParameters != null && i < expectedValueParameters.size()) { - type = expectedValueParameters.get(i).getOutType(); - } - else { -// context.trace.getErrorHandler().genericError(declaredParameter.getNode(), "Cannot infer a type for this declaredParameter. To specify it explicitly use the {(p : Type) => ...} notation"); - context.trace.report(CANNOT_INFER_PARAMETER_TYPE.on(declaredParameter)); - type = ErrorUtils.createErrorType("Cannot be inferred"); - } - } - ValueParameterDescriptor valueParameterDescriptor = context.getClassDescriptorResolver().resolveValueParameterDescriptor(functionDescriptor, declaredParameter, i, type); - parameterTypes.add(valueParameterDescriptor.getOutType()); - valueParameterDescriptors.add(valueParameterDescriptor); - } - } - - JetType effectiveReceiverType; - if (receiverTypeRef == null) { - if (functionTypeExpected) { - effectiveReceiverType = JetStandardClasses.getReceiverType(expectedType); - } - else { - effectiveReceiverType = null; - } - } - else { - effectiveReceiverType = receiverType; - } - functionDescriptor.initialize(effectiveReceiverType, NO_RECEIVER, Collections.emptyList(), valueParameterDescriptors, null, Modality.FINAL, Visibility.LOCAL); - context.trace.record(BindingContext.FUNCTION, expression, functionDescriptor); - - JetType returnType = TypeUtils.NO_EXPECTED_TYPE; - JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace); - JetTypeReference returnTypeRef = functionLiteral.getReturnTypeRef(); - if (returnTypeRef != null) { - returnType = context.getTypeResolver().resolveType(context.scope, returnTypeRef); - context.getServices().checkFunctionReturnType(functionInnerScope, expression, functionDescriptor, returnType, context.dataFlowInfo); - } - else { - if (functionTypeExpected) { - returnType = JetStandardClasses.getReturnType(expectedType); - } - returnType = context.getServices().getBlockReturnedType(functionInnerScope, functionLiteral.getBodyExpression(), CoercionStrategy.COERCION_TO_UNIT, context.replaceExpectedType(returnType)); - } - JetType safeReturnType = returnType == null ? ErrorUtils.createErrorType("") : returnType; - functionDescriptor.setReturnType(safeReturnType); - - if (functionTypeExpected) { - JetType expectedReturnType = JetStandardClasses.getReturnType(expectedType); - if (JetStandardClasses.isUnit(expectedReturnType)) { - functionDescriptor.setReturnType(expectedReturnType); - return context.getServices().checkType(JetStandardClasses.getFunctionType(Collections.emptyList(), effectiveReceiverType, parameterTypes, expectedReturnType), expression, context); - } - - } - return context.getServices().checkType(JetStandardClasses.getFunctionType(Collections.emptyList(), effectiveReceiverType, parameterTypes, safeReturnType), expression, context); - } - - @Override - public JetType visitParenthesizedExpression(JetParenthesizedExpression expression, ExpressionTypingContext context) { - JetExpression innerExpression = expression.getExpression(); - if (innerExpression == null) { - return null; - } - return context.getServices().checkType(getType(innerExpression, context.replaceScope(context.scope)), expression, context); - } - - @Override - public JetType visitConstantExpression(JetConstantExpression expression, ExpressionTypingContext context) { - ASTNode node = expression.getNode(); - IElementType elementType = node.getElementType(); - String text = node.getText(); - JetStandardLibrary standardLibrary = context.semanticServices.getStandardLibrary(); - CompileTimeConstantResolver compileTimeConstantResolver = context.getCompileTimeConstantResolver(); - - CompileTimeConstant value; - if (elementType == JetNodeTypes.INTEGER_CONSTANT) { - value = compileTimeConstantResolver.getIntegerValue(text, context.expectedType); - } - else if (elementType == JetNodeTypes.FLOAT_CONSTANT) { - value = compileTimeConstantResolver.getFloatValue(text, context.expectedType); - } - else if (elementType == JetNodeTypes.BOOLEAN_CONSTANT) { - value = compileTimeConstantResolver.getBooleanValue(text, context.expectedType); - } - else if (elementType == JetNodeTypes.CHARACTER_CONSTANT) { - value = compileTimeConstantResolver.getCharValue(text, context.expectedType); - } - else if (elementType == JetNodeTypes.RAW_STRING_CONSTANT) { - value = compileTimeConstantResolver.getRawStringValue(text, context.expectedType); - } - else if (elementType == JetNodeTypes.NULL) { - value = compileTimeConstantResolver.getNullValue(context.expectedType); - } - else { - throw new IllegalArgumentException("Unsupported constant: " + expression); - } - if (value instanceof ErrorValue) { - ErrorValue errorValue = (ErrorValue) value; -// context.trace.getErrorHandler().genericError(node, errorValue.getMessage()); - context.trace.report(ERROR_COMPILE_TIME_VALUE.on(node, errorValue.getMessage())); - return getDefaultType(context.semanticServices, elementType); - } - else { - context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, value); - return context.getServices().checkType(value.getType(standardLibrary), expression, context); - } - } - - @NotNull - private JetType getDefaultType(JetSemanticServices semanticServices, IElementType constantType) { - if (constantType == JetNodeTypes.INTEGER_CONSTANT) { - return semanticServices.getStandardLibrary().getIntType(); - } - else if (constantType == JetNodeTypes.FLOAT_CONSTANT) { - return semanticServices.getStandardLibrary().getDoubleType(); - } - else if (constantType == JetNodeTypes.BOOLEAN_CONSTANT) { - return semanticServices.getStandardLibrary().getBooleanType(); - } - else if (constantType == JetNodeTypes.CHARACTER_CONSTANT) { - return semanticServices.getStandardLibrary().getCharType(); - } - else if (constantType == JetNodeTypes.RAW_STRING_CONSTANT) { - return semanticServices.getStandardLibrary().getStringType(); - } - else if (constantType == JetNodeTypes.NULL) { - return JetStandardClasses.getNullableNothingType(); - } - else { - throw new IllegalArgumentException("Unsupported constant type: " + constantType); - } - } - - @Override - public JetType visitThrowExpression(JetThrowExpression expression, ExpressionTypingContext context) { - JetExpression thrownExpression = expression.getThrownExpression(); - if (thrownExpression != null) { - JetType type = getType(thrownExpression, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).replaceScope(context.scope)); - // TODO : check that it inherits Throwable - } - return context.getServices().checkType(JetStandardClasses.getNothingType(), expression, context); - } - - @Override - public JetType visitReturnExpression(JetReturnExpression expression, ExpressionTypingContext context) { - context.labelResolver.recordLabel(expression, context); - if (context.expectedReturnType == TypeUtils.FORBIDDEN) { -// context.trace.getErrorHandler().genericError(expression.getNode(), "'return' is not allowed here"); - context.trace.report(RETURN_NOT_ALLOWED.on(expression)); - return null; - } - JetExpression returnedExpression = expression.getReturnedExpression(); - - JetType returnedType = JetStandardClasses.getUnitType(); - if (returnedExpression != null) { - getType(returnedExpression, context.replaceExpectedType(context.expectedReturnType).replaceScope(context.scope)); - } - else { - if (context.expectedReturnType != TypeUtils.NO_EXPECTED_TYPE && !JetStandardClasses.isUnit(context.expectedReturnType)) { -// context.trace.getErrorHandler().genericError(expression.getNode(), "This function must return a value of type " + context.expectedReturnType); - context.trace.report(RETURN_TYPE_MISMATCH.on(expression, context.expectedReturnType)); - } - } - return context.getServices().checkType(JetStandardClasses.getNothingType(), expression, context); - } - - @Override - public JetType visitBreakExpression(JetBreakExpression expression, ExpressionTypingContext context) { - context.labelResolver.recordLabel(expression, context); - return context.getServices().checkType(JetStandardClasses.getNothingType(), expression, context); - } - - @Override - public JetType visitContinueExpression(JetContinueExpression expression, ExpressionTypingContext context) { - context.labelResolver.recordLabel(expression, context); - return context.getServices().checkType(JetStandardClasses.getNothingType(), expression, context); - } - - @Override - public JetType visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression, ExpressionTypingContext context) { - JetTypeReference right = expression.getRight(); - JetType result = null; - if (right != null) { - JetType targetType = context.getTypeResolver().resolveType(context.scope, right); - - if (isTypeFlexible(expression.getLeft())) { - TemporaryBindingTrace temporaryTraceWithExpectedType = TemporaryBindingTrace.create(context.trace); - boolean success = checkBinaryWithTypeRHS(expression, context, targetType, targetType, temporaryTraceWithExpectedType); - if (success) { - temporaryTraceWithExpectedType.commit(); - } - else { - TemporaryBindingTrace temporaryTraceWithoutExpectedType = TemporaryBindingTrace.create(context.trace); - checkBinaryWithTypeRHS(expression, context, targetType, TypeUtils.NO_EXPECTED_TYPE, temporaryTraceWithoutExpectedType); - temporaryTraceWithoutExpectedType.commit(); - } - } - else { - TemporaryBindingTrace temporaryTraceWithoutExpectedType = TemporaryBindingTrace.create(context.trace); - checkBinaryWithTypeRHS(expression, context, targetType, TypeUtils.NO_EXPECTED_TYPE, temporaryTraceWithoutExpectedType); - temporaryTraceWithoutExpectedType.commit(); - } - - IElementType operationType = expression.getOperationSign().getReferencedNameElementType(); - result = operationType == JetTokens.AS_SAFE ? TypeUtils.makeNullable(targetType) : targetType; - } - else { - getType(expression.getLeft(), context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE)); - } - return context.getServices().checkType(result, expression, context); - } - - private boolean isTypeFlexible(@Nullable JetExpression expression) { - if (expression == null) return false; - - return TokenSet.create( - JetNodeTypes.INTEGER_CONSTANT, - JetNodeTypes.FLOAT_CONSTANT - ).contains(expression.getNode().getElementType()); - } - - private boolean checkBinaryWithTypeRHS(JetBinaryExpressionWithTypeRHS expression, ExpressionTypingContext context, @NotNull JetType targetType, @NotNull JetType expectedType, TemporaryBindingTrace temporaryTrace) { - ExpressionTypingContext newContext = context.replaceExpectedTypeAndTrace(expectedType, temporaryTrace); - - JetType actualType = getType(expression.getLeft(), newContext); - if (actualType == null) return false; - - JetSimpleNameExpression operationSign = expression.getOperationSign(); - IElementType operationType = operationSign.getReferencedNameElementType(); - if (operationType == JetTokens.COLON) { - if (targetType != TypeUtils.NO_EXPECTED_TYPE && !context.semanticServices.getTypeChecker().isSubtypeOf(actualType, targetType)) { -// context.trace.getErrorHandler().typeMismatch(expression.getLeft(), targetType, actualType); - context.trace.report(TYPE_MISMATCH.on(expression.getLeft(), targetType, actualType)); - return false; - } - return true; - } - else if (operationType == JetTokens.AS_KEYWORD || operationType == JetTokens.AS_SAFE) { - checkForCastImpossibility(expression, actualType, targetType, context); - return true; - } - else { -// context.trace.getErrorHandler().genericError(operationSign.getNode(), "Unknown binary operation");\ - context.trace.report(UNSUPPORTED.on(operationSign, "binary operation with type RHS")); - return false; - } - } - - private void checkForCastImpossibility(JetBinaryExpressionWithTypeRHS expression, JetType actualType, JetType targetType, ExpressionTypingContext context) { - if (actualType == null || targetType == TypeUtils.NO_EXPECTED_TYPE) return; - - JetTypeChecker typeChecker = context.semanticServices.getTypeChecker(); - if (!typeChecker.isSubtypeOf(targetType, actualType)) { - if (typeChecker.isSubtypeOf(actualType, targetType)) { -// context.trace.getErrorHandler().genericWarning(expression.getOperationSign().getNode(), "No cast needed, use ':' instead"); - context.trace.report(USELESS_CAST_STATIC_ASSERT_IS_FINE.on(expression, expression.getOperationSign())); - } - else { - // See JET-58 Make 'as never succeeds' a warning, or even never check for Java (external) types -// context.trace.getErrorHandler().genericWarning(expression.getOperationSign().getNode(), "This cast can never succeed"); - context.trace.report(CAST_NEVER_SUCCEEDS.on(expression.getOperationSign())); - } - } - else { - if (typeChecker.isSubtypeOf(actualType, targetType)) { -// context.trace.getErrorHandler().genericWarning(expression.getOperationSign().getNode(), "No cast needed"); - context.trace.report(USELESS_CAST.on(expression, expression.getOperationSign())); - } - } - } - - @Override - public JetType visitTupleExpression(JetTupleExpression expression, ExpressionTypingContext context) { - List entries = expression.getEntries(); - List types = new ArrayList(); - for (JetExpression entry : entries) { - types.add(context.getServices().safeGetType(context.scope, entry, TypeUtils.NO_EXPECTED_TYPE)); // TODO - } - if (context.expectedType != TypeUtils.NO_EXPECTED_TYPE && JetStandardClasses.isTupleType(context.expectedType)) { - List enrichedTypes = context.getServices().checkArgumentTypes(types, entries, context.expectedType.getArguments(), context); - if (enrichedTypes != types) { - return JetStandardClasses.getTupleType(enrichedTypes); - } - } - // TODO : labels - return context.getServices().checkType(JetStandardClasses.getTupleType(types), expression, context); - } - - @Override - public JetType visitThisExpression(JetThisExpression expression, ExpressionTypingContext context) { - JetType result = null; - ReceiverDescriptor thisReceiver = null; - String labelName = expression.getLabelName(); - if (labelName != null) { - thisReceiver = context.labelResolver.resolveThisLabel(expression, context, thisReceiver, labelName); - } - else { - thisReceiver = context.scope.getImplicitReceiver(); - - DeclarationDescriptor declarationDescriptorForUnqualifiedThis = context.scope.getDeclarationDescriptorForUnqualifiedThis(); - if (declarationDescriptorForUnqualifiedThis != null) { - context.trace.record(REFERENCE_TARGET, expression.getThisReference(), declarationDescriptorForUnqualifiedThis); - } - } - - if (thisReceiver != null) { - if (!thisReceiver.exists()) { -// context.trace.getErrorHandler().genericError(expression.getNode(), "'this' is not defined in this context"); - context.trace.report(NO_THIS.on(expression)); - } - else { - JetTypeReference superTypeQualifier = expression.getSuperTypeQualifier(); - if (superTypeQualifier != null) { - JetTypeElement superTypeElement = superTypeQualifier.getTypeElement(); - // Errors are reported by the parser - if (superTypeElement instanceof JetUserType) { - JetUserType typeElement = (JetUserType) superTypeElement; - - ClassifierDescriptor classifierCandidate = context.getTypeResolver().resolveClass(context.scope, typeElement); - if (classifierCandidate instanceof ClassDescriptor) { - ClassDescriptor superclass = (ClassDescriptor) classifierCandidate; - - JetType thisType = thisReceiver.getType(); - Collection supertypes = thisType.getConstructor().getSupertypes(); - TypeSubstitutor substitutor = TypeSubstitutor.create(thisType); - for (JetType declaredSupertype : supertypes) { - if (declaredSupertype.getConstructor().equals(superclass.getTypeConstructor())) { - result = substitutor.safeSubstitute(declaredSupertype, Variance.INVARIANT); - break; - } - } - if (result == null) { -// context.trace.getErrorHandler().genericError(superTypeElement.getNode(), "Not a superclass"); - context.trace.report(NOT_A_SUPERTYPE.on(superTypeElement)); - } - } - } - } - else { - result = thisReceiver.getType(); - } - if (result != null) { - context.trace.record(BindingContext.EXPRESSION_TYPE, expression.getThisReference(), result); - } - } - } - return context.getServices().checkType(result, expression, context); - } - - @Override - public JetType visitBlockExpression(JetBlockExpression expression, ExpressionTypingContext context) { - return context.getServices().getBlockReturnedType(context.scope, expression, CoercionStrategy.NO_COERCION, context); - } - - @Override - public JetType visitWhenExpression(final JetWhenExpression expression, ExpressionTypingContext contextWithExpectedType) { - ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); - // TODO :change scope according to the bound value in the when header - final JetExpression subjectExpression = expression.getSubjectExpression(); - - final JetType subjectType = subjectExpression != null ? context.getServices().safeGetType(context.scope, subjectExpression, TypeUtils.NO_EXPECTED_TYPE) : ErrorUtils.createErrorType("Unknown type"); - final VariableDescriptor variableDescriptor = subjectExpression != null ? context.getServices().getVariableDescriptorFromSimpleName(subjectExpression, context) : null; - - // TODO : exhaustive patterns - - Set expressionTypes = Sets.newHashSet(); - for (JetWhenEntry whenEntry : expression.getEntries()) { - JetWhenCondition[] conditions = whenEntry.getConditions(); - DataFlowInfo newDataFlowInfo; - WritableScope scopeToExtend; - if (conditions.length == 1) { - scopeToExtend = newWritableScopeImpl(context.scope, context.trace).setDebugName("Scope extended in when entry"); - newDataFlowInfo = context.dataFlowInfo; - JetWhenCondition condition = conditions[0]; - if (condition != null) { - newDataFlowInfo = checkWhenCondition(subjectExpression, subjectType, condition, scopeToExtend, context, variableDescriptor); - } - } - else { - scopeToExtend = newWritableScopeImpl(context.scope, context.trace); // We don't write to this scope - newDataFlowInfo = null; - for (JetWhenCondition condition : conditions) { - DataFlowInfo dataFlowInfo = checkWhenCondition(subjectExpression, subjectType, condition, newWritableScopeImpl(context.scope, context.trace), context, variableDescriptor); - if (newDataFlowInfo == null) { - newDataFlowInfo = dataFlowInfo; - } - else { - newDataFlowInfo = newDataFlowInfo.or(dataFlowInfo); - } - } - if (newDataFlowInfo == null) { - newDataFlowInfo = context.dataFlowInfo; - } - else { - newDataFlowInfo = newDataFlowInfo.and(context.dataFlowInfo); - } - } - JetExpression bodyExpression = whenEntry.getExpression(); - if (bodyExpression != null) { - JetType type = getTypeWithNewScopeAndDataFlowInfo(scopeToExtend, bodyExpression, newDataFlowInfo, contextWithExpectedType); - if (type != null) { - expressionTypes.add(type); - } - } - } - - if (!expressionTypes.isEmpty()) { - return context.semanticServices.getTypeChecker().commonSupertype(expressionTypes); - } - else if (expression.getEntries().isEmpty()) { -// context.trace.getErrorHandler().genericError(expression.getNode(), "Entries required for when-expression"); - context.trace.report(NO_WHEN_ENTRIES.on(expression)); - } - return null; - } - - private DataFlowInfo checkWhenCondition(@Nullable final JetExpression subjectExpression, final JetType subjectType, JetWhenCondition condition, final WritableScope scopeToExtend, final ExpressionTypingContext context, final VariableDescriptor... subjectVariables) { - final DataFlowInfo[] newDataFlowInfo = new DataFlowInfo[]{context.dataFlowInfo}; - condition.accept(new JetVisitorVoid() { - - @Override - public void visitWhenConditionCall(JetWhenConditionCall condition) { - JetExpression callSuffixExpression = condition.getCallSuffixExpression(); -// JetScope compositeScope = new ScopeWithReceiver(context.scope, subjectType, semanticServices.getTypeChecker()); - if (callSuffixExpression != null) { -// JetType selectorReturnType = getType(compositeScope, callSuffixExpression, false, context); - assert subjectExpression != null; - JetType selectorReturnType = getSelectorReturnType(new ExpressionReceiver(subjectExpression, subjectType), condition.getOperationTokenNode(), callSuffixExpression, context);//getType(compositeScope, callSuffixExpression, false, context); - ensureBooleanResultWithCustomSubject(callSuffixExpression, selectorReturnType, "This expression", context); -// context.getServices().checkNullSafety(subjectType, condition.getOperationTokenNode(), getCalleeFunctionDescriptor(callSuffixExpression, context), condition); - } - } - - @Override - public void visitWhenConditionInRange(JetWhenConditionInRange condition) { - JetExpression rangeExpression = condition.getRangeExpression(); - if (rangeExpression != null) { - assert subjectExpression != null; - checkInExpression(condition, condition.getOperationReference(), subjectExpression, rangeExpression, context); - } - } - - @Override - public void visitWhenConditionIsPattern(JetWhenConditionIsPattern condition) { - JetPattern pattern = condition.getPattern(); - if (pattern != null) { - newDataFlowInfo[0] = checkPatternType(pattern, subjectType, scopeToExtend, context, subjectVariables); - } - } - - @Override - public void visitJetElement(JetElement element) { -// context.trace.getErrorHandler().genericError(element.getNode(), "Unsupported [OperatorConventions] : " + element); - context.trace.report(UNSUPPORTED.on(element, getClass().getCanonicalName())); - } - }); - return newDataFlowInfo[0]; - } - - private DataFlowInfo checkPatternType(@NotNull JetPattern pattern, @NotNull final JetType subjectType, @NotNull final WritableScope scopeToExtend, final ExpressionTypingContext context, @NotNull final VariableDescriptor... subjectVariables) { - final DataFlowInfo[] result = new DataFlowInfo[] {context.dataFlowInfo}; - pattern.accept(new JetVisitorVoid() { - @Override - public void visitTypePattern(JetTypePattern typePattern) { - JetTypeReference typeReference = typePattern.getTypeReference(); - if (typeReference != null) { - JetType type = context.getTypeResolver().resolveType(context.scope, typeReference); - checkTypeCompatibility(type, subjectType, typePattern); - result[0] = context.dataFlowInfo.isInstanceOf(subjectVariables, type); - } - } - - @Override - public void visitTuplePattern(JetTuplePattern pattern) { - List entries = pattern.getEntries(); - TypeConstructor typeConstructor = subjectType.getConstructor(); - if (!JetStandardClasses.getTuple(entries.size()).getTypeConstructor().equals(typeConstructor) - || typeConstructor.getParameters().size() != entries.size()) { -// context.trace.getErrorHandler().genericError(pattern.getNode(), "Type mismatch: subject is of type " + subjectType + " but the pattern is of type Tuple" + entries.size()); - context.trace.report(TYPE_MISMATCH_IN_TUPLE_PATTERN.on(pattern, subjectType, entries.size())); - } - else { - for (int i = 0, entriesSize = entries.size(); i < entriesSize; i++) { - JetTuplePatternEntry entry = entries.get(i); - JetType type = subjectType.getArguments().get(i).getType(); - - // TODO : is a name always allowed, ie for tuple patterns, not decomposer arg lists? - ASTNode nameLabelNode = entry.getNameLabelNode(); - if (nameLabelNode != null) { -// context.trace.getErrorHandler().genericError(nameLabelNode, "Unsupported [OperatorConventions]"); - context.trace.report(UNSUPPORTED.on(nameLabelNode, getClass().getCanonicalName())); - } - - JetPattern entryPattern = entry.getPattern(); - if (entryPattern != null) { - result[0] = result[0].and(checkPatternType(entryPattern, type, scopeToExtend, context)); - } - } - } - } - - @Override - public void visitDecomposerPattern(JetDecomposerPattern pattern) { - JetExpression decomposerExpression = pattern.getDecomposerExpression(); - if (decomposerExpression != null) { - ReceiverDescriptor receiver = new TransientReceiver(subjectType); - JetType selectorReturnType = getSelectorReturnType(receiver, null, decomposerExpression, context); - - result[0] = checkPatternType(pattern.getArgumentList(), selectorReturnType == null ? ErrorUtils.createErrorType("No type") : selectorReturnType, scopeToExtend, context); - } - } - - @Override - public void visitWildcardPattern(JetWildcardPattern pattern) { - // Nothing - } - - @Override - public void visitExpressionPattern(JetExpressionPattern pattern) { - JetExpression expression = pattern.getExpression(); - if (expression != null) { - JetType type = getType(expression, context.replaceScope(scopeToExtend)); - checkTypeCompatibility(type, subjectType, pattern); - } - } - - @Override - public void visitBindingPattern(JetBindingPattern pattern) { - JetProperty variableDeclaration = pattern.getVariableDeclaration(); - JetTypeReference propertyTypeRef = variableDeclaration.getPropertyTypeRef(); - JetType type = propertyTypeRef == null ? subjectType : context.getTypeResolver().resolveType(context.scope, propertyTypeRef); - VariableDescriptor variableDescriptor = context.getClassDescriptorResolver().resolveLocalVariableDescriptorWithType(context.scope.getContainingDeclaration(), variableDeclaration, type); - scopeToExtend.addVariableDescriptor(variableDescriptor); - if (propertyTypeRef != null) { - if (!context.semanticServices.getTypeChecker().isSubtypeOf(subjectType, type)) { -// context.trace.getErrorHandler().genericError(propertyTypeRef.getNode(), type + " must be a supertype of " + subjectType + ". Use 'is' to match against " + type); - context.trace.report(TYPE_MISMATCH_IN_BINDING_PATTERN.on(propertyTypeRef, type, subjectType)); - } - } - - JetWhenCondition condition = pattern.getCondition(); - if (condition != null) { - int oldLength = subjectVariables.length; - VariableDescriptor[] newSubjectVariables = new VariableDescriptor[oldLength + 1]; - System.arraycopy(subjectVariables, 0, newSubjectVariables, 0, oldLength); - newSubjectVariables[oldLength] = variableDescriptor; - result[0] = checkWhenCondition(null, subjectType, condition, scopeToExtend, context, newSubjectVariables); - } - } - - private void checkTypeCompatibility(@Nullable JetType type, @NotNull JetType subjectType, @NotNull JetElement reportErrorOn) { - // TODO : Take auto casts into account? - if (type == null) { - return; - } - if (TypeUtils.intersect(context.semanticServices.getTypeChecker(), Sets.newHashSet(type, subjectType)) == null) { -// context.trace.getErrorHandler().genericError(reportErrorOn.getNode(), "Incompatible types: " + type + " and " + subjectType); - context.trace.report(INCOMPATIBLE_TYPES.on(reportErrorOn, type, subjectType)); - } - } - - @Override - public void visitJetElement(JetElement element) { -// context.trace.getErrorHandler().genericError(element.getNode(), "Unsupported [OperatorConventions]"); - context.trace.report(UNSUPPORTED.on(element, getClass().getCanonicalName())); - } - }); - return result[0]; - } - - @Override - public JetType visitTryExpression(JetTryExpression expression, ExpressionTypingContext context) { - JetExpression tryBlock = expression.getTryBlock(); - List catchClauses = expression.getCatchClauses(); - JetFinallySection finallyBlock = expression.getFinallyBlock(); - List types = new ArrayList(); - for (JetCatchClause catchClause : catchClauses) { - JetParameter catchParameter = catchClause.getCatchParameter(); - JetExpression catchBody = catchClause.getCatchBody(); - if (catchParameter != null) { - VariableDescriptor variableDescriptor = context.getClassDescriptorResolver().resolveLocalVariableDescriptor(context.scope.getContainingDeclaration(), context.scope, catchParameter); - if (catchBody != null) { - WritableScope catchScope = newWritableScopeImpl(context.scope, context.trace).setDebugName("Catch scope"); - catchScope.addVariableDescriptor(variableDescriptor); - JetType type = getType(catchBody, context.replaceScope(catchScope)); - if (type != null) { - types.add(type); - } - } - } - } - if (finallyBlock != null) { - types.clear(); // Do not need the list for the check, but need the code above to typecheck catch bodies - JetType type = getType(finallyBlock.getFinalExpression(), context.replaceScope(context.scope)); - if (type != null) { - types.add(type); - } - } - JetType type = getType(tryBlock, context.replaceScope(context.scope)); - if (type != null) { - types.add(type); - } - if (types.isEmpty()) { - return null; - } - else { - return context.semanticServices.getTypeChecker().commonSupertype(types); - } - } - - @Override - public JetType visitIfExpression(JetIfExpression expression, ExpressionTypingContext contextWithExpectedType) { - ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); - JetExpression condition = expression.getCondition(); - checkCondition(context.scope, condition, context); - - JetExpression elseBranch = expression.getElse(); - JetExpression thenBranch = expression.getThen(); - - WritableScopeImpl thenScope = newWritableScopeImpl(context.scope, context.trace).setDebugName("Then scope"); - DataFlowInfo thenInfo = extractDataFlowInfoFromCondition(condition, true, thenScope, context); - DataFlowInfo elseInfo = extractDataFlowInfoFromCondition(condition, false, null, context); - - if (elseBranch == null) { - if (thenBranch != null) { - JetType type = getTypeWithNewScopeAndDataFlowInfo(thenScope, thenBranch, thenInfo, context); - if (type != null && JetStandardClasses.isNothing(type)) { - resultDataFlowInfo = elseInfo; -// resultScope = elseScope; - } - return context.getServices().checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType); - } - return null; - } - if (thenBranch == null) { - JetType type = getTypeWithNewScopeAndDataFlowInfo(context.scope, elseBranch, elseInfo, context); - if (type != null && JetStandardClasses.isNothing(type)) { - resultDataFlowInfo = thenInfo; -// resultScope = thenScope; - } - return context.getServices().checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType); - } - JetType thenType = getTypeWithNewScopeAndDataFlowInfo(thenScope, thenBranch, thenInfo, contextWithExpectedType); - JetType elseType = getTypeWithNewScopeAndDataFlowInfo(context.scope, elseBranch, elseInfo, contextWithExpectedType); - - JetType result; - if (thenType == null) { - result = elseType; - } - else if (elseType == null) { - result = thenType; - } - else { - result = context.semanticServices.getTypeChecker().commonSupertype(Arrays.asList(thenType, elseType)); - } - - boolean jumpInThen = thenType != null && JetStandardClasses.isNothing(thenType); - boolean jumpInElse = elseType != null && JetStandardClasses.isNothing(elseType); - - if (jumpInThen && !jumpInElse) { - resultDataFlowInfo = elseInfo; -// resultScope = elseScope; - } - else if (jumpInElse && !jumpInThen) { - resultDataFlowInfo = thenInfo; -// resultScope = thenScope; - } - return result; - } - - @NotNull - private DataFlowInfo extractDataFlowInfoFromCondition(@Nullable JetExpression condition, final boolean conditionValue, @Nullable final WritableScope scopeToExtend, final ExpressionTypingContext context) { - if (condition == null) return context.dataFlowInfo; - final DataFlowInfo[] result = new DataFlowInfo[] {context.dataFlowInfo}; - condition.accept(new JetVisitorVoid() { - @Override - public void visitIsExpression(JetIsExpression expression) { - if (conditionValue && !expression.isNegated() || !conditionValue && expression.isNegated()) { - JetPattern pattern = expression.getPattern(); - result[0] = context.patternsToDataFlowInfo.get(pattern); - if (scopeToExtend != null) { - List descriptors = context.patternsToBoundVariableLists.get(pattern); - if (descriptors != null) { - for (VariableDescriptor variableDescriptor : descriptors) { - scopeToExtend.addVariableDescriptor(variableDescriptor); - } - } - } - } - } - - @Override - public void visitBinaryExpression(JetBinaryExpression expression) { - IElementType operationToken = expression.getOperationToken(); - if (operationToken == JetTokens.ANDAND || operationToken == JetTokens.OROR) { - WritableScope actualScopeToExtend; - if (operationToken == JetTokens.ANDAND) { - actualScopeToExtend = conditionValue ? scopeToExtend : null; - } - else { - actualScopeToExtend = conditionValue ? null : scopeToExtend; - } - - DataFlowInfo dataFlowInfo = extractDataFlowInfoFromCondition(expression.getLeft(), conditionValue, actualScopeToExtend, context); - JetExpression expressionRight = expression.getRight(); - if (expressionRight != null) { - DataFlowInfo rightInfo = extractDataFlowInfoFromCondition(expressionRight, conditionValue, actualScopeToExtend, context); - DataFlowInfo.CompositionOperator operator; - if (operationToken == JetTokens.ANDAND) { - operator = conditionValue ? DataFlowInfo.AND : DataFlowInfo.OR; - } - else { - operator = conditionValue ? DataFlowInfo.OR : DataFlowInfo.AND; - } - dataFlowInfo = operator.compose(dataFlowInfo, rightInfo); - } - result[0] = dataFlowInfo; - } - else if (operationToken == JetTokens.EQEQ - || operationToken == JetTokens.EXCLEQ - || operationToken == JetTokens.EQEQEQ - || operationToken == JetTokens.EXCLEQEQEQ) { - JetExpression left = expression.getLeft(); - JetExpression right = expression.getRight(); - if (right == null) return; - - if (!(left instanceof JetSimpleNameExpression)) { - JetExpression tmp = left; - left = right; - right = tmp; - - if (!(left instanceof JetSimpleNameExpression)) { - return; - } - } - - VariableDescriptor variableDescriptor = context.getServices().getVariableDescriptorFromSimpleName(left, context); - if (variableDescriptor == null) return; - - // TODO : validate that DF makes sense for this variable: local, val, internal w/backing field, etc - - // Comparison to a non-null expression - JetType rhsType = context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, right); - if (rhsType != null && !rhsType.isNullable()) { - extendDataFlowWithNullComparison(operationToken, variableDescriptor, !conditionValue); - return; - } - - VariableDescriptor rightVariable = context.getServices().getVariableDescriptorFromSimpleName(right, context); - if (rightVariable != null) { - JetType lhsType = context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, left); - if (lhsType != null && !lhsType.isNullable()) { - extendDataFlowWithNullComparison(operationToken, rightVariable, !conditionValue); - return; - } - } - - // Comparison to 'null' - if (!(right instanceof JetConstantExpression)) { - return; - } - JetConstantExpression constantExpression = (JetConstantExpression) right; - if (constantExpression.getNode().getElementType() != JetNodeTypes.NULL) { - return; - } - - extendDataFlowWithNullComparison(operationToken, variableDescriptor, conditionValue); - } - } - - private void extendDataFlowWithNullComparison(IElementType operationToken, @NotNull VariableDescriptor variableDescriptor, boolean equalsToNull) { - if (operationToken == JetTokens.EQEQ || operationToken == JetTokens.EQEQEQ) { - result[0] = context.dataFlowInfo.equalsToNull(variableDescriptor, !equalsToNull); - } - else if (operationToken == JetTokens.EXCLEQ || operationToken == JetTokens.EXCLEQEQEQ) { - result[0] = context.dataFlowInfo.equalsToNull(variableDescriptor, equalsToNull); - } - } - - @Override - public void visitUnaryExpression(JetUnaryExpression expression) { - IElementType operationTokenType = expression.getOperationSign().getReferencedNameElementType(); - if (operationTokenType == JetTokens.EXCL) { - JetExpression baseExpression = expression.getBaseExpression(); - if (baseExpression != null) { - result[0] = extractDataFlowInfoFromCondition(baseExpression, !conditionValue, scopeToExtend, context); - } - } - } - - @Override - public void visitParenthesizedExpression(JetParenthesizedExpression expression) { - JetExpression body = expression.getExpression(); - if (body != null) { - body.accept(this); - } - } - }); - if (result[0] == null) { - return context.dataFlowInfo; - } - return result[0]; - } - - private void checkCondition(@NotNull JetScope scope, @Nullable JetExpression condition, ExpressionTypingContext context) { - if (condition != null) { - JetType conditionType = getType(condition, context.replaceScope(scope)); - - if (conditionType != null && !isBoolean(context.semanticServices, conditionType)) { -// context.trace.getErrorHandler().genericError(condition.getNode(), "Condition must be of type Boolean, but was of type " + conditionType); - context.trace.report(TYPE_MISMATCH_IN_CONDITION.on(condition, conditionType)); - } - } - } - - @Override - public JetType visitWhileExpression(JetWhileExpression expression, ExpressionTypingContext contextWithExpectedType) { - ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); - JetExpression condition = expression.getCondition(); - checkCondition(context.scope, condition, context); - JetExpression body = expression.getBody(); - if (body != null) { - WritableScopeImpl scopeToExtend = newWritableScopeImpl(context.scope, context.trace).setDebugName("Scope extended in while's condition"); - DataFlowInfo conditionInfo = condition == null ? context.dataFlowInfo : extractDataFlowInfoFromCondition(condition, true, scopeToExtend, context); - getTypeWithNewScopeAndDataFlowInfo(scopeToExtend, body, conditionInfo, context); - } - if (!containsBreak(expression, context)) { -// resultScope = newWritableScopeImpl(); - resultDataFlowInfo = extractDataFlowInfoFromCondition(condition, false, null, context); - } - return context.getServices().checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType); - } - - private boolean containsBreak(final JetLoopExpression loopExpression, final ExpressionTypingContext context) { - final boolean[] result = new boolean[1]; - result[0] = false; - //todo breaks in inline function literals - loopExpression.visit(new JetTreeVisitor() { - @Override - public Void visitBreakExpression(JetBreakExpression breakExpression, JetLoopExpression outerLoop) { - JetSimpleNameExpression targetLabel = breakExpression.getTargetLabel(); - PsiElement element = targetLabel != null ? context.trace.get(LABEL_TARGET, targetLabel) : null; - if (element == loopExpression || (targetLabel == null && outerLoop == loopExpression)) { - result[0] = true; - } - return null; - } - - @Override - public Void visitLoopExpression(JetLoopExpression loopExpression, JetLoopExpression outerLoop) { - return super.visitLoopExpression(loopExpression, loopExpression); - } - }, loopExpression); - - return result[0]; - } - - @Override - public JetType visitDoWhileExpression(JetDoWhileExpression expression, ExpressionTypingContext contextWithExpectedType) { - ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); - JetExpression body = expression.getBody(); - JetScope conditionScope = context.scope; - if (body instanceof JetFunctionLiteralExpression) { - JetFunctionLiteralExpression function = (JetFunctionLiteralExpression) body; - if (!function.getFunctionLiteral().hasParameterSpecification()) { - WritableScope writableScope = newWritableScopeImpl(context.scope, context.trace).setDebugName("do..while body scope"); - conditionScope = writableScope; - context.getServices().getBlockReturnedTypeWithWritableScope(writableScope, function.getFunctionLiteral().getBodyExpression().getStatements(), CoercionStrategy.NO_COERCION, context); - context.trace.record(BindingContext.BLOCK, function); - } else { - getType(body, context.replaceScope(context.scope)); - } - } - else if (body != null) { - WritableScope writableScope = newWritableScopeImpl(context.scope, context.trace).setDebugName("do..while body scope"); - conditionScope = writableScope; - context.getServices().getBlockReturnedTypeWithWritableScope(writableScope, Collections.singletonList(body), CoercionStrategy.NO_COERCION, context); - } - JetExpression condition = expression.getCondition(); - checkCondition(conditionScope, condition, context); - if (!containsBreak(expression, context)) { -// resultScope = newWritableScopeImpl(); - resultDataFlowInfo = extractDataFlowInfoFromCondition(condition, false, null, context); - } - return context.getServices().checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType); - } - - protected WritableScopeImpl newWritableScopeImpl(JetScope scope, BindingTrace trace) { - return new WritableScopeImpl(scope, scope.getContainingDeclaration(), new TraceBasedRedeclarationHandler(trace)); - } - - @Override - public JetType visitForExpression(JetForExpression expression, ExpressionTypingContext contextWithExpectedType) { - ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); - JetParameter loopParameter = expression.getLoopParameter(); - JetExpression loopRange = expression.getLoopRange(); - JetType expectedParameterType = null; - if (loopRange != null) { - ExpressionReceiver loopRangeReceiver = getExpressionReceiver(loopRange, context.replaceScope(context.scope)); - if (loopRangeReceiver != null) { - expectedParameterType = checkIterableConvention(loopRangeReceiver, context); - } - } - - WritableScope loopScope = newWritableScopeImpl(context.scope, context.trace).setDebugName("Scope with for-loop index"); - - if (loopParameter != null) { - JetTypeReference typeReference = loopParameter.getTypeReference(); - VariableDescriptor variableDescriptor; - if (typeReference != null) { - variableDescriptor = context.getClassDescriptorResolver().resolveLocalVariableDescriptor(context.scope.getContainingDeclaration(), context.scope, loopParameter); - JetType actualParameterType = variableDescriptor.getOutType(); - if (expectedParameterType != null && - actualParameterType != null && - !context.semanticServices.getTypeChecker().isSubtypeOf(expectedParameterType, actualParameterType)) { -// context.trace.getErrorHandler().genericError(typeReference.getNode(), "The loop iterates over values of type " + expectedParameterType + " but the parameter is declared to be " + actualParameterType); - context.trace.report(TYPE_MISMATCH_IN_FOR_LOOP.on(typeReference, expectedParameterType, actualParameterType)); - } - } - else { - if (expectedParameterType == null) { - expectedParameterType = ErrorUtils.createErrorType("Error"); - } - variableDescriptor = context.getClassDescriptorResolver().resolveLocalVariableDescriptor(context.scope.getContainingDeclaration(), loopParameter, expectedParameterType); - } - loopScope.addVariableDescriptor(variableDescriptor); - } - - JetExpression body = expression.getBody(); - if (body != null) { - getType(body, context.replaceScope(loopScope)); - } - - return context.getServices().checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType); - } - - @Nullable - private JetType checkIterableConvention(@NotNull ExpressionReceiver loopRange, ExpressionTypingContext context) { - JetExpression loopRangeExpression = loopRange.getExpression(); - OverloadResolutionResults iteratorResolutionResults = context.resolveExactSignature(loopRange, "iterator", Collections.emptyList()); - if (iteratorResolutionResults.isSuccess()) { - FunctionDescriptor iteratorFunction = iteratorResolutionResults.getResult().getResultingDescriptor(); - - context.trace.record(LOOP_RANGE_ITERATOR, loopRangeExpression, iteratorFunction); - - JetType iteratorType = iteratorFunction.getReturnType(); - FunctionDescriptor hasNextFunction = checkHasNextFunctionSupport(loopRangeExpression, iteratorType, context); - boolean hasNextFunctionSupported = hasNextFunction != null; - VariableDescriptor hasNextProperty = checkHasNextPropertySupport(loopRangeExpression, iteratorType, context); - boolean hasNextPropertySupported = hasNextProperty != null; - if (hasNextFunctionSupported && hasNextPropertySupported && !ErrorUtils.isErrorType(iteratorType)) { - // TODO : overload resolution rules impose priorities here??? -// context.trace.getErrorHandler().genericError(reportErrorsOn, "An ambiguity between 'iterator().hasNext()' function and 'iterator().hasNext' property"); - context.trace.report(HAS_NEXT_PROPERTY_AND_FUNCTION_AMBIGUITY.on(loopRangeExpression)); - } - else if (!hasNextFunctionSupported && !hasNextPropertySupported) { -// context.trace.getErrorHandler().genericError(reportErrorsOn, "Loop range must have an 'iterator().hasNext()' function or an 'iterator().hasNext' property"); - context.trace.report(HAS_NEXT_MISSING.on(loopRangeExpression)); - } - else { - context.trace.record(LOOP_RANGE_HAS_NEXT, loopRange.getExpression(), hasNextFunctionSupported ? hasNextFunction : hasNextProperty); - } - - OverloadResolutionResults nextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "next", Collections.emptyList()); - if (nextResolutionResults.isAmbiguity()) { -// context.trace.getErrorHandler().genericError(reportErrorsOn, "Method 'iterator().next()' is ambiguous for this expression"); - context.trace.report(NEXT_AMBIGUITY.on(loopRangeExpression)); - } else if (nextResolutionResults.isNothing()) { -// context.trace.getErrorHandler().genericError(reportErrorsOn, "Loop range must have an 'iterator().next()' method"); - context.trace.report(NEXT_MISSING.on(loopRangeExpression)); - } else { - FunctionDescriptor nextFunction = nextResolutionResults.getResult().getResultingDescriptor(); - context.trace.record(LOOP_RANGE_NEXT, loopRange.getExpression(), nextFunction); - return nextFunction.getReturnType(); - } - } - else { - if (iteratorResolutionResults.isAmbiguity()) { -// StringBuffer stringBuffer = new StringBuffer("Method 'iterator()' is ambiguous for this expression: "); -// for (FunctionDescriptor functionDescriptor : iteratorResolutionResults.getResults()) { -// stringBuffer.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append(" "); -// } -// errorMessage = stringBuffer.toString(); - context.trace.report(ITERATOR_AMBIGUITY.on(loopRangeExpression, iteratorResolutionResults.getResults())); - } - else { -// context.trace.getErrorHandler().genericError(reportErrorsOn, errorMessage); - context.trace.report(ITERATOR_MISSING.on(loopRangeExpression)); - } - } - return null; - } - - @Nullable - private FunctionDescriptor checkHasNextFunctionSupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, ExpressionTypingContext context) { - OverloadResolutionResults hasNextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "hasNext", Collections.emptyList()); - if (hasNextResolutionResults.isAmbiguity()) { -// context.trace.getErrorHandler().genericError(loopRange.getNode(), "Method 'iterator().hasNext()' is ambiguous for this expression"); - context.trace.report(HAS_NEXT_FUNCTION_AMBIGUITY.on(loopRange)); - } else if (hasNextResolutionResults.isNothing()) { - return null; - } else { - assert hasNextResolutionResults.isSuccess(); - JetType hasNextReturnType = hasNextResolutionResults.getResult().getResultingDescriptor().getReturnType(); - if (!isBoolean(context.semanticServices, hasNextReturnType)) { -// context.trace.getErrorHandler().genericError(loopRange.getNode(), "The 'iterator().hasNext()' method of the loop range must return Boolean, but returns " + hasNextReturnType); - context.trace.report(HAS_NEXT_FUNCTION_TYPE_MISMATCH.on(loopRange, hasNextReturnType)); - } - } - return hasNextResolutionResults.getResult().getResultingDescriptor(); - } - - @Nullable - private VariableDescriptor checkHasNextPropertySupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, ExpressionTypingContext context) { - VariableDescriptor hasNextProperty = iteratorType.getMemberScope().getVariable("hasNext"); - // TODO :extension properties - if (hasNextProperty == null) { - return null; - } else { - JetType hasNextReturnType = hasNextProperty.getOutType(); - if (hasNextReturnType == null) { - // TODO : accessibility -// context.trace.getErrorHandler().genericError(loopRange.getNode(), "The 'iterator().hasNext' property of the loop range must be readable"); - context.trace.report(HAS_NEXT_MUST_BE_READABLE.on(loopRange)); - } - else if (!isBoolean(context.semanticServices, hasNextReturnType)) { -// context.trace.getErrorHandler().genericError(loopRange.getNode(), "The 'iterator().hasNext' property of the loop range must return Boolean, but returns " + hasNextReturnType); - context.trace.report(HAS_NEXT_PROPERTY_TYPE_MISMATCH.on(loopRange, hasNextReturnType)); - } - } - return hasNextProperty; - } - - @Override - public JetType visitHashQualifiedExpression(JetHashQualifiedExpression expression, ExpressionTypingContext context) { -// context.trace.getErrorHandler().genericError(expression.getOperationTokenNode(), "Unsupported"); - context.trace.report(UNSUPPORTED.on(expression, getClass().getCanonicalName())); - return null; - } - - @Override - public JetType visitQualifiedExpression(JetQualifiedExpression expression, ExpressionTypingContext contextWithExpectedType) { - ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); - // TODO : functions as values - JetExpression selectorExpression = expression.getSelectorExpression(); - JetExpression receiverExpression = expression.getReceiverExpression(); - JetType receiverType = ExpressionTyperVisitorWithNamespaces.INSTANCE.getType(receiverExpression, context.replaceExpectedTypes(TypeUtils.NO_EXPECTED_TYPE, TypeUtils.NO_EXPECTED_TYPE)); - if (selectorExpression == null) return null; - if (receiverType == null) receiverType = ErrorUtils.createErrorType("Type for " + expression.getText()); - - if (selectorExpression instanceof JetSimpleNameExpression) { - propagateConstantValues(expression, context, (JetSimpleNameExpression) selectorExpression); - } - - // Clean resolution: no autocasts -// TemporaryBindingTrace cleanResolutionTrace = TemporaryBindingTrace.create(context.trace); -// ExpressionTypingContext cleanResolutionContext = context.replaceBindingTrace(cleanResolutionTrace); - JetType selectorReturnType = getSelectorReturnType(new ExpressionReceiver(receiverExpression, receiverType), expression.getOperationTokenNode(), selectorExpression, context); - - //TODO move further - if (expression.getOperationSign() == JetTokens.SAFE_ACCESS) { - if (selectorReturnType != null && !selectorReturnType.isNullable() && !JetStandardClasses.isUnit(selectorReturnType)) { - selectorReturnType = TypeUtils.makeNullable(selectorReturnType); - } - } -// if (selectorReturnType != null) { -// cleanResolutionTrace.addAllMyDataTo(context.trace); -// } -// else { -// VariableDescriptor variableDescriptor = cleanResolutionContext.services.getVariableDescriptorFromSimpleName(receiverExpression, context); -// boolean somethingFound = false; -// if (variableDescriptor != null) { -// List possibleTypes = Lists.newArrayList(context.dataFlowInfo.getPossibleTypesForVariable(variableDescriptor)); -// Collections.reverse(possibleTypes); -// -// TemporaryBindingTrace autocastResolutionTrace = TemporaryBindingTrace.create(context.trace); -// ExpressionTypingContext autocastResolutionContext = context.replaceBindingTrace(autocastResolutionTrace); -// for (JetType possibleType : possibleTypes) { -// selectorReturnType = getSelectorReturnType(new ExpressionReceiver(receiverExpression, possibleType), selectorExpression, autocastResolutionContext); -// if (selectorReturnType != null) { -// context.getServices().checkAutoCast(receiverExpression, possibleType, variableDescriptor, autocastResolutionTrace); -// autocastResolutionTrace.commit(); -// somethingFound = true; -// break; -// } -// else { -// autocastResolutionTrace = TemporaryBindingTrace.create(context.trace); -// autocastResolutionContext = context.replaceBindingTrace(autocastResolutionTrace); -// } -// } -// } -// if (!somethingFound) { -// cleanResolutionTrace.commit(); -// } -// } - - JetType result; - if (expression.getOperationSign() == JetTokens.QUEST) { - if (selectorReturnType != null && !isBoolean(context.semanticServices, selectorReturnType)) { - // TODO : more comprehensible error message -// context.trace.getErrorHandler().typeMismatch(selectorExpression, semanticServices.getStandardLibrary().getBooleanType(), selectorReturnType); - context.trace.report(TYPE_MISMATCH.on(selectorExpression, context.semanticServices.getStandardLibrary().getBooleanType(), selectorReturnType)); - } - result = TypeUtils.makeNullable(receiverType); - } - else { - result = selectorReturnType; - } - // TODO : this is suspicious: remove this code? - if (result != null) { - context.trace.record(BindingContext.EXPRESSION_TYPE, selectorExpression, result); - } - if (selectorReturnType != null) { -// // TODO : extensions to 'Any?' -// receiverType = context.getServices().enrichOutType(receiverExpression, receiverType, context); -// -// context.getServices().checkNullSafety(receiverType, expression.getOperationTokenNode(), getCalleeFunctionDescriptor(selectorExpression, context), expression); - } - return context.getServices().checkType(result, expression, contextWithExpectedType); - } - - private void propagateConstantValues(JetQualifiedExpression expression, ExpressionTypingContext context, JetSimpleNameExpression selectorExpression) { - JetExpression receiverExpression = expression.getReceiverExpression(); - CompileTimeConstant receiverValue = context.trace.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, receiverExpression); - CompileTimeConstant wholeExpressionValue = context.trace.getBindingContext().get(BindingContext.COMPILE_TIME_VALUE, expression); - if (wholeExpressionValue == null && receiverValue != null && !(receiverValue instanceof ErrorValue) && receiverValue.getValue() instanceof Number) { - Number value = (Number) receiverValue.getValue(); - String referencedName = selectorExpression.getReferencedName(); - if (OperatorConventions.NUMBER_CONVERSIONS.contains(referencedName)) { - if ("dbl".equals(referencedName)) { - context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new DoubleValue(value.doubleValue())); - } - else if ("flt".equals(referencedName)) { - context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new FloatValue(value.floatValue())); - } - else if ("lng".equals(referencedName)) { - context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new LongValue(value.longValue())); - } - else if ("sht".equals(referencedName)) { - context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new ShortValue(value.shortValue())); - } - else if ("byt".equals(referencedName)) { - context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new ByteValue(value.byteValue())); - } - else if ("int".equals(referencedName)) { - context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new IntValue(value.intValue())); - } - } - } - } - -// @NotNull -// private FunctionDescriptor getCalleeFunctionDescriptor(@NotNull JetExpression selectorExpression, final ExpressionTypingContext context) { -// final FunctionDescriptor[] result = new FunctionDescriptor[1]; -// selectorExpression.accept(new JetVisitorVoid() { -// @Override -// public void visitCallExpression(JetCallExpression callExpression) { -// JetExpression calleeExpression = callExpression.getCalleeExpression(); -// if (calleeExpression != null) { -// calleeExpression.accept(this); -// } -// } -// -// @Override -// public void visitReferenceExpression(JetReferenceExpression referenceExpression) { -// DeclarationDescriptor declarationDescriptor = context.trace.getBindingContext().get(REFERENCE_TARGET, referenceExpression); -// if (declarationDescriptor instanceof FunctionDescriptor) { -// result[0] = (FunctionDescriptor) declarationDescriptor; -// } -// } -// -// @Override -// public void visitArrayAccessExpression(JetArrayAccessExpression expression) { -// expression.getArrayExpression().accept(this); -// } -// -// @Override -// public void visitBinaryExpression(JetBinaryExpression expression) { -// expression.getLeft().accept(this); -// } -// -// @Override -// public void visitQualifiedExpression(JetQualifiedExpression expression) { -// expression.getReceiverExpression().accept(this); -// } -// -// @Override -// public void visitJetElement(JetElement element) { -//// context.trace.getErrorHandler().genericError(element.getNode(), "Unsupported [getCalleeFunctionDescriptor]: " + element); -// context.trace.report(UNSUPPORTED.on(element, "getCalleeFunctionDescriptor")); -// } -// }); -// if (result[0] == null) { -// result[0] = ErrorUtils.createErrorFunction(0, Collections.emptyList()); -// } -// return result[0]; -// } - - @Nullable - private JetType getSelectorReturnType(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetExpression selectorExpression, @NotNull ExpressionTypingContext context) { - if (selectorExpression instanceof JetCallExpression) { - JetCallExpression callExpression = (JetCallExpression) selectorExpression; - return context.resolveCall(receiver, callOperationNode, callExpression); - } - else if (selectorExpression instanceof JetSimpleNameExpression) { - JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) selectorExpression; - - TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(context.trace); - VariableDescriptor variableDescriptor = context.replaceBindingTrace(temporaryTrace).resolveSimpleProperty(receiver, callOperationNode, nameExpression); - if (variableDescriptor != null) { - temporaryTrace.commit(); - return context.getServices().checkType(variableDescriptor.getOutType(), nameExpression, context); - } - ExpressionTypingContext newContext = receiver.exists() ? context.replaceScope(receiver.getType().getMemberScope()) : context; - JetType jetType = lookupNamespaceOrClassObject(nameExpression, nameExpression.getReferencedName(), newContext); - if (jetType == null) { - context.trace.report(UNRESOLVED_REFERENCE.on(nameExpression)); - } - return context.getServices().checkType(jetType, nameExpression, context); -// JetScope scope = receiverType != null ? receiverType.getMemberScope() : context.scope; -// return getType(selectorExpression, context.replaceScope(scope)); - } - else if (selectorExpression instanceof JetQualifiedExpression) { - JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) selectorExpression; - JetExpression newReceiverExpression = qualifiedExpression.getReceiverExpression(); - JetType newReceiverType = getSelectorReturnType(receiver, callOperationNode, newReceiverExpression, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE)); - JetExpression newSelectorExpression = qualifiedExpression.getSelectorExpression(); - if (newReceiverType != null && newSelectorExpression != null) { - return getSelectorReturnType(new ExpressionReceiver(newReceiverExpression, newReceiverType), qualifiedExpression.getOperationTokenNode(), newSelectorExpression, context); - } - } - else { - // TODO : not a simple name -> resolve in scope, expect property type or a function type -// context.trace.getErrorHandler().genericError(selectorExpression.getNode(), "Unsupported selector element type: " + selectorExpression); - context.trace.report(UNSUPPORTED.on(selectorExpression, "getSelectorReturnType")); - } - return null; - } - - @Override - public JetType visitCallExpression(JetCallExpression expression, ExpressionTypingContext context) { - JetType expressionType = context.resolveCall(NO_RECEIVER, null, expression); - return context.getServices().checkType(expressionType, expression, context); - } - - @Override - public JetType visitIsExpression(JetIsExpression expression, ExpressionTypingContext contextWithExpectedType) { - ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); - JetType knownType = safeGetType(expression.getLeftHandSide(), context.replaceScope(context.scope)); - JetPattern pattern = expression.getPattern(); - if (pattern != null) { - WritableScopeImpl scopeToExtend = newWritableScopeImpl(context.scope, context.trace).setDebugName("Scope extended in 'is'"); - DataFlowInfo newDataFlowInfo = checkPatternType(pattern, knownType, scopeToExtend, context, context.getServices().getVariableDescriptorFromSimpleName(expression.getLeftHandSide(), context)); - context.patternsToDataFlowInfo.put(pattern, newDataFlowInfo); - context.patternsToBoundVariableLists.put(pattern, scopeToExtend.getDeclaredVariables()); - } - return context.getServices().checkType(context.semanticServices.getStandardLibrary().getBooleanType(), expression, contextWithExpectedType); - } - - @Override - public JetType visitUnaryExpression(JetUnaryExpression expression, ExpressionTypingContext context) { - JetExpression baseExpression = expression.getBaseExpression(); - if (baseExpression == null) return null; - JetSimpleNameExpression operationSign = expression.getOperationSign(); - if (JetTokens.LABELS.contains(operationSign.getReferencedNameElementType())) { - String referencedName = operationSign.getReferencedName(); - referencedName = referencedName == null ? " " : referencedName; - context.labelResolver.enterLabeledElement(referencedName.substring(1), baseExpression); - // TODO : Some processing for the label? - JetType type = context.getServices().checkType(getType(baseExpression, context.replaceExpectedReturnType(context.expectedType)), expression, context); - context.labelResolver.exitLabeledElement(baseExpression); - return type; - } - IElementType operationType = operationSign.getReferencedNameElementType(); - String name = OperatorConventions.UNARY_OPERATION_NAMES.get(operationType); - if (name == null) { -// context.trace.getErrorHandler().genericError(operationSign.getNode(), "Unknown unary operation"); - context.trace.report(UNSUPPORTED.on(operationSign, "visitUnaryExpression")); - return null; - } - ExpressionReceiver receiver = getExpressionReceiver(baseExpression, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).replaceScope(context.scope)); - if (receiver == null) return null; - - FunctionDescriptor functionDescriptor = context.resolveCallWithGivenName( - CallMaker.makeCall(receiver, expression), - expression.getOperationSign(), - name, - receiver); - - if (functionDescriptor == null) return null; - JetType returnType = functionDescriptor.getReturnType(); - JetType result; - if (operationType == JetTokens.PLUSPLUS || operationType == JetTokens.MINUSMINUS) { - if (context.semanticServices.getTypeChecker().isSubtypeOf(returnType, JetStandardClasses.getUnitType())) { - result = JetStandardClasses.getUnitType(); - } - else { - JetType receiverType = receiver.getType(); - if (!context.semanticServices.getTypeChecker().isSubtypeOf(returnType, receiverType)) { -// context.trace.getErrorHandler().genericError(operationSign.getNode(), name + " must return " + receiverType + " but returns " + returnType); - context.trace.report(RESULT_TYPE_MISMATCH.on(operationSign, name, receiverType, returnType)); - } - else { - context.trace.record(BindingContext.VARIABLE_REASSIGNMENT, expression); - } - // TODO : Maybe returnType? - result = receiverType; - } - } - else { - result = returnType; - } - - return context.getServices().checkType(result, expression, context); - } - - @Override - public JetType visitBinaryExpression(JetBinaryExpression expression, ExpressionTypingContext contextWithExpectedType) { - ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); - JetSimpleNameExpression operationSign = expression.getOperationReference(); - - JetExpression left = expression.getLeft(); - JetExpression right = expression.getRight(); - - JetType result = null; - IElementType operationType = operationSign.getReferencedNameElementType(); - if (operationType == JetTokens.IDENTIFIER) { - String referencedName = operationSign.getReferencedName(); - if (referencedName != null) { - result = getTypeForBinaryCall(context.scope, referencedName, context, expression); - } - } - else if (OperatorConventions.BINARY_OPERATION_NAMES.containsKey(operationType)) { - result = getTypeForBinaryCall(context.scope, OperatorConventions.BINARY_OPERATION_NAMES.get(operationType), context, expression); - } - else if (operationType == JetTokens.EQ) { - result = visitAssignment(expression, contextWithExpectedType); - } - else if (OperatorConventions.ASSIGNMENT_OPERATIONS.containsKey(operationType)) { - result = visitAssignmentOperation(expression, contextWithExpectedType); - } - else if (OperatorConventions.COMPARISON_OPERATIONS.contains(operationType)) { - JetType compareToReturnType = getTypeForBinaryCall(context.scope, "compareTo", context, expression); - if (compareToReturnType != null) { - TypeConstructor constructor = compareToReturnType.getConstructor(); - JetStandardLibrary standardLibrary = context.semanticServices.getStandardLibrary(); - TypeConstructor intTypeConstructor = standardLibrary.getInt().getTypeConstructor(); - if (constructor.equals(intTypeConstructor)) { - result = standardLibrary.getBooleanType(); - } else { -// context.trace.getErrorHandler().genericError(operationSign.getNode(), "compareTo() must return Int, but returns " + compareToReturnType); - context.trace.report(COMPARE_TO_TYPE_MISMATCH.on(operationSign, compareToReturnType)); - } - } - } - else if (OperatorConventions.EQUALS_OPERATIONS.contains(operationType)) { - String name = "equals"; - if (right != null) { - ExpressionReceiver receiver = safeGetExpressionReceiver(left, context.replaceScope(context.scope)); - OverloadResolutionResults resolutionResults = context.resolveExactSignature( - receiver, "equals", - Collections.singletonList(JetStandardClasses.getNullableAnyType())); - if (resolutionResults.isSuccess()) { - FunctionDescriptor equals = resolutionResults.getResult().getResultingDescriptor(); - context.trace.record(REFERENCE_TARGET, operationSign, equals); - if (ensureBooleanResult(operationSign, name, equals.getReturnType(), context)) { - ensureNonemptyIntersectionOfOperandTypes(expression, context); - } - } - else { - if (resolutionResults.isAmbiguity()) { -// StringBuilder stringBuilder = new StringBuilder(); -// for (FunctionDescriptor functionDescriptor : resolutionResults.getResults()) { -// stringBuilder.append(DescriptorRenderer.TEXT.render(functionDescriptor)).append(" "); -// } -// context.trace.getErrorHandler().genericError(operationSign.getNode(), "Ambiguous function: " + stringBuilder); - context.trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(operationSign, resolutionResults.getResults())); - } - else { -// context.trace.getErrorHandler().genericError(operationSign.getNode(), "No method 'equals(Any?) : Boolean' available"); - context.trace.report(EQUALS_MISSING.on(operationSign)); - } - } - } - result = context.semanticServices.getStandardLibrary().getBooleanType(); - } - else if (operationType == JetTokens.EQEQEQ || operationType == JetTokens.EXCLEQEQEQ) { - ensureNonemptyIntersectionOfOperandTypes(expression, context); - - // TODO : Check comparison pointlessness - result = context.semanticServices.getStandardLibrary().getBooleanType(); - } - else if (OperatorConventions.IN_OPERATIONS.contains(operationType)) { - if (right == null) { - result = ErrorUtils.createErrorType("No right argument"); // TODO - return null; - } - checkInExpression(expression, expression.getOperationReference(), expression.getLeft(), expression.getRight(), context); - result = context.semanticServices.getStandardLibrary().getBooleanType(); - } - else if (operationType == JetTokens.ANDAND || operationType == JetTokens.OROR) { - JetType leftType = getType(left, context.replaceScope(context.scope)); - WritableScopeImpl leftScope = newWritableScopeImpl(context.scope, context.trace).setDebugName("Left scope of && or ||"); - DataFlowInfo flowInfoLeft = extractDataFlowInfoFromCondition(left, operationType == JetTokens.ANDAND, leftScope, context); // TODO: This gets computed twice: here and in extractDataFlowInfoFromCondition() for the whole condition - WritableScopeImpl rightScope = operationType == JetTokens.ANDAND ? leftScope : newWritableScopeImpl(context.scope, context.trace).setDebugName("Right scope of && or ||"); - JetType rightType = right == null ? null : getType(right, context.replaceDataFlowInfo(flowInfoLeft).replaceScope(rightScope)); - if (leftType != null && !isBoolean(context.semanticServices, leftType)) { -// context.trace.getErrorHandler().typeMismatch(left, semanticServices.getStandardLibrary().getBooleanType(), leftType); - context.trace.report(TYPE_MISMATCH.on(left, context.semanticServices.getStandardLibrary().getBooleanType(), leftType)); - } - if (rightType != null && !isBoolean(context.semanticServices, rightType)) { -// context.trace.getErrorHandler().typeMismatch(right, semanticServices.getStandardLibrary().getBooleanType(), rightType); - context.trace.report(TYPE_MISMATCH.on(right, context.semanticServices.getStandardLibrary().getBooleanType(), rightType)); - } - result = context.semanticServices.getStandardLibrary().getBooleanType(); - } - else if (operationType == JetTokens.ELVIS) { - JetType leftType = getType(left, context.replaceScope(context.scope)); - JetType rightType = right == null ? null : getType(right, contextWithExpectedType.replaceScope(context.scope)); - if (leftType != null) { - if (!leftType.isNullable()) { -// context.trace.getErrorHandler().genericWarning(left.getNode(), "Elvis operator (?:) always returns the left operand of non-nullable type " + leftType); - context.trace.report(USELESS_ELVIS.on(expression, left, leftType)); - } - if (rightType != null) { - context.getServices().checkType(TypeUtils.makeNullableAsSpecified(leftType, rightType.isNullable()), left, contextWithExpectedType); - return TypeUtils.makeNullableAsSpecified(context.semanticServices.getTypeChecker().commonSupertype(leftType, rightType), rightType.isNullable()); - } - } - } - else { -// context.trace.getErrorHandler().genericError(operationSign.getNode(), "Unknown operation"); - context.trace.report(UNSUPPORTED.on(operationSign, "Unknown operation")); - } - return context.getServices().checkType(result, expression, contextWithExpectedType); - } - - private void checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @NotNull JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context) { - String name = "contains"; - ExpressionReceiver receiver = safeGetExpressionReceiver(right, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE)); - FunctionDescriptor functionDescriptor = context.resolveCallWithGivenName( - CallMaker.makeCallWithExpressions(callElement, receiver, null, operationSign, Collections.singletonList(left)), - operationSign, - name, receiver); - JetType containsType = functionDescriptor != null ? functionDescriptor.getReturnType() : null; - ensureBooleanResult(operationSign, name, containsType, context); - } - - private void ensureNonemptyIntersectionOfOperandTypes(JetBinaryExpression expression, ExpressionTypingContext context) { - JetSimpleNameExpression operationSign = expression.getOperationReference(); - JetExpression left = expression.getLeft(); - JetExpression right = expression.getRight(); - - // TODO : duplicated effort for == and != - JetType leftType = getType(left, context.replaceScope(context.scope)); - if (leftType != null && right != null) { - JetType rightType = getType(right, context.replaceScope(context.scope)); - - if (rightType != null) { - JetType intersect = TypeUtils.intersect(context.semanticServices.getTypeChecker(), new HashSet(Arrays.asList(leftType, rightType))); - if (intersect == null) { -// context.trace.getErrorHandler().genericError(expression.getNode(), "Operator " + operationSign.getReferencedName() + " cannot be applied to " + leftType + " and " + rightType); - context.trace.report(EQUALITY_NOT_APPLICABLE.on(expression, operationSign, leftType, rightType)); - } - } - } - } - - protected JetType visitAssignmentOperation(JetBinaryExpression expression, ExpressionTypingContext context) { - return assignmentIsNotAnExpressionError(expression, context); - } - - protected JetType visitAssignment(JetBinaryExpression expression, ExpressionTypingContext context) { - return assignmentIsNotAnExpressionError(expression, context); - } - - private JetType assignmentIsNotAnExpressionError(JetBinaryExpression expression, ExpressionTypingContext context) { -// context.trace.getErrorHandler().genericError(expression.getNode(), "Assignments are not expressions, and only expressions are allowed in this context"); - context.trace.report(ASSIGNMENT_IN_EXPRESSION_CONTEXT.on(expression)); - return null; - } - - private boolean ensureBooleanResult(JetExpression operationSign, String name, JetType resultType, ExpressionTypingContext context) { - return ensureBooleanResultWithCustomSubject(operationSign, resultType, "'" + name + "'", context); - } - - private boolean ensureBooleanResultWithCustomSubject(JetExpression operationSign, JetType resultType, String subjectName, ExpressionTypingContext context) { - if (resultType != null) { - // TODO : Relax? - if (!isBoolean(context.semanticServices, resultType)) { -// context.trace.getErrorHandler().genericError(operationSign.getNode(), subjectName + " must return Boolean but returns " + resultType); - context.trace.report(RESULT_TYPE_MISMATCH.on(operationSign, subjectName, context.semanticServices.getStandardLibrary().getBooleanType(), resultType)); - return false; - } - } - return true; - } - - private boolean isBoolean(JetSemanticServices semanticServices, @NotNull JetType type) { - return semanticServices.getTypeChecker().isConvertibleTo(type, semanticServices.getStandardLibrary().getBooleanType()); - } - - @Override - public JetType visitArrayAccessExpression(JetArrayAccessExpression expression, ExpressionTypingContext contextWithExpectedType) { - ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); - JetExpression arrayExpression = expression.getArrayExpression(); - ExpressionReceiver receiver = getExpressionReceiver(arrayExpression, context.replaceScope(context.scope)); - - if (receiver != null) { - FunctionDescriptor functionDescriptor = context.resolveCallWithGivenName( - CallMaker.makeCallWithExpressions(expression, receiver, null, expression, expression.getIndexExpressions()), - expression, - "get", - receiver); - if (functionDescriptor != null) { - return context.getServices().checkType(functionDescriptor.getReturnType(), expression, contextWithExpectedType); - } - } - return null; - } - - @Nullable - protected JetType getTypeForBinaryCall(JetScope scope, String name, ExpressionTypingContext context, JetBinaryExpression binaryExpression) { - ExpressionReceiver receiver = safeGetExpressionReceiver(binaryExpression.getLeft(), context.replaceScope(scope)); - FunctionDescriptor functionDescriptor = context.replaceScope(scope).resolveCallWithGivenName( - CallMaker.makeCall(receiver, binaryExpression), - binaryExpression.getOperationReference(), - name, - receiver); - if (functionDescriptor != null) { -// if (receiver.getType().isNullable()) { -// // TODO : better error message for '1 + nullableVar' case -// JetExpression right = binaryExpression.getRight(); -// String rightText = right == null ? "" : right.getText(); -// String leftText = binaryExpression.getLeft().getText(); -//// context.trace.getErrorHandler().genericError(binaryExpression.getOperationReference().getNode(), -//// "Infix call corresponds to a dot-qualified call '" + -//// leftText + "." + name + "(" + rightText + ")'" + -//// " which is not allowed on a nullable receiver '" + leftText + "'." + -//// " Use '?.'-qualified call instead"); -// context.trace.report(UNSAFE_INFIX_CALL.on(binaryExpression.getOperationReference(), leftText, name, rightText)); -// } - - - return functionDescriptor.getReturnType(); - } - return null; - } - - @Override - public JetType visitDeclaration(JetDeclaration dcl, ExpressionTypingContext context) { -// context.trace.getErrorHandler().genericError(dcl.getNode(), "Declarations are not allowed in this position"); - context.trace.report(DECLARATION_IN_ILLEGAL_CONTEXT.on(dcl)); - return null; - } - - @Override - public JetType visitRootNamespaceExpression(JetRootNamespaceExpression expression, ExpressionTypingContext context) { -// context.trace.getErrorHandler().genericError(expression.getNode(), "'namespace' is not an expression"); - context.trace.report(NAMESPACE_IS_NOT_AN_EXPRESSION.on(expression)); - return null; - } - - - @Override - public JetType visitStringTemplateExpression(JetStringTemplateExpression expression, ExpressionTypingContext contextWithExpectedType) { - final ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); - final StringBuilder builder = new StringBuilder(); - final CompileTimeConstant[] value = new CompileTimeConstant[1]; - for (JetStringTemplateEntry entry : expression.getEntries()) { - entry.accept(new JetVisitorVoid() { - - @Override - public void visitStringTemplateEntryWithExpression(JetStringTemplateEntryWithExpression entry) { - JetExpression entryExpression = entry.getExpression(); - if (entryExpression != null) { - getType(entryExpression, context.replaceScope(context.scope)); - } - value[0] = CompileTimeConstantResolver.OUT_OF_RANGE; - } - - @Override - public void visitLiteralStringTemplateEntry(JetLiteralStringTemplateEntry entry) { - builder.append(entry.getText()); - } - - @Override - public void visitEscapeStringTemplateEntry(JetEscapeStringTemplateEntry entry) { - // TODO : Check escape - String text = entry.getText(); - assert text.length() == 2 && text.charAt(0) == '\\'; - char escaped = text.charAt(1); - - Character character = CompileTimeConstantResolver.translateEscape(escaped); - if (character == null) { -// context.trace.getErrorHandler().genericError(entry.getNode(), "Illegal escape sequence"); - context.trace.report(ILLEGAL_ESCAPE_SEQUENCE.on(entry)); - value[0] = CompileTimeConstantResolver.OUT_OF_RANGE; - } - else { - builder.append(character); - } - } - }); - } - if (value[0] != CompileTimeConstantResolver.OUT_OF_RANGE) { - context.trace.record(BindingContext.COMPILE_TIME_VALUE, expression, new StringValue(builder.toString())); - } - return context.getServices().checkType(context.semanticServices.getStandardLibrary().getStringType(), expression, contextWithExpectedType); - } - - @Override - public JetType visitJetElement(JetElement element, ExpressionTypingContext context) { -// context.trace.getErrorHandler().genericError(element.getNode(), "[OperatorConventions] Unsupported element: " + element + " " + element.getClass().getCanonicalName()); - context.trace.report(UNSUPPORTED.on(element, getClass().getCanonicalName())); - return null; - } -} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTyperVisitorWithNamespaces.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTyperVisitorWithNamespaces.java deleted file mode 100644 index 4372f5506a3..00000000000 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTyperVisitorWithNamespaces.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.jetbrains.jet.lang.types.expressions; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.psi.JetRootNamespaceExpression; -import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; -import org.jetbrains.jet.lang.resolve.JetModuleUtil; -import org.jetbrains.jet.lang.types.JetType; - -/** -* @author abreslav -*/ -public class ExpressionTyperVisitorWithNamespaces extends ExpressionTyperVisitor { - public static final ExpressionTyperVisitorWithNamespaces INSTANCE = new ExpressionTyperVisitorWithNamespaces(); - - private ExpressionTyperVisitorWithNamespaces() {} - - @Override - public boolean isNamespacePosition() { - return true; - } - - @Override - public JetType visitRootNamespaceExpression(JetRootNamespaceExpression expression, ExpressionTypingContext context) { - return context.getServices().checkType(JetModuleUtil.getRootNamespaceType(expression), expression, context); - } - - @Override - protected boolean furtherNameLookup(@NotNull JetSimpleNameExpression expression, @NotNull String referencedName, @NotNull JetType[] result, ExpressionTypingContext context) { - result[0] = lookupNamespaceType(expression, referencedName, context); - return result[0] != null; - } - -} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java index 703a84642bf..68a1be872b1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingContext.java @@ -20,7 +20,6 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeUtils; -import java.util.HashMap; import java.util.List; import java.util.Map; @@ -38,21 +37,22 @@ import java.util.Map; @NotNull JetScope scope, @NotNull DataFlowInfo dataFlowInfo, @NotNull JetType expectedType, - @NotNull JetType expectedReturnType) { - return new ExpressionTypingContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, dataFlowInfo, expectedType, expectedReturnType); - } - - @NotNull - public static ExpressionTypingContext newRootContext( - @NotNull JetSemanticServices semanticServices, - @NotNull BindingTrace trace, - @NotNull JetScope scope, - @NotNull DataFlowInfo dataFlowInfo, - @NotNull JetType expectedType, - @NotNull JetType expectedReturnType) { - return new ExpressionTypingContext(semanticServices, new HashMap(), new HashMap>(), new LabelResolver(), trace, scope, dataFlowInfo, expectedType, expectedReturnType); + @NotNull JetType expectedReturnType, + boolean namespacesAllowed) { + return new ExpressionTypingContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, dataFlowInfo, expectedType, expectedReturnType, namespacesAllowed); } +// @NotNull +// public static ExpressionTypingContext newRootContext( +// @NotNull JetSemanticServices semanticServices, +// @NotNull BindingTrace trace, +// @NotNull JetScope scope, +// @NotNull DataFlowInfo dataFlowInfo, +// @NotNull JetType expectedType, +// @NotNull JetType expectedReturnType) { +// return newContext(semanticServices, new HashMap(), new HashMap>(), new LabelResolver(), trace, scope, dataFlowInfo, expectedType, expectedReturnType); +// } +// public final JetSemanticServices semanticServices; public final BindingTrace trace; public final JetScope scope; @@ -65,10 +65,12 @@ import java.util.Map; public final Map> patternsToBoundVariableLists; public final LabelResolver labelResolver; + public final boolean namespacesAllowed; + private CallResolver callResolver; private TypeResolver typeResolver; private ClassDescriptorResolver classDescriptorResolver; - private ExpressionTyperServices services; + private ExpressionTypingServices services; private CompileTimeConstantResolver compileTimeConstantResolver; private ExpressionTypingContext( @@ -80,58 +82,56 @@ import java.util.Map; @NotNull JetScope scope, @NotNull DataFlowInfo dataFlowInfo, @NotNull JetType expectedType, - @NotNull JetType expectedReturnType) { + @NotNull JetType expectedReturnType, + boolean namespacesAllowed) { this.trace = trace; -// this.typeResolver = new TypeResolver(semanticServices, trace, true); this.patternsToBoundVariableLists = patternsToBoundVariableLists; this.patternsToDataFlowInfo = patternsToDataFlowInfo; this.labelResolver = labelResolver; this.scope = scope; -// this.services = new ExpressionTyperServices(semanticServices, trace); this.semanticServices = semanticServices; -// this.classDescriptorResolver = semanticServices.getClassDescriptorResolver(trace); this.dataFlowInfo = dataFlowInfo; this.expectedType = expectedType; this.expectedReturnType = expectedReturnType; + this.namespacesAllowed = namespacesAllowed; } + @NotNull + public ExpressionTypingContext replaceNamespacesAllowed(boolean namespacesAllowed) { + if (namespacesAllowed == this.namespacesAllowed) return this; + return newContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, dataFlowInfo, expectedType, expectedReturnType, namespacesAllowed); + } + + @NotNull public ExpressionTypingContext replaceDataFlowInfo(DataFlowInfo newDataFlowInfo) { - return newContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, newDataFlowInfo, expectedType, expectedReturnType); + if (newDataFlowInfo == dataFlowInfo) return this; + return newContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, newDataFlowInfo, expectedType, expectedReturnType, namespacesAllowed); } public ExpressionTypingContext replaceExpectedType(@Nullable JetType newExpectedType) { if (newExpectedType == null) return replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); if (expectedType == newExpectedType) return this; - return newContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, dataFlowInfo, newExpectedType, expectedReturnType); + return newContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, dataFlowInfo, newExpectedType, expectedReturnType, namespacesAllowed); } public ExpressionTypingContext replaceExpectedReturnType(@Nullable JetType newExpectedReturnType) { if (newExpectedReturnType == null) return replaceExpectedReturnType(TypeUtils.NO_EXPECTED_TYPE); if (expectedReturnType == newExpectedReturnType) return this; - return newContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, dataFlowInfo, expectedType, newExpectedReturnType); + return newContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, dataFlowInfo, expectedType, newExpectedReturnType, namespacesAllowed); } public ExpressionTypingContext replaceBindingTrace(@NotNull BindingTrace newTrace) { if (newTrace == trace) return this; - return newContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, newTrace, scope, dataFlowInfo, expectedType, expectedReturnType); - } - - public ExpressionTypingContext replaceExpectedTypeAndTrace(@NotNull JetType newExpectedType, @NotNull BindingTrace newTrace) { - if (newExpectedType == expectedType && newTrace == trace) return this; - return newContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, newTrace, scope, dataFlowInfo, newExpectedType, expectedReturnType); + return newContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, newTrace, scope, dataFlowInfo, expectedType, expectedReturnType, namespacesAllowed); } @NotNull public ExpressionTypingContext replaceScope(@NotNull JetScope newScope) { if (newScope == scope) return this; - return newContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, newScope, dataFlowInfo, expectedType, expectedReturnType); + return newContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, newScope, dataFlowInfo, expectedType, expectedReturnType, namespacesAllowed); } - @NotNull - public ExpressionTypingContext replaceExpectedTypes(@NotNull JetType newExpectedType, @NotNull JetType newExpectedReturnType) { - if (expectedType == newExpectedType && expectedReturnType == newExpectedReturnType) return this; - return newContext(semanticServices, patternsToDataFlowInfo, patternsToBoundVariableLists, labelResolver, trace, scope, dataFlowInfo, newExpectedType, newExpectedReturnType); - } +///////////// LAZY ACCESSORS public CallResolver getCallResolver() { if (callResolver == null) { @@ -140,30 +140,9 @@ import java.util.Map; return callResolver; } - @Nullable - public FunctionDescriptor resolveCallWithGivenName(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull String name, @NotNull ReceiverDescriptor receiver) { - return getCallResolver().resolveCallWithGivenName(trace, scope, call, functionReference, name, expectedType); - } - - @Nullable - public JetType resolveCall(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetCallExpression callExpression) { - return getCallResolver().resolveCall(trace, scope, CallMaker.makeCall(receiver, callOperationNode, callExpression), expectedType); - } - - @Nullable - public VariableDescriptor resolveSimpleProperty(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetSimpleNameExpression nameExpression) { - Call call = CallMaker.makePropertyCall(receiver, callOperationNode, nameExpression); - return getCallResolver().resolveSimpleProperty(trace, scope, call, expectedType); - } - - @NotNull - public OverloadResolutionResults resolveExactSignature(@NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List parameterTypes) { - return getCallResolver().resolveExactSignature(scope, receiver, name, parameterTypes); - } - - public ExpressionTyperServices getServices() { + public ExpressionTypingServices getServices() { if (services == null) { - services = new ExpressionTyperServices(semanticServices, trace); + services = new ExpressionTypingServices(semanticServices, trace); } return services; } @@ -188,4 +167,27 @@ import java.util.Map; } return compileTimeConstantResolver; } + +////////// Call resolution utilities + + @Nullable + public FunctionDescriptor resolveCallWithGivenName(@NotNull Call call, @NotNull JetReferenceExpression functionReference, @NotNull String name, @NotNull ReceiverDescriptor receiver) { + return getCallResolver().resolveCallWithGivenName(trace, scope, call, functionReference, name, expectedType); + } + + @Nullable + public JetType resolveCall(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetCallExpression callExpression) { + return getCallResolver().resolveCall(trace, scope, CallMaker.makeCall(receiver, callOperationNode, callExpression), expectedType); + } + + @Nullable + public VariableDescriptor resolveSimpleProperty(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetSimpleNameExpression nameExpression) { + Call call = CallMaker.makePropertyCall(receiver, callOperationNode, nameExpression); + return getCallResolver().resolveSimpleProperty(trace, scope, call, expectedType); + } + + @NotNull + public OverloadResolutionResults resolveExactSignature(@NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List parameterTypes) { + return getCallResolver().resolveExactSignature(scope, receiver, name, parameterTypes); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingFacade.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingFacade.java new file mode 100644 index 00000000000..dcbdad0e6c9 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingFacade.java @@ -0,0 +1,17 @@ +package org.jetbrains.jet.lang.types.expressions; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.jet.lang.types.JetType; + +/** + * @author abreslav + */ +public interface ExpressionTypingFacade { + @NotNull + JetType safeGetType(@NotNull JetExpression expression, ExpressionTypingContext context); + + @Nullable + JetType getType(@NotNull JetExpression expression, ExpressionTypingContext context); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingInternals.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingInternals.java new file mode 100644 index 00000000000..8dff3d7a264 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingInternals.java @@ -0,0 +1,27 @@ +package org.jetbrains.jet.lang.types.expressions; + +import com.intellij.lang.ASTNode; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.JetElement; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; +import org.jetbrains.jet.lang.resolve.calls.DataFlowInfo; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; +import org.jetbrains.jet.lang.types.JetType; + +/** + * @author abreslav + */ +/*package*/ interface ExpressionTypingInternals extends ExpressionTypingFacade { + + void setResultingDataFlowInfo(@NotNull DataFlowInfo dataFlowInfo); + + @Nullable + DataFlowInfo getResultingDataFlowInfo(); + + @Nullable + JetType getSelectorReturnType(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetExpression selectorExpression, @NotNull ExpressionTypingContext context); + + void checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @NotNull JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java new file mode 100644 index 00000000000..c4e0141a02f --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingServices.java @@ -0,0 +1,288 @@ +package org.jetbrains.jet.lang.types.expressions; + +import com.google.common.collect.Lists; +import com.intellij.psi.PsiElement; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.JetSemanticServices; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptorUtil; +import org.jetbrains.jet.lang.descriptors.VariableDescriptor; +import org.jetbrains.jet.lang.diagnostics.Diagnostic; +import org.jetbrains.jet.lang.diagnostics.DiagnosticWithPsiElement; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.*; +import org.jetbrains.jet.lang.resolve.calls.DataFlowInfo; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.resolve.scopes.WritableScope; +import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; +import org.jetbrains.jet.lang.types.*; +import org.jetbrains.jet.lexer.JetTokens; + +import java.util.*; + +import static org.jetbrains.jet.lang.diagnostics.Errors.TYPE_MISMATCH; +import static org.jetbrains.jet.lang.resolve.BindingContext.*; +import static org.jetbrains.jet.lang.types.TypeUtils.FORBIDDEN; +import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; + +/** +* @author abreslav +*/ +public class ExpressionTypingServices { + private final JetSemanticServices semanticServices; + private final BindingTrace trace; + + private final ExpressionTypingFacade expressionTypingFacade = ExpressionTypingVisitorDispatcher.create(); + + public ExpressionTypingServices(JetSemanticServices semanticServices, BindingTrace trace) { + this.semanticServices = semanticServices; + this.trace = trace; + } + + @NotNull + public JetType safeGetType(@NotNull JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType) { + JetType type = getType(scope, expression, expectedType); + if (type != null) { + return type; + } + return ErrorUtils.createErrorType("Type for " + expression.getText()); + } + + @Nullable + public JetType getType(@NotNull final JetScope scope, @NotNull JetExpression expression, @NotNull JetType expectedType) { + ExpressionTypingContext context = ExpressionTypingContext.newContext( + semanticServices, + new HashMap(), new HashMap>(), new LabelResolver(), + trace, scope, DataFlowInfo.getEmpty(), expectedType, FORBIDDEN, false + ); + return expressionTypingFacade.getType(expression, context); + } + + public JetType getTypeWithNamespaces(@NotNull final JetScope scope, @NotNull JetExpression expression) { + ExpressionTypingContext context = ExpressionTypingContext.newContext( + semanticServices, + new HashMap(), new HashMap>(), new LabelResolver(), + trace, scope, DataFlowInfo.getEmpty(), NO_EXPECTED_TYPE, FORBIDDEN, + true); + return expressionTypingFacade.getType(expression, context); +// return ((ExpressionTypingContext) ExpressionTyperVisitorWithNamespaces).INSTANCE.getType(expression, ExpressionTypingContext.newRootContext(semanticServices, trace, scope, DataFlowInfo.getEmpty(), TypeUtils.NO_EXPECTED_TYPE, TypeUtils.NO_EXPECTED_TYPE)); + } + + public void checkFunctionReturnType(@NotNull JetScope outerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor) { + checkFunctionReturnType(outerScope, function, functionDescriptor, DataFlowInfo.getEmpty()); + } + + @NotNull + public JetType inferFunctionReturnType(@NotNull JetScope outerScope, JetDeclarationWithBody function, FunctionDescriptor functionDescriptor) { + Map typeMap = collectReturnedExpressionsWithTypes(trace, outerScope, function, functionDescriptor); + Collection types = typeMap.values(); + return types.isEmpty() + ? JetStandardClasses.getNothingType() + : semanticServices.getTypeChecker().commonSupertype(types); + } + + public void checkFunctionReturnType(JetScope functionInnerScope, JetDeclarationWithBody function, @NotNull final JetType expectedReturnType) { + checkFunctionReturnType(function, ExpressionTypingContext.newContext( + semanticServices, new HashMap(), new HashMap>(), new LabelResolver(), + trace, functionInnerScope, DataFlowInfo.getEmpty(), NO_EXPECTED_TYPE, expectedReturnType, false + )); + } + +///////////////////////////////////////////////////////// + + /*package*/ void checkFunctionReturnType(@NotNull JetScope outerScope, @NotNull JetDeclarationWithBody function, @NotNull FunctionDescriptor functionDescriptor, DataFlowInfo dataFlowInfo) { + JetType expectedReturnType = functionDescriptor.getReturnType(); + if (!function.hasBlockBody() && !function.hasDeclaredReturnType()) { + expectedReturnType = NO_EXPECTED_TYPE; + } + JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace); + checkFunctionReturnType(function, ExpressionTypingContext.newContext( + semanticServices, new HashMap(), new HashMap>(), new LabelResolver(), + trace, functionInnerScope, dataFlowInfo, NO_EXPECTED_TYPE, expectedReturnType, false + )); + } + + /*package*/ void checkFunctionReturnType(JetDeclarationWithBody function, ExpressionTypingContext context) { + JetExpression bodyExpression = function.getBodyExpression(); + if (bodyExpression == null) return; + + final boolean blockBody = function.hasBlockBody(); + final ExpressionTypingContext newContext = + blockBody + ? context.replaceExpectedType(NO_EXPECTED_TYPE) + : context.replaceExpectedType(context.expectedReturnType == FORBIDDEN ? NO_EXPECTED_TYPE : context.expectedReturnType).replaceExpectedReturnType(FORBIDDEN); + + if (function instanceof JetFunctionLiteralExpression) { + JetFunctionLiteralExpression functionLiteralExpression = (JetFunctionLiteralExpression) function; + getBlockReturnedType(newContext.scope, functionLiteralExpression.getBodyExpression(), CoercionStrategy.COERCION_TO_UNIT, newContext); + } + else { + expressionTypingFacade.getType(bodyExpression, newContext); + } + } + + @Nullable + /*package*/ JetType getBlockReturnedType(@NotNull JetScope outerScope, @NotNull JetBlockExpression expression, @NotNull CoercionStrategy coercionStrategyForLastExpression, ExpressionTypingContext context) { + List block = expression.getStatements(); + if (block.isEmpty()) { + return ExpressionTypingUtils.checkType(JetStandardClasses.getUnitType(), expression, context); + } + + DeclarationDescriptor containingDescriptor = outerScope.getContainingDeclaration(); + WritableScope scope = new WritableScopeImpl(outerScope, containingDescriptor, new TraceBasedRedeclarationHandler(context.trace)).setDebugName("getBlockReturnedType"); + return getBlockReturnedTypeWithWritableScope(scope, block, coercionStrategyForLastExpression, context); + } + + private Map collectReturnedExpressionsWithTypes( + final @NotNull BindingTrace trace, + JetScope outerScope, + final JetDeclarationWithBody function, + FunctionDescriptor functionDescriptor) { + JetExpression bodyExpression = function.getBodyExpression(); + assert bodyExpression != null; + JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace); + expressionTypingFacade.getType(bodyExpression, ExpressionTypingContext.newContext(semanticServices, new HashMap(), new HashMap>(), new LabelResolver(), + trace, functionInnerScope, DataFlowInfo.getEmpty(), NO_EXPECTED_TYPE, FORBIDDEN, false)); + //todo function literals + final Collection returnedExpressions = Lists.newArrayList(); + if (function.hasBlockBody()) { + //now this code is never invoked!, it should be invoked for inference of return type of function literal with local returns + bodyExpression.accept(new JetTreeVisitor() { + @Override + public Void visitReturnExpression(JetReturnExpression expression, JetDeclarationWithBody outerFunction) { + JetSimpleNameExpression targetLabel = expression.getTargetLabel(); + PsiElement element = targetLabel != null ? trace.get(LABEL_TARGET, targetLabel) : null; + if (element == function || (targetLabel == null && outerFunction == function)) { + returnedExpressions.add(expression); + } + return null; + } + + @Override + public Void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression, JetDeclarationWithBody outerFunction) { + return super.visitFunctionLiteralExpression(expression, expression.getFunctionLiteral()); + } + + @Override + public Void visitNamedFunction(JetNamedFunction function, JetDeclarationWithBody outerFunction) { + return super.visitNamedFunction(function, function); + } + }, function); + } + else { + returnedExpressions.add(bodyExpression); + } + Map typeMap = new HashMap(); + for (JetExpression returnedExpression : returnedExpressions) { + JetType cachedType = trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, returnedExpression); + trace.record(STATEMENT, returnedExpression, false); + if (cachedType != null) { + typeMap.put(returnedExpression, cachedType); + } + } + return typeMap; + } + + /*package*/ JetType getBlockReturnedTypeWithWritableScope(@NotNull WritableScope scope, @NotNull List block, @NotNull CoercionStrategy coercionStrategyForLastExpression, ExpressionTypingContext context) { + if (block.isEmpty()) { + return JetStandardClasses.getUnitType(); + } + + ExpressionTypingInternals blockLevelVisitor = ExpressionTypingVisitorDispatcher.createForBlock(scope); + ExpressionTypingContext newContext = createContext(context, trace, scope, context.dataFlowInfo, NO_EXPECTED_TYPE, context.expectedReturnType); + + JetType result = null; + for (Iterator iterator = block.iterator(); iterator.hasNext(); ) { + final JetElement statement = iterator.next(); + trace.record(STATEMENT, statement); + final JetExpression statementExpression = (JetExpression) statement; + //TODO constructor assert context.expectedType != FORBIDDEN : "" + if (!iterator.hasNext()) { + if (context.expectedType != NO_EXPECTED_TYPE) { + if (coercionStrategyForLastExpression == CoercionStrategy.COERCION_TO_UNIT && JetStandardClasses.isUnit(context.expectedType)) { + // This implements coercion to Unit + TemporaryBindingTrace temporaryTraceExpectingUnit = TemporaryBindingTrace.create(trace); + final boolean[] mismatch = new boolean[1]; + ObservableBindingTrace errorInterceptingTrace = makeTraceInterceptingTypeMismatch(temporaryTraceExpectingUnit, statementExpression, mismatch); + newContext = createContext(newContext, errorInterceptingTrace, scope, newContext.dataFlowInfo, context.expectedType, context.expectedReturnType); + result = blockLevelVisitor.getType(statementExpression, newContext); + if (mismatch[0]) { + TemporaryBindingTrace temporaryTraceNoExpectedType = TemporaryBindingTrace.create(trace); + mismatch[0] = false; + ObservableBindingTrace interceptingTrace = makeTraceInterceptingTypeMismatch(temporaryTraceNoExpectedType, statementExpression, mismatch); + newContext = createContext(newContext, interceptingTrace, scope, newContext.dataFlowInfo, NO_EXPECTED_TYPE, context.expectedReturnType); + result = blockLevelVisitor.getType(statementExpression, newContext); + if (mismatch[0]) { + temporaryTraceExpectingUnit.commit(); + } + else { + temporaryTraceNoExpectedType.commit(); + } + } + else { + temporaryTraceExpectingUnit.commit(); + } + } + else { + newContext = createContext(newContext, trace, scope, newContext.dataFlowInfo, context.expectedType, context.expectedReturnType); + result = blockLevelVisitor.getType(statementExpression, newContext); + } + } + else { + result = blockLevelVisitor.getType(statementExpression, newContext); + if (coercionStrategyForLastExpression == CoercionStrategy.COERCION_TO_UNIT) { + boolean mightBeUnit = false; + if (statementExpression instanceof JetDeclaration) { + mightBeUnit = true; + } + if (statementExpression instanceof JetBinaryExpression) { + JetBinaryExpression binaryExpression = (JetBinaryExpression) statementExpression; + IElementType operationType = binaryExpression.getOperationToken(); + if (operationType == JetTokens.EQ || OperatorConventions.ASSIGNMENT_OPERATIONS.containsKey(operationType)) { + mightBeUnit = true; + } + } + if (mightBeUnit) { + // ExpressionTypingVisitorWithWritableScope should return only null or Unit for declarations and assignments + assert result == null || JetStandardClasses.isUnit(result); + result = JetStandardClasses.getUnitType(); + } + } + } + } + else { + result = blockLevelVisitor.getType(statementExpression, newContext); + } + + DataFlowInfo newDataFlowInfo = blockLevelVisitor.getResultingDataFlowInfo(); + if (newDataFlowInfo == null) { + newDataFlowInfo = context.dataFlowInfo; + } + if (newDataFlowInfo != context.dataFlowInfo) { + newContext = createContext(newContext, trace, scope, newDataFlowInfo, NO_EXPECTED_TYPE, context.expectedReturnType); + } + blockLevelVisitor = ExpressionTypingVisitorDispatcher.createForBlock(scope); + } + return result; + } + + private ExpressionTypingContext createContext(ExpressionTypingContext oldContext, BindingTrace trace, WritableScope scope, DataFlowInfo dataFlowInfo, JetType expectedType, JetType expectedReturnType) { + return ExpressionTypingContext.newContext(oldContext.semanticServices, oldContext.patternsToDataFlowInfo, oldContext.patternsToBoundVariableLists, oldContext.labelResolver, trace, scope, dataFlowInfo, expectedType, expectedReturnType, oldContext.namespacesAllowed); + } + + private ObservableBindingTrace makeTraceInterceptingTypeMismatch(final BindingTrace trace, final JetExpression expressionToWatch, final boolean[] mismatchFound) { + return new ObservableBindingTrace(trace) { + + @Override + public void report(@NotNull Diagnostic diagnostic) { + if (diagnostic.getFactory() == TYPE_MISMATCH && ((DiagnosticWithPsiElement) diagnostic).getPsiElement() == expressionToWatch) { + mismatchFound[0] = true; + } + super.report(diagnostic); + } + }; + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java new file mode 100644 index 00000000000..75aefa19eb0 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java @@ -0,0 +1,252 @@ +package org.jetbrains.jet.lang.types.expressions; + +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.tree.TokenSet; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.JetNodeTypes; +import org.jetbrains.jet.lang.JetSemanticServices; +import org.jetbrains.jet.lang.descriptors.VariableDescriptor; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.TraceBasedRedeclarationHandler; +import org.jetbrains.jet.lang.resolve.calls.AutoCastUtils; +import org.jetbrains.jet.lang.resolve.calls.DataFlowInfo; +import org.jetbrains.jet.lang.resolve.scopes.WritableScope; +import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; +import org.jetbrains.jet.lang.types.JetStandardClasses; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeUtils; +import org.jetbrains.jet.lexer.JetTokens; + +import java.util.List; + +import static org.jetbrains.jet.lang.diagnostics.Errors.RESULT_TYPE_MISMATCH; +import static org.jetbrains.jet.lang.diagnostics.Errors.TYPE_MISMATCH; + +/** + * @author abreslav + */ +public class ExpressionTypingUtils { + + @Nullable + protected static ExpressionReceiver getExpressionReceiver(@NotNull ExpressionTypingFacade facade, @NotNull JetExpression expression, ExpressionTypingContext context) { + JetType type = facade.getType(expression, context); + if (type == null) { + return null; + } + return new ExpressionReceiver(expression, type); + } + + @NotNull + protected static ExpressionReceiver safeGetExpressionReceiver(@NotNull ExpressionTypingFacade facade, @NotNull JetExpression expression, ExpressionTypingContext context) { + return new ExpressionReceiver(expression, facade.safeGetType(expression, context)); + } + + @NotNull + public static WritableScopeImpl newWritableScopeImpl(ExpressionTypingContext context) { + return new WritableScopeImpl(context.scope, context.scope.getContainingDeclaration(), new TraceBasedRedeclarationHandler(context.trace)); + } + + public static boolean isBoolean(@NotNull JetSemanticServices semanticServices, @NotNull JetType type) { + return semanticServices.getTypeChecker().isConvertibleTo(type, semanticServices.getStandardLibrary().getBooleanType()); + } + + public static boolean ensureBooleanResult(JetExpression operationSign, String name, JetType resultType, ExpressionTypingContext context) { + return ensureBooleanResultWithCustomSubject(operationSign, resultType, "'" + name + "'", context); + } + + public static boolean ensureBooleanResultWithCustomSubject(JetExpression operationSign, JetType resultType, String subjectName, ExpressionTypingContext context) { + if (resultType != null) { + // TODO : Relax? + if (!isBoolean(context.semanticServices, resultType)) { +// context.trace.getErrorHandler().genericError(operationSign.getNode(), subjectName + " must return Boolean but returns " + resultType); + context.trace.report(RESULT_TYPE_MISMATCH.on(operationSign, subjectName, context.semanticServices.getStandardLibrary().getBooleanType(), resultType)); + return false; + } + } + return true; + } + + @NotNull + public static JetType getDefaultType(JetSemanticServices semanticServices, IElementType constantType) { + if (constantType == JetNodeTypes.INTEGER_CONSTANT) { + return semanticServices.getStandardLibrary().getIntType(); + } + else if (constantType == JetNodeTypes.FLOAT_CONSTANT) { + return semanticServices.getStandardLibrary().getDoubleType(); + } + else if (constantType == JetNodeTypes.BOOLEAN_CONSTANT) { + return semanticServices.getStandardLibrary().getBooleanType(); + } + else if (constantType == JetNodeTypes.CHARACTER_CONSTANT) { + return semanticServices.getStandardLibrary().getCharType(); + } + else if (constantType == JetNodeTypes.RAW_STRING_CONSTANT) { + return semanticServices.getStandardLibrary().getStringType(); + } + else if (constantType == JetNodeTypes.NULL) { + return JetStandardClasses.getNullableNothingType(); + } + else { + throw new IllegalArgumentException("Unsupported constant type: " + constantType); + } + } + + @NotNull + public static DataFlowInfo extractDataFlowInfoFromCondition(@Nullable JetExpression condition, final boolean conditionValue, @Nullable final WritableScope scopeToExtend, final ExpressionTypingContext context) { + if (condition == null) return context.dataFlowInfo; + final DataFlowInfo[] result = new DataFlowInfo[] {context.dataFlowInfo}; + condition.accept(new JetVisitorVoid() { + @Override + public void visitIsExpression(JetIsExpression expression) { + if (conditionValue && !expression.isNegated() || !conditionValue && expression.isNegated()) { + JetPattern pattern = expression.getPattern(); + result[0] = context.patternsToDataFlowInfo.get(pattern); + if (scopeToExtend != null) { + List descriptors = context.patternsToBoundVariableLists.get(pattern); + if (descriptors != null) { + for (VariableDescriptor variableDescriptor : descriptors) { + scopeToExtend.addVariableDescriptor(variableDescriptor); + } + } + } + } + } + + @Override + public void visitBinaryExpression(JetBinaryExpression expression) { + IElementType operationToken = expression.getOperationToken(); + if (operationToken == JetTokens.ANDAND || operationToken == JetTokens.OROR) { + WritableScope actualScopeToExtend; + if (operationToken == JetTokens.ANDAND) { + actualScopeToExtend = conditionValue ? scopeToExtend : null; + } + else { + actualScopeToExtend = conditionValue ? null : scopeToExtend; + } + + DataFlowInfo dataFlowInfo = extractDataFlowInfoFromCondition(expression.getLeft(), conditionValue, actualScopeToExtend, context); + JetExpression expressionRight = expression.getRight(); + if (expressionRight != null) { + DataFlowInfo rightInfo = extractDataFlowInfoFromCondition(expressionRight, conditionValue, actualScopeToExtend, context); + DataFlowInfo.CompositionOperator operator; + if (operationToken == JetTokens.ANDAND) { + operator = conditionValue ? DataFlowInfo.AND : DataFlowInfo.OR; + } + else { + operator = conditionValue ? DataFlowInfo.OR : DataFlowInfo.AND; + } + dataFlowInfo = operator.compose(dataFlowInfo, rightInfo); + } + result[0] = dataFlowInfo; + } + else if (operationToken == JetTokens.EQEQ + || operationToken == JetTokens.EXCLEQ + || operationToken == JetTokens.EQEQEQ + || operationToken == JetTokens.EXCLEQEQEQ) { + JetExpression left = expression.getLeft(); + JetExpression right = expression.getRight(); + if (right == null) return; + + if (!(left instanceof JetSimpleNameExpression)) { + JetExpression tmp = left; + left = right; + right = tmp; + + if (!(left instanceof JetSimpleNameExpression)) { + return; + } + } + + VariableDescriptor variableDescriptor = AutoCastUtils.getVariableDescriptorFromSimpleName(context.trace.getBindingContext(), left); + if (variableDescriptor == null) return; + + // TODO : validate that DF makes sense for this variable: local, val, internal w/backing field, etc + + // Comparison to a non-null expression + JetType rhsType = context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, right); + if (rhsType != null && !rhsType.isNullable()) { + extendDataFlowWithNullComparison(operationToken, variableDescriptor, !conditionValue); + return; + } + + VariableDescriptor rightVariable = AutoCastUtils.getVariableDescriptorFromSimpleName(context.trace.getBindingContext(), right); + if (rightVariable != null) { + JetType lhsType = context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, left); + if (lhsType != null && !lhsType.isNullable()) { + extendDataFlowWithNullComparison(operationToken, rightVariable, !conditionValue); + return; + } + } + + // Comparison to 'null' + if (!(right instanceof JetConstantExpression)) { + return; + } + JetConstantExpression constantExpression = (JetConstantExpression) right; + if (constantExpression.getNode().getElementType() != JetNodeTypes.NULL) { + return; + } + + extendDataFlowWithNullComparison(operationToken, variableDescriptor, conditionValue); + } + } + + private void extendDataFlowWithNullComparison(IElementType operationToken, @NotNull VariableDescriptor variableDescriptor, boolean equalsToNull) { + if (operationToken == JetTokens.EQEQ || operationToken == JetTokens.EQEQEQ) { + result[0] = context.dataFlowInfo.equalsToNull(variableDescriptor, !equalsToNull); + } + else if (operationToken == JetTokens.EXCLEQ || operationToken == JetTokens.EXCLEQEQEQ) { + result[0] = context.dataFlowInfo.equalsToNull(variableDescriptor, equalsToNull); + } + } + + @Override + public void visitUnaryExpression(JetUnaryExpression expression) { + IElementType operationTokenType = expression.getOperationSign().getReferencedNameElementType(); + if (operationTokenType == JetTokens.EXCL) { + JetExpression baseExpression = expression.getBaseExpression(); + if (baseExpression != null) { + result[0] = extractDataFlowInfoFromCondition(baseExpression, !conditionValue, scopeToExtend, context); + } + } + } + + @Override + public void visitParenthesizedExpression(JetParenthesizedExpression expression) { + JetExpression body = expression.getExpression(); + if (body != null) { + body.accept(this); + } + } + }); + if (result[0] == null) { + return context.dataFlowInfo; + } + return result[0]; + } + + public static boolean isTypeFlexible(@Nullable JetExpression expression) { + if (expression == null) return false; + + return TokenSet.create( + JetNodeTypes.INTEGER_CONSTANT, + JetNodeTypes.FLOAT_CONSTANT + ).contains(expression.getNode().getElementType()); + } + + @Nullable + public static JetType checkType(@Nullable JetType expressionType, @NotNull JetExpression expression, @NotNull ExpressionTypingContext context) { + if (expressionType == null || context.expectedType == null || context.expectedType == TypeUtils.NO_EXPECTED_TYPE || + context.semanticServices.getTypeChecker().isSubtypeOf(expressionType, context.expectedType)) { + return expressionType; + } + if (AutoCastUtils.castExpression(expression, context.expectedType, context.dataFlowInfo, context.trace) == null) { + context.trace.report(TYPE_MISMATCH.on(expression, context.expectedType, expressionType)); + return expressionType; + } + return context.expectedType; + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitor.java new file mode 100644 index 00000000000..702804df70b --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitor.java @@ -0,0 +1,17 @@ +package org.jetbrains.jet.lang.types.expressions; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetVisitor; +import org.jetbrains.jet.lang.types.JetType; + +/** + * @author abreslav + */ +/*package*/ abstract class ExpressionTypingVisitor extends JetVisitor { + + protected final ExpressionTypingInternals facade; + + protected ExpressionTypingVisitor(@NotNull ExpressionTypingInternals facade) { + this.facade = facade; + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java new file mode 100644 index 00000000000..0a8b5efd150 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorDispatcher.java @@ -0,0 +1,198 @@ +package org.jetbrains.jet.lang.types.expressions; + +import com.intellij.lang.ASTNode; +import com.intellij.util.Function; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.calls.DataFlowInfo; +import org.jetbrains.jet.lang.resolve.scopes.WritableScope; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; +import org.jetbrains.jet.lang.types.DeferredType; +import org.jetbrains.jet.lang.types.ErrorUtils; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.util.lazy.ReenteringLazyValueComputationException; + +import static org.jetbrains.jet.lang.diagnostics.Errors.TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM; + +/** + * @author abreslav + */ +public class ExpressionTypingVisitorDispatcher extends JetVisitor implements ExpressionTypingInternals { + + private static Function BASIC_FACTORY = new Function() { + @Override + public BasicExpressionTypingVisitor fun(ExpressionTypingInternals facade) { + return new BasicExpressionTypingVisitor(facade); + } + }; + + @NotNull + public static ExpressionTypingFacade create() { + return new ExpressionTypingVisitorDispatcher(BASIC_FACTORY); + } + + @NotNull + public static ExpressionTypingInternals createForBlock(final WritableScope writableScope) { + return new ExpressionTypingVisitorDispatcher(new Function() { + @Override + public BasicExpressionTypingVisitor fun(ExpressionTypingInternals facade) { + return new ExpressionTypingVisitorWithWritableScope(facade, writableScope); + } + }); + } + + private final BasicExpressionTypingVisitor basic; + private final ClosureExpressionsTypingVisitor closures = new ClosureExpressionsTypingVisitor(this); + private final ControlStructureTypingVisitor controlStructures = new ControlStructureTypingVisitor(this); + private final PatternMatchingTypingVisitor patterns = new PatternMatchingTypingVisitor(this); + protected DataFlowInfo resultDataFlowInfo; + + private ExpressionTypingVisitorDispatcher(Function factoryForBasic) { + this.basic = factoryForBasic.fun(this); + } + + @Override + @Nullable + public DataFlowInfo getResultingDataFlowInfo() { + return resultDataFlowInfo; + } + + @Override + public JetType getSelectorReturnType(@NotNull ReceiverDescriptor receiver, @Nullable ASTNode callOperationNode, @NotNull JetExpression selectorExpression, @NotNull ExpressionTypingContext context) { + return basic.getSelectorReturnType(receiver, callOperationNode, selectorExpression, context); + } + + @Override + public void checkInExpression(JetElement callElement, @NotNull JetSimpleNameExpression operationSign, @NotNull JetExpression left, @NotNull JetExpression right, ExpressionTypingContext context) { + basic.checkInExpression(callElement, operationSign, left, right, context); + } + + @Override + public void setResultingDataFlowInfo(@NotNull DataFlowInfo dataFlowInfo) { + this.resultDataFlowInfo = dataFlowInfo; + } + + @Override + @NotNull + public final JetType safeGetType(@NotNull JetExpression expression, ExpressionTypingContext context) { + JetType type = getType(expression, context); + if (type != null) { + return type; + } + return ErrorUtils.createErrorType("Type for " + expression.getText()); + } + + @Override + @Nullable + public final JetType getType(@NotNull JetExpression expression, ExpressionTypingContext context) { + if (context.trace.get(BindingContext.PROCESSED, expression)) { + return context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression); + } + JetType result; + try { + result = expression.accept(this, context); + // Some recursive definitions (object expressions) must put their types in the cache manually: + if (context.trace.get(BindingContext.PROCESSED, expression)) { + return context.trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression); + } + + if (result instanceof DeferredType) { + result = ((DeferredType) result).getActualType(); + } + if (result != null) { + context.trace.record(BindingContext.EXPRESSION_TYPE, expression, result); + } + + } + catch (ReenteringLazyValueComputationException e) { + context.trace.report(TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM.on(expression)); + result = null; + } + + if (!context.trace.get(BindingContext.PROCESSED, expression)) { + context.trace.record(BindingContext.RESOLUTION_SCOPE, expression, context.scope); + } + context.trace.record(BindingContext.PROCESSED, expression); + return result; + } + +////////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public JetType visitFunctionLiteralExpression(JetFunctionLiteralExpression expression, ExpressionTypingContext data) { + return expression.accept(closures, data); + } + + @Override + public JetType visitObjectLiteralExpression(JetObjectLiteralExpression expression, ExpressionTypingContext data) { + return expression.accept(closures, data); + } + +////////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public JetType visitThrowExpression(JetThrowExpression expression, ExpressionTypingContext data) { + return expression.accept(controlStructures, data); + } + + @Override + public JetType visitReturnExpression(JetReturnExpression expression, ExpressionTypingContext data) { + return expression.accept(controlStructures, data); + } + + @Override + public JetType visitContinueExpression(JetContinueExpression expression, ExpressionTypingContext data) { + return expression.accept(controlStructures, data); + } + + @Override + public JetType visitIfExpression(JetIfExpression expression, ExpressionTypingContext data) { + return expression.accept(controlStructures, data); + } + + @Override + public JetType visitTryExpression(JetTryExpression expression, ExpressionTypingContext data) { + return expression.accept(controlStructures, data); + } + + @Override + public JetType visitForExpression(JetForExpression expression, ExpressionTypingContext data) { + return expression.accept(controlStructures, data); + } + + @Override + public JetType visitWhileExpression(JetWhileExpression expression, ExpressionTypingContext data) { + return expression.accept(controlStructures, data); + } + + @Override + public JetType visitDoWhileExpression(JetDoWhileExpression expression, ExpressionTypingContext data) { + return expression.accept(controlStructures, data); + } + + @Override + public JetType visitBreakExpression(JetBreakExpression expression, ExpressionTypingContext data) { + return expression.accept(controlStructures, data); + } + +////////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public JetType visitIsExpression(JetIsExpression expression, ExpressionTypingContext data) { + return expression.accept(patterns, data); + } + + @Override + public JetType visitWhenExpression(JetWhenExpression expression, ExpressionTypingContext data) { + return expression.accept(patterns, data); + } + +////////////////////////////////////////////////////////////////////////////////////////////// + + @Override + public JetType visitJetElement(JetElement element, ExpressionTypingContext data) { + return element.accept(basic, data); + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTyperVisitorWithWritableScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorWithWritableScope.java similarity index 77% rename from compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTyperVisitorWithWritableScope.java rename to compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorWithWritableScope.java index 9f65b68dd34..bd5a325ffdf 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTyperVisitorWithWritableScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingVisitorWithWritableScope.java @@ -18,14 +18,16 @@ import org.jetbrains.jet.lexer.JetTokens; import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.resolve.BindingContext.MUST_BE_WRAPPED_IN_A_REF; import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; +import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.getExpressionReceiver; /** * @author abreslav */ -public class ExpressionTyperVisitorWithWritableScope extends ExpressionTyperVisitor { +public class ExpressionTypingVisitorWithWritableScope extends BasicExpressionTypingVisitor { private final WritableScope scope; - public ExpressionTyperVisitorWithWritableScope(@NotNull WritableScope scope) { + public ExpressionTypingVisitorWithWritableScope(@NotNull ExpressionTypingInternals facade, @NotNull WritableScope scope) { + super(facade); this.scope = scope; } @@ -44,19 +46,16 @@ public class ExpressionTyperVisitorWithWritableScope extends ExpressionTyperVisi public JetType visitProperty(JetProperty property, ExpressionTypingContext context) { JetTypeReference receiverTypeRef = property.getReceiverTypeRef(); if (receiverTypeRef != null) { -// context.trace.getErrorHandler().genericError(receiverTypeRef.getNode(), "Local receiver-properties are not allowed"); context.trace.report(LOCAL_EXTENSION_PROPERTY.on(receiverTypeRef)); } JetPropertyAccessor getter = property.getGetter(); if (getter != null) { -// context.trace.getErrorHandler().genericError(getter.getNode(), "Local variables are not allowed to have getters"); context.trace.report(LOCAL_VARIABLE_WITH_GETTER.on(getter)); } JetPropertyAccessor setter = property.getSetter(); if (setter != null) { -// context.trace.getErrorHandler().genericError(setter.getNode(), "Local variables are not allowed to have setters"); context.trace.report(LOCAL_VARIABLE_WITH_SETTER.on(setter)); } @@ -64,12 +63,7 @@ public class ExpressionTyperVisitorWithWritableScope extends ExpressionTyperVisi JetExpression initializer = property.getInitializer(); if (property.getPropertyTypeRef() != null && initializer != null) { JetType outType = propertyDescriptor.getOutType(); - JetType initializerType = getType(initializer, context.replaceExpectedType(outType).replaceScope(scope)); -// if (outType != null && -// initializerType != null && -// !semanticServices.getTypeChecker().isConvertibleTo(initializerType, outType)) { -// context.trace.report(TYPE_MISMATCH.on(initializer, outType, initializerType)); -// } + JetType initializerType = facade.getType(initializer, context.replaceExpectedType(outType).replaceScope(scope)); } scope.addVariableDescriptor(propertyDescriptor); @@ -141,14 +135,9 @@ public class ExpressionTyperVisitorWithWritableScope extends ExpressionTyperVisi JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) deparenthesized; return resolveArrayAccessToLValue(arrayAccessExpression, right, expression.getOperationReference(), context); } - JetType leftType = getType(left, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).replaceScope(scope)); + JetType leftType = facade.getType(left, context.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).replaceScope(scope)); if (right != null) { - JetType rightType = getType(right, context.replaceExpectedType(leftType).replaceScope(scope)); -// if (rightType != null && -// leftType != null && -// !semanticServices.getTypeChecker().isConvertibleTo(rightType, leftType)) { -// context.trace.report(TYPE_MISMATCH.on(right, leftType, rightType)); -// } + JetType rightType = facade.getType(right, context.replaceExpectedType(leftType).replaceScope(scope)); } if (left instanceof JetSimpleNameExpression) { JetSimpleNameExpression simpleName = (JetSimpleNameExpression) left; @@ -172,34 +161,22 @@ public class ExpressionTyperVisitorWithWritableScope extends ExpressionTyperVisi } private JetType resolveArrayAccessToLValue(JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide, JetSimpleNameExpression operationSign, ExpressionTypingContext context) { - ExpressionReceiver receiver = getExpressionReceiver(arrayAccessExpression.getArrayExpression(), context.replaceScope(scope)); + ExpressionReceiver receiver = getExpressionReceiver(facade, arrayAccessExpression.getArrayExpression(), context.replaceScope(scope)); if (receiver == null) return null; // Call call = CallMaker.makeCall(receiver, arrayAccessExpression, rightHandSide); -// // TODO : nasty hack: effort is duplicated -// callResolver.resolveCallWithGivenName( -// scope, -// call, -// arrayAccessExpression, -// "set", arrayAccessExpression.getArrayExpression(), NO_EXPECTED_TYPE); FunctionDescriptor functionDescriptor = context.replaceScope(scope).replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE).resolveCallWithGivenName( call, arrayAccessExpression, "set", receiver); if (functionDescriptor == null) return null; context.trace.record(REFERENCE_TARGET, operationSign, functionDescriptor); - return context.getServices().checkType(functionDescriptor.getReturnType(), arrayAccessExpression, context); - } - - @Override - public JetType visitAnnotatedExpression(JetAnnotatedExpression expression, ExpressionTypingContext data) { - return getType(expression.getBaseExpression(), data); + return ExpressionTypingUtils.checkType(functionDescriptor.getReturnType(), arrayAccessExpression, context); } @Override public JetType visitJetElement(JetElement element, ExpressionTypingContext context) { context.trace.report(UNSUPPORTED.on(element, "in a block")); -// context.trace.getErrorHandler().genericError(element.getNode(), "Unsupported element in a block: " + element + " " + element.getClass().getCanonicalName()); return null; } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/FunctionBodyTyper.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/FunctionBodyTyper.java new file mode 100644 index 00000000000..4b4200764d2 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/FunctionBodyTyper.java @@ -0,0 +1,7 @@ +package org.jetbrains.jet.lang.types.expressions; + +/** + * @author abreslav + */ +public class FunctionBodyTyper { +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java new file mode 100644 index 00000000000..3cd9cc80cab --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/PatternMatchingTypingVisitor.java @@ -0,0 +1,265 @@ +package org.jetbrains.jet.lang.types.expressions; + +import com.google.common.collect.Sets; +import com.intellij.lang.ASTNode; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.VariableDescriptor; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.calls.AutoCastUtils; +import org.jetbrains.jet.lang.resolve.calls.DataFlowInfo; +import org.jetbrains.jet.lang.resolve.scopes.WritableScope; +import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; +import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; +import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver; +import org.jetbrains.jet.lang.types.*; + +import java.util.List; +import java.util.Set; + +import static org.jetbrains.jet.lang.diagnostics.Errors.*; +import static org.jetbrains.jet.lang.diagnostics.Errors.INCOMPATIBLE_TYPES; +import static org.jetbrains.jet.lang.diagnostics.Errors.UNSUPPORTED; +import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.ensureBooleanResultWithCustomSubject; +import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.newWritableScopeImpl; + +/** + * @author abreslav + */ +public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor { + protected PatternMatchingTypingVisitor(@NotNull ExpressionTypingInternals facade) { + super(facade); + } + + @Override + public JetType visitIsExpression(JetIsExpression expression, ExpressionTypingContext contextWithExpectedType) { + ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); + JetType knownType = facade.safeGetType(expression.getLeftHandSide(), context.replaceScope(context.scope)); + JetPattern pattern = expression.getPattern(); + if (pattern != null) { + WritableScopeImpl scopeToExtend = newWritableScopeImpl(context).setDebugName("Scope extended in 'is'"); + DataFlowInfo newDataFlowInfo = checkPatternType(pattern, knownType, scopeToExtend, context, AutoCastUtils.getVariableDescriptorFromSimpleName(context.trace.getBindingContext(), expression.getLeftHandSide())); + context.patternsToDataFlowInfo.put(pattern, newDataFlowInfo); + context.patternsToBoundVariableLists.put(pattern, scopeToExtend.getDeclaredVariables()); + } + return ExpressionTypingUtils.checkType(context.semanticServices.getStandardLibrary().getBooleanType(), expression, contextWithExpectedType); + } + + @Override + public JetType visitWhenExpression(final JetWhenExpression expression, ExpressionTypingContext contextWithExpectedType) { + ExpressionTypingContext context = contextWithExpectedType.replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE); + // TODO :change scope according to the bound value in the when header + final JetExpression subjectExpression = expression.getSubjectExpression(); + + final JetType subjectType = subjectExpression != null ? context.getServices().safeGetType(context.scope, subjectExpression, TypeUtils.NO_EXPECTED_TYPE) : ErrorUtils.createErrorType("Unknown type"); + final VariableDescriptor variableDescriptor = subjectExpression != null ? AutoCastUtils.getVariableDescriptorFromSimpleName(context.trace.getBindingContext(), subjectExpression) : null; + + // TODO : exhaustive patterns + + Set expressionTypes = Sets.newHashSet(); + for (JetWhenEntry whenEntry : expression.getEntries()) { + JetWhenCondition[] conditions = whenEntry.getConditions(); + DataFlowInfo newDataFlowInfo; + WritableScope scopeToExtend; + if (conditions.length == 1) { + scopeToExtend = newWritableScopeImpl(context).setDebugName("Scope extended in when entry"); + newDataFlowInfo = context.dataFlowInfo; + JetWhenCondition condition = conditions[0]; + if (condition != null) { + newDataFlowInfo = checkWhenCondition(subjectExpression, subjectType, condition, scopeToExtend, context, variableDescriptor); + } + } + else { + scopeToExtend = newWritableScopeImpl(context); // We don't write to this scope + newDataFlowInfo = null; + for (JetWhenCondition condition : conditions) { + DataFlowInfo dataFlowInfo = checkWhenCondition(subjectExpression, subjectType, condition, newWritableScopeImpl(context), context, variableDescriptor); + if (newDataFlowInfo == null) { + newDataFlowInfo = dataFlowInfo; + } + else { + newDataFlowInfo = newDataFlowInfo.or(dataFlowInfo); + } + } + if (newDataFlowInfo == null) { + newDataFlowInfo = context.dataFlowInfo; + } + else { + newDataFlowInfo = newDataFlowInfo.and(context.dataFlowInfo); + } + } + JetExpression bodyExpression = whenEntry.getExpression(); + if (bodyExpression != null) { + JetType type = facade.getType(bodyExpression, contextWithExpectedType.replaceScope(scopeToExtend).replaceDataFlowInfo(newDataFlowInfo)); + if (type != null) { + expressionTypes.add(type); + } + } + } + + if (!expressionTypes.isEmpty()) { + return context.semanticServices.getTypeChecker().commonSupertype(expressionTypes); + } + else if (expression.getEntries().isEmpty()) { +// context.trace.getErrorHandler().genericError(expression.getNode(), "Entries required for when-expression"); + context.trace.report(NO_WHEN_ENTRIES.on(expression)); + } + return null; + } + + private DataFlowInfo checkWhenCondition(@Nullable final JetExpression subjectExpression, final JetType subjectType, JetWhenCondition condition, final WritableScope scopeToExtend, final ExpressionTypingContext context, final VariableDescriptor... subjectVariables) { + final DataFlowInfo[] newDataFlowInfo = new DataFlowInfo[]{context.dataFlowInfo}; + condition.accept(new JetVisitorVoid() { + + @Override + public void visitWhenConditionCall(JetWhenConditionCall condition) { + JetExpression callSuffixExpression = condition.getCallSuffixExpression(); +// JetScope compositeScope = new ScopeWithReceiver(context.scope, subjectType, semanticServices.getTypeChecker()); + if (callSuffixExpression != null) { +// JetType selectorReturnType = getType(compositeScope, callSuffixExpression, false, context); + assert subjectExpression != null; + JetType selectorReturnType = facade.getSelectorReturnType(new ExpressionReceiver(subjectExpression, subjectType), condition.getOperationTokenNode(), callSuffixExpression, context);//getType(compositeScope, callSuffixExpression, false, context); + ensureBooleanResultWithCustomSubject(callSuffixExpression, selectorReturnType, "This expression", context); +// context.getServices().checkNullSafety(subjectType, condition.getOperationTokenNode(), getCalleeFunctionDescriptor(callSuffixExpression, context), condition); + } + } + + @Override + public void visitWhenConditionInRange(JetWhenConditionInRange condition) { + JetExpression rangeExpression = condition.getRangeExpression(); + if (rangeExpression != null) { + assert subjectExpression != null; + facade.checkInExpression(condition, condition.getOperationReference(), subjectExpression, rangeExpression, context); + } + } + + @Override + public void visitWhenConditionIsPattern(JetWhenConditionIsPattern condition) { + JetPattern pattern = condition.getPattern(); + if (pattern != null) { + newDataFlowInfo[0] = checkPatternType(pattern, subjectType, scopeToExtend, context, subjectVariables); + } + } + + @Override + public void visitJetElement(JetElement element) { +// context.trace.getErrorHandler().genericError(element.getNode(), "Unsupported [OperatorConventions] : " + element); + context.trace.report(UNSUPPORTED.on(element, getClass().getCanonicalName())); + } + }); + return newDataFlowInfo[0]; + } + + private DataFlowInfo checkPatternType(@NotNull JetPattern pattern, @NotNull final JetType subjectType, @NotNull final WritableScope scopeToExtend, final ExpressionTypingContext context, @NotNull final VariableDescriptor... subjectVariables) { + final DataFlowInfo[] result = new DataFlowInfo[] {context.dataFlowInfo}; + pattern.accept(new JetVisitorVoid() { + @Override + public void visitTypePattern(JetTypePattern typePattern) { + JetTypeReference typeReference = typePattern.getTypeReference(); + if (typeReference != null) { + JetType type = context.getTypeResolver().resolveType(context.scope, typeReference); + checkTypeCompatibility(type, subjectType, typePattern); + result[0] = context.dataFlowInfo.isInstanceOf(subjectVariables, type); + } + } + + @Override + public void visitTuplePattern(JetTuplePattern pattern) { + List entries = pattern.getEntries(); + TypeConstructor typeConstructor = subjectType.getConstructor(); + if (!JetStandardClasses.getTuple(entries.size()).getTypeConstructor().equals(typeConstructor) + || typeConstructor.getParameters().size() != entries.size()) { +// context.trace.getErrorHandler().genericError(pattern.getNode(), "Type mismatch: subject is of type " + subjectType + " but the pattern is of type Tuple" + entries.size()); + context.trace.report(TYPE_MISMATCH_IN_TUPLE_PATTERN.on(pattern, subjectType, entries.size())); + } + else { + for (int i = 0, entriesSize = entries.size(); i < entriesSize; i++) { + JetTuplePatternEntry entry = entries.get(i); + JetType type = subjectType.getArguments().get(i).getType(); + + // TODO : is a name always allowed, ie for tuple patterns, not decomposer arg lists? + ASTNode nameLabelNode = entry.getNameLabelNode(); + if (nameLabelNode != null) { +// context.trace.getErrorHandler().genericError(nameLabelNode, "Unsupported [OperatorConventions]"); + context.trace.report(UNSUPPORTED.on(nameLabelNode, getClass().getCanonicalName())); + } + + JetPattern entryPattern = entry.getPattern(); + if (entryPattern != null) { + result[0] = result[0].and(checkPatternType(entryPattern, type, scopeToExtend, context)); + } + } + } + } + + @Override + public void visitDecomposerPattern(JetDecomposerPattern pattern) { + JetExpression decomposerExpression = pattern.getDecomposerExpression(); + if (decomposerExpression != null) { + ReceiverDescriptor receiver = new TransientReceiver(subjectType); + JetType selectorReturnType = facade.getSelectorReturnType(receiver, null, decomposerExpression, context); + + result[0] = checkPatternType(pattern.getArgumentList(), selectorReturnType == null ? ErrorUtils.createErrorType("No type") : selectorReturnType, scopeToExtend, context); + } + } + + @Override + public void visitWildcardPattern(JetWildcardPattern pattern) { + // Nothing + } + + @Override + public void visitExpressionPattern(JetExpressionPattern pattern) { + JetExpression expression = pattern.getExpression(); + if (expression != null) { + JetType type = facade.getType(expression, context.replaceScope(scopeToExtend)); + checkTypeCompatibility(type, subjectType, pattern); + } + } + + @Override + public void visitBindingPattern(JetBindingPattern pattern) { + JetProperty variableDeclaration = pattern.getVariableDeclaration(); + JetTypeReference propertyTypeRef = variableDeclaration.getPropertyTypeRef(); + JetType type = propertyTypeRef == null ? subjectType : context.getTypeResolver().resolveType(context.scope, propertyTypeRef); + VariableDescriptor variableDescriptor = context.getClassDescriptorResolver().resolveLocalVariableDescriptorWithType(context.scope.getContainingDeclaration(), variableDeclaration, type); + scopeToExtend.addVariableDescriptor(variableDescriptor); + if (propertyTypeRef != null) { + if (!context.semanticServices.getTypeChecker().isSubtypeOf(subjectType, type)) { +// context.trace.getErrorHandler().genericError(propertyTypeRef.getNode(), type + " must be a supertype of " + subjectType + ". Use 'is' to match against " + type); + context.trace.report(TYPE_MISMATCH_IN_BINDING_PATTERN.on(propertyTypeRef, type, subjectType)); + } + } + + JetWhenCondition condition = pattern.getCondition(); + if (condition != null) { + int oldLength = subjectVariables.length; + VariableDescriptor[] newSubjectVariables = new VariableDescriptor[oldLength + 1]; + System.arraycopy(subjectVariables, 0, newSubjectVariables, 0, oldLength); + newSubjectVariables[oldLength] = variableDescriptor; + result[0] = checkWhenCondition(null, subjectType, condition, scopeToExtend, context, newSubjectVariables); + } + } + + private void checkTypeCompatibility(@Nullable JetType type, @NotNull JetType subjectType, @NotNull JetElement reportErrorOn) { + // TODO : Take auto casts into account? + if (type == null) { + return; + } + if (TypeUtils.intersect(context.semanticServices.getTypeChecker(), Sets.newHashSet(type, subjectType)) == null) { +// context.trace.getErrorHandler().genericError(reportErrorOn.getNode(), "Incompatible types: " + type + " and " + subjectType); + context.trace.report(INCOMPATIBLE_TYPES.on(reportErrorOn, type, subjectType)); + } + } + + @Override + public void visitJetElement(JetElement element) { +// context.trace.getErrorHandler().genericError(element.getNode(), "Unsupported [OperatorConventions]"); + context.trace.report(UNSUPPORTED.on(element, getClass().getCanonicalName())); + } + }); + return result[0]; + } + +} diff --git a/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java b/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java index a6f4c57c81e..ef032cd7b37 100644 --- a/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java +++ b/idea/tests/org/jetbrains/jet/resolve/JetResolveTest.java @@ -12,13 +12,18 @@ import junit.framework.Test; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.JetTestCaseBase; import org.jetbrains.jet.lang.JetSemanticServices; -import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.resolve.BindingTraceContext; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; +import org.jetbrains.jet.lang.resolve.calls.CallResolver; +import org.jetbrains.jet.lang.resolve.calls.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.calls.ResolvedCall; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor; -import org.jetbrains.jet.lang.types.*; -import org.jetbrains.jet.lang.types.expressions.ExpressionTyperServices; +import org.jetbrains.jet.lang.types.JetStandardLibrary; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeProjection; import org.jetbrains.jet.parsing.JetParsingTest; import java.io.File; @@ -106,9 +111,10 @@ public class JetResolveTest extends ExtensibleResolveTestCase { @NotNull private FunctionDescriptor standardFunction(ClassDescriptor classDescriptor, List typeArguments, String name, JetType... parameterType) { List parameterTypeList = Arrays.asList(parameterType); - ExpressionTyperServices typeInferrerServices = JetSemanticServices.createSemanticServices(getProject()).getTypeInferrerServices(new BindingTraceContext()); +// ExpressionTypingServices typeInferrerServices = JetSemanticServices.createSemanticServices(getProject()).getTypeInferrerServices(new BindingTraceContext()); - OverloadResolutionResults functions = typeInferrerServices.getCallResolver().resolveExactSignature( + CallResolver callResolver = new CallResolver(JetSemanticServices.createSemanticServices(getProject()), DataFlowInfo.getEmpty()); + OverloadResolutionResults functions = callResolver.resolveExactSignature( classDescriptor.getMemberScope(typeArguments), ReceiverDescriptor.NO_RECEIVER, name, parameterTypeList); for (ResolvedCall resolvedCall : functions.getResults()) { List unsubstitutedValueParameters = resolvedCall.getResultingDescriptor().getValueParameters();