From 48847da5e6716cdc66d0d4ec355269cfb537d257 Mon Sep 17 00:00:00 2001 From: Rajveer Date: Tue, 28 Mar 2023 16:05:04 +0530 Subject: [PATCH] Added the expression cases of the form 'visit...Expr()' Part of Issue #61601 --- lib/AST/ASTPrinter.cpp | 264 ++++++++++++++++-- test/attr/accessibility_print.swift | 4 +- .../enum/derived_hashable_equatable.swift | 18 +- .../derived_hashable_equatable_macos.swift | 6 +- test/expr/print/conditions.swift | 20 ++ test/expr/print/func_closures.swift | 55 ++++ test/expr/print/misc_expr.swift | 140 ++++++++++ test/expr/print/protocol.swift | 4 +- 8 files changed, 478 insertions(+), 33 deletions(-) create mode 100644 test/expr/print/func_closures.swift create mode 100644 test/expr/print/misc_expr.swift diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 164672f7606c3..68e4673cc213b 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -809,7 +809,9 @@ class PrintAST : public ASTVisitor { if (D->getAttrs().hasAttribute() && !llvm::is_contained(Options.ExcludeAttrList, DAK_AccessControl)) return; - + if (D->getDeclContext()->isLocalContext()) + return; + printAccess(D->getFormalAccess()); bool shouldSkipSetterAccess = llvm::is_contained(Options.ExcludeAttrList, DAK_SetterAccess); @@ -933,6 +935,8 @@ class PrintAST : public ASTVisitor { void printTypedPattern(const TypedPattern *TP); void printBraceStmt(const BraceStmt *stmt, bool newlineIfEmpty = true); void printAccessorDecl(const AccessorDecl *decl); + void printKeyPathComponents(KeyPathExpr *expr, ArrayRef components); + void printClosure(AbstractClosureExpr *closure, CaptureListExpr *captureList); public: void printPattern(const Pattern *pattern); @@ -1010,6 +1014,8 @@ class PrintAST : public ASTVisitor { void printFunctionParameters(AbstractFunctionDecl *AFD); void printArgument(const Argument &arg); + + void printArgumentList(ArgumentList *args, bool forSubscript = false); void printStmtCondition(StmtCondition stmt); @@ -5330,7 +5336,9 @@ void PrintAST::visitPostfixOperatorDecl(PostfixOperatorDecl *decl) { }); } -void PrintAST::visitModuleDecl(ModuleDecl *decl) { } +void PrintAST::visitModuleDecl(ModuleDecl *decl) { + +} void PrintAST::visitMissingDecl(MissingDecl *missing) { Printer << "missing_decl"; @@ -5487,12 +5495,26 @@ void PrintAST::visitErrorExpr(ErrorExpr *expr) { Printer << ""; } -void PrintAST::visitTernaryExpr(TernaryExpr *expr) {} +void PrintAST::visitTernaryExpr(TernaryExpr *expr) { + if (auto condExpr = expr->getCondExpr()) { + visit(expr->getCondExpr()); + } + Printer << " ? "; + visit(expr->getThenExpr()); + Printer << " : "; + if (auto elseExpr = expr->getElseExpr()) { + visit(expr->getElseExpr()); + } +} void PrintAST::visitIsExpr(IsExpr *expr) { + visit(expr->getSubExpr()); + Printer << " is "; + printType(expr->getCastType()); } void PrintAST::visitTapExpr(TapExpr *expr) { + } void PrintAST::visitTryExpr(TryExpr *expr) { @@ -5502,18 +5524,7 @@ void PrintAST::visitTryExpr(TryExpr *expr) { void PrintAST::visitCallExpr(CallExpr *expr) { visit(expr->getFn()); - Printer << "("; - auto args = expr->getArgs()->getOriginalArgs(); - bool isFirst = true; - // FIXME: handle trailing closures. - for (auto arg : *args) { - if (!isFirst) { - Printer << ", "; - } - printArgument(arg); - isFirst = false; - } - Printer << ")"; + printArgumentList(expr->getArgs()->getOriginalArgs()); } void PrintAST::printArgument(const Argument &arg) { @@ -5528,6 +5539,16 @@ void PrintAST::printArgument(const Argument &arg) { visit(arg.getExpr()); } +void PrintAST::printArgumentList(ArgumentList *args, bool forSubscript) { + Printer << (!forSubscript ? "(" : "["); + llvm::interleave(args->begin(), args->end(), [&](Argument arg) { + printArgument(arg); + }, [&] { + Printer << ", "; + }); + Printer << (!forSubscript ? ")" : "]"); +} + void PrintAST::visitLoadExpr(LoadExpr *expr) { visit(expr->getSubExpr()); } @@ -5573,6 +5594,15 @@ void PrintAST::visitDictionaryExpr(DictionaryExpr *expr) { } void PrintAST::visitArrowExpr(ArrowExpr *expr) { + visit(expr->getArgsExpr()); + if (expr->getAsyncLoc().isValid()) { + Printer << " async"; + } + if (expr->getThrowsLoc().isValid()) { + Printer << " throws"; + } + Printer << " -> "; + visit(expr->getResultExpr()); } void PrintAST::visitAwaitExpr(AwaitExpr *expr) { @@ -5620,6 +5650,7 @@ void PrintAST::visitTupleExpr(TupleExpr *expr) { } void PrintAST::visitTypeJoinExpr(TypeJoinExpr *expr) { + llvm_unreachable("Not representable in source code"); } void PrintAST::visitAssignExpr(AssignExpr *expr) { @@ -5641,12 +5672,42 @@ void PrintAST::visitBinaryExpr(BinaryExpr *expr) { } void PrintAST::visitCoerceExpr(CoerceExpr *expr) { + visit(expr->getSubExpr()); + Printer << " as "; + printType(expr->getCastType()); } void PrintAST::visitOneWayExpr(OneWayExpr *expr) { + llvm_unreachable("Not representable in source code"); +} + +void PrintAST::printClosure(AbstractClosureExpr *closure, CaptureListExpr *captureList) { + } void PrintAST::visitClosureExpr(ClosureExpr *expr) { + Printer << "{ "; + if (auto parameters = expr->getParameters()) { + Printer << "("; + bool isFirst = true; + for (auto ¶meter: *parameters) { + if (!isFirst) { + Printer << ", "; + } + visit(parameter); + isFirst = false; + } + Printer << ") "; + if (expr->hasExplicitResultType()) { + Printer << "-> "; + printType(expr->getExplicitResultType()); + Printer << " "; + } + Printer << "in " << '\n'; + } + auto body = expr->getBody()->getElements(); + printASTNodes(body); + Printer << "\n}"; } void PrintAST::visitDeclRefExpr(DeclRefExpr *expr) { @@ -5662,7 +5723,80 @@ void PrintAST::visitErasureExpr(ErasureExpr *expr) { visit(expr->getSubExpr()); } +void PrintAST::printKeyPathComponents(KeyPathExpr *expr, ArrayRef components) { + using ComponentKind = KeyPathExpr::Component::Kind; + + if (!components.empty()) { + for (auto &component: components) { + auto kind = component.getKind(); + + switch (kind) { + case ComponentKind::Invalid: { + break; + } + case ComponentKind::UnresolvedProperty: { + Printer << component.getUnresolvedDeclName(); + break; + } + case ComponentKind::UnresolvedSubscript: { + auto args = component.getSubscriptArgs(); + printArgumentList(args, /*forSubscript*/ true); + break; + } + case ComponentKind::Property: { + Printer << component.getUnresolvedDeclName(); + break; + } + case ComponentKind::Subscript: { + auto args = component.getSubscriptArgs(); + printArgumentList(args, /*forSubscript*/ true); + break; + } + case ComponentKind::OptionalForce: { + Printer << "!"; + break; + } + case ComponentKind::OptionalChain: { + Printer << "?"; + break; + } + case ComponentKind::OptionalWrap: { + break; + } + case ComponentKind::Identity: { + Printer << "self"; + break; + } + case ComponentKind::TupleElement: { + Printer << component.getTupleIndex(); + break; + } + case ComponentKind::DictionaryKey: { + Printer << component.getUnresolvedDeclName(); + break; + } + case ComponentKind::CodeCompletion: { + break; + } + } + } + } else { + visit(expr->getParsedPath()); + } +} + void PrintAST::visitKeyPathExpr(KeyPathExpr *expr) { + // FIXME: The individual components are good, but printKeyPathComponents is not being called into for regular key paths, and missing the dots between components. + if (expr->isObjC()) { + Printer << "#keyPath("; + printKeyPathComponents(expr, expr->getComponents()); + Printer << ")"; + } else if (auto rootType = expr->getRootType()) { + Printer << "\\"; + printType(rootType); + } else { + visit(expr->getParsedRoot()); + } } void PrintAST::visitSingleValueStmtExpr(SingleValueStmtExpr *expr) { @@ -5675,9 +5809,16 @@ void PrintAST::visitForceTryExpr(ForceTryExpr *expr) { } void PrintAST::visitSequenceExpr(SequenceExpr *expr) { + auto elements = expr->getElements(); + llvm::interleave(elements, [&](Expr* element) { + visit(element); + }, [&] { + Printer << " "; + }); } void PrintAST::visitSuperRefExpr(SuperRefExpr *expr) { + Printer << "super"; } void PrintAST::visitMemberRefExpr(MemberRefExpr *expr) { @@ -5687,12 +5828,19 @@ void PrintAST::visitMemberRefExpr(MemberRefExpr *expr) { } void PrintAST::visitSubscriptExpr(SubscriptExpr *expr) { + visit(expr->getBase()); + printArgumentList(expr->getArgs()->getOriginalArgs(), /*forSubscript*/ true); } void PrintAST::visitEnumIsCaseExpr(EnumIsCaseExpr *expr) { + visit(expr->getSubExpr()); + Printer << " is "; + printTypeLoc(expr->getCaseTypeRepr()); } void PrintAST::visitForceValueExpr(ForceValueExpr *expr) { + visit(expr->getSubExpr()); + Printer << "!"; } void PrintAST::visitCurrentContextIsolationExpr( @@ -5702,6 +5850,7 @@ void PrintAST::visitCurrentContextIsolationExpr( } void PrintAST::visitKeyPathDotExpr(KeyPathDotExpr *expr) { + Printer << "."; } void PrintAST::visitAutoClosureExpr(AutoClosureExpr *expr) { @@ -5709,45 +5858,88 @@ void PrintAST::visitAutoClosureExpr(AutoClosureExpr *expr) { } void PrintAST::visitCaptureListExpr(CaptureListExpr *expr) { + // FIXME: This should be moved into `printClosure` and merged with the closure. + // Printing implementation. + auto captureList = expr->getCaptureList(); + Printer << "["; + auto isFirst = true; + for (auto &par: captureList) { + if (!isFirst) { + Printer << ", "; + } + printAttributes(par.getVar()); + Printer << par.getVar()->getName(); + for (auto init: par.PBD->initializers()) { + auto initName = init->getReferencedDecl().getDecl()->getName(); + if (initName != par.getVar()->getName()) + Printer << " = " << initName; + } + isFirst = false; + } + Printer << "]"; } void PrintAST::visitDynamicTypeExpr(DynamicTypeExpr *expr) { + Printer << "type(of: "; + visit(expr->getBase()); + Printer << ")"; } void PrintAST::visitOpaqueValueExpr(OpaqueValueExpr *expr) { } void PrintAST::visitOptionalTryExpr(OptionalTryExpr *expr) { + Printer << "try? "; + visit(expr->getSubExpr()); } void PrintAST::visitPrefixUnaryExpr(PrefixUnaryExpr *expr) { + visit(expr->getFn()); + visit(expr->getOperand()); } void PrintAST::visitBindOptionalExpr(BindOptionalExpr *expr) { + visit(expr->getSubExpr()); + Printer << "?"; } void PrintAST::visitBridgeToObjCExpr(BridgeToObjCExpr *expr) { } void PrintAST::visitObjCSelectorExpr(ObjCSelectorExpr *expr) { + Printer << "#selector"; + Printer << "("; + visit(expr->getSubExpr()); + Printer << ")"; } void PrintAST::visitPostfixUnaryExpr(PostfixUnaryExpr *expr) { + visit(expr->getOperand()); + visit(expr->getFn()); } void PrintAST::visitTupleElementExpr(TupleElementExpr *expr) { + visit(expr->getBase()); + Printer << "."; + Printer << expr->getFieldNumber(); } void PrintAST::visitDerivedToBaseExpr(DerivedToBaseExpr *expr) { } void PrintAST::visitDotSyntaxCallExpr(DotSyntaxCallExpr *expr) { - visit(expr->getBase()); - Printer << "."; + auto decl = expr->getFn()->getReferencedDecl().getDecl(); + if (!decl || !decl->isOperator()) { + visit(expr->getBase()); + Printer << "."; + } visit(expr->getFn()); } void PrintAST::visitObjectLiteralExpr(ObjectLiteralExpr *expr) { + Printer << "#"; + Printer << expr->getLiteralKindRawName(); + printArgumentList(expr->getArgs()); } void PrintAST::visitUnresolvedDotExpr(UnresolvedDotExpr *expr) { @@ -5813,9 +6005,14 @@ void PrintAST::visitDestructureTupleExpr(DestructureTupleExpr *expr) { } void PrintAST::visitDynamicMemberRefExpr(DynamicMemberRefExpr *expr) { + visit(expr->getBase()); + Printer << "."; + Printer << expr->getMember().getDecl()->getName(); } void PrintAST::visitDynamicSubscriptExpr(DynamicSubscriptExpr *expr) { + visit(expr->getBase()); + printArgumentList(expr->getArgs()->getOriginalArgs(), /*forSubscript*/ true); } void PrintAST::visitPointerToPointerExpr(PointerToPointerExpr *expr) { @@ -5823,6 +6020,8 @@ void PrintAST::visitPointerToPointerExpr(PointerToPointerExpr *expr) { } void PrintAST::visitUnresolvedMemberExpr(UnresolvedMemberExpr *expr) { + Printer << "."; + Printer << expr->getName(); } void PrintAST::visitDiscardAssignmentExpr(DiscardAssignmentExpr *expr) { @@ -5830,6 +6029,7 @@ void PrintAST::visitDiscardAssignmentExpr(DiscardAssignmentExpr *expr) { } void PrintAST::visitEditorPlaceholderExpr(EditorPlaceholderExpr *expr) { + Printer << expr->getPlaceholder(); } void PrintAST::visitForcedCheckedCastExpr(ForcedCheckedCastExpr *expr) { @@ -5845,12 +6045,19 @@ void PrintAST::visitConditionalCheckedCastExpr(ConditionalCheckedCastExpr *expr) } void PrintAST::visitOverloadedDeclRefExpr(OverloadedDeclRefExpr *expr) { + if (expr->getNameLoc().isCompound()) { + Printer << expr->getDecls().front()->getName(); + } else { + Printer << expr->getDecls().front()->getBaseName(); + } } void PrintAST::visitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *expr) { + Printer << expr->getName(); } void PrintAST::visitUnresolvedPatternExpr(UnresolvedPatternExpr *expr) { + printPattern(expr->getSubPattern()); } void PrintAST::visitAnyHashableErasureExpr(AnyHashableErasureExpr *expr) { @@ -5875,6 +6082,10 @@ void PrintAST::visitInjectIntoOptionalExpr(InjectIntoOptionalExpr *expr) { } void PrintAST::visitKeyPathApplicationExpr(KeyPathApplicationExpr *expr) { + visit(expr->getBase()); + Printer << "[keyPath: "; + visit(expr->getKeyPath()); + Printer << "]"; } void PrintAST::visitMetatypeConversionExpr(MetatypeConversionExpr *expr) { @@ -5894,6 +6105,9 @@ void PrintAST::visitUnevaluatedInstanceExpr(UnevaluatedInstanceExpr *expr) { } void PrintAST::visitDotSyntaxBaseIgnoredExpr(DotSyntaxBaseIgnoredExpr *expr) { + visit(expr->getLHS()); + Printer << "."; + visit(expr->getRHS()); } void PrintAST::visitUnresolvedSpecializeExpr(UnresolvedSpecializeExpr *expr) { @@ -5912,18 +6126,22 @@ void PrintAST::visitDifferentiableFunctionExpr(DifferentiableFunctionExpr *expr) } void PrintAST::visitMagicIdentifierLiteralExpr(MagicIdentifierLiteralExpr *expr) { + Printer << expr->getKindString(expr->getKind()); } void PrintAST::visitForeignObjectConversionExpr(ForeignObjectConversionExpr *expr) { } void PrintAST::visitOtherConstructorDeclRefExpr(OtherConstructorDeclRefExpr *expr) { + Printer << "init"; } void PrintAST::visitRebindSelfInConstructorExpr(RebindSelfInConstructorExpr *expr) { + visit(expr->getSubExpr()); } void PrintAST::visitMakeTemporarilyEscapableExpr(MakeTemporarilyEscapableExpr *expr) { + visit(expr->getOriginalExpr()); } void PrintAST::visitProtocolMetatypeToObjectExpr(ProtocolMetatypeToObjectExpr *expr) { @@ -5939,6 +6157,7 @@ void PrintAST::visitCovariantReturnConversionExpr(CovariantReturnConversionExpr } void PrintAST::visitInterpolatedStringLiteralExpr(InterpolatedStringLiteralExpr *expr) { + visit(expr->getInterpolationExpr()); } void PrintAST::visitCollectionUpcastConversionExpr(CollectionUpcastConversionExpr *expr) { @@ -6106,6 +6325,17 @@ void PrintAST::visitForEachStmt(ForEachStmt *stmt) { printPattern(stmt->getPattern()); Printer << " " << tok::kw_in << " "; // FIXME: print container + if (auto *seq = stmt->getTypeCheckedSequence()) { + // Look through the call to '.makeIterator()' + + if (auto *CE = dyn_cast(seq)) { + if (auto *SAE = dyn_cast(CE->getFn())) + seq = SAE->getBase(); + } + visit(seq); + } else { + visit(stmt->getParsedSequence()); + } Printer << " "; visit(stmt->getBody()); } diff --git a/test/attr/accessibility_print.swift b/test/attr/accessibility_print.swift index 00a5c2e1e3845..c4ac2b916e1bd 100644 --- a/test/attr/accessibility_print.swift +++ b/test/attr/accessibility_print.swift @@ -211,14 +211,14 @@ public extension FE_PublicClass { // CHECK-LABEL: internal func GA_localTypes() func GA_localTypes() { - // CHECK-SRC: private struct Local { + // CHECK-SRC: struct Local { struct Local { // CHECK-SRC: internal let x let x = 0 } _ = Local() - // CHECK-SRC: private enum LocalEnum { + // CHECK-SRC: enum LocalEnum { enum LocalEnum { // CHECK-SRC: {{^}} case A case A, B diff --git a/test/decl/enum/derived_hashable_equatable.swift b/test/decl/enum/derived_hashable_equatable.swift index f40d5d6bfe2cc..fa65da30f213b 100644 --- a/test/decl/enum/derived_hashable_equatable.swift +++ b/test/decl/enum/derived_hashable_equatable.swift @@ -8,14 +8,14 @@ enum Simple: Hashable { case b // CHECK: @_implements(Equatable, ==(_:_:)) internal static func __derived_enum_equals(_ a: Simple, _ b: Simple) -> Bool { - // CHECK-NEXT: private var index_a: Int + // CHECK-NEXT: var index_a: Int // CHECK-NEXT: switch a { // CHECK-NEXT: case .a: // CHECK-NEXT: index_a = 0 // CHECK-NEXT: case .b: // CHECK-NEXT: index_a = 1 // CHECK-NEXT: } - // CHECK-NEXT: private var index_b: Int + // CHECK-NEXT: var index_b: Int // CHECK-NEXT: switch b { // CHECK-NEXT: case .a: // CHECK-NEXT: index_b = 0 @@ -26,7 +26,7 @@ enum Simple: Hashable { // CHECK-NEXT: } // CHECK: internal func hash(into hasher: inout Hasher) { - // CHECK-NEXT: private var discriminator: Int + // CHECK-NEXT: var discriminator: Int // CHECK-NEXT: switch self { // CHECK-NEXT: case .a: // CHECK-NEXT: discriminator = 0 @@ -101,14 +101,14 @@ enum HasUnavailableElement: Hashable { case b // CHECK: @_implements(Equatable, ==(_:_:)) internal static func __derived_enum_equals(_ a: HasUnavailableElement, _ b: HasUnavailableElement) -> Bool { - // CHECK-NEXT: private var index_a: Int + // CHECK-NEXT: var index_a: Int // CHECK-NEXT: switch a { // CHECK-NEXT: case .a: // CHECK-NEXT: index_a = 0 // CHECK-NEXT: case .b: // CHECK-NEXT: _diagnoseUnavailableCodeReached{{.*}}() // CHECK-NEXT: } - // CHECK-NEXT: private var index_b: Int + // CHECK-NEXT: var index_b: Int // CHECK-NEXT: switch b { // CHECK-NEXT: case .a: // CHECK-NEXT: index_b = 0 @@ -119,7 +119,7 @@ enum HasUnavailableElement: Hashable { // CHECK-NEXT: } // CHECK: internal func hash(into hasher: inout Hasher) { - // CHECK-NEXT: private var discriminator: Int + // CHECK-NEXT: var discriminator: Int // CHECK-NEXT: switch self { // CHECK-NEXT: case .a: // CHECK-NEXT: discriminator = 0 @@ -185,14 +185,14 @@ enum UnavailableEnum: Hashable { case b // CHECK: @_implements(Equatable, ==(_:_:)) internal static func __derived_enum_equals(_ a: UnavailableEnum, _ b: UnavailableEnum) -> Bool { - // CHECK-NEXT: private var index_a: Int + // CHECK-NEXT: var index_a: Int // CHECK-NEXT: switch a { // CHECK-NEXT: case .a: // CHECK-NEXT: index_a = 0 // CHECK-NEXT: case .b: // CHECK-NEXT: index_a = 1 // CHECK-NEXT: } - // CHECK-NEXT: private var index_b: Int + // CHECK-NEXT: var index_b: Int // CHECK-NEXT: switch b { // CHECK-NEXT: case .a: // CHECK-NEXT: index_b = 0 @@ -203,7 +203,7 @@ enum UnavailableEnum: Hashable { // CHECK-NEXT: } // CHECK: internal func hash(into hasher: inout Hasher) { - // CHECK-NEXT: private var discriminator: Int + // CHECK-NEXT: var discriminator: Int // CHECK-NEXT: switch self { // CHECK-NEXT: case .a: // CHECK-NEXT: discriminator = 0 diff --git a/test/decl/enum/derived_hashable_equatable_macos.swift b/test/decl/enum/derived_hashable_equatable_macos.swift index 0189ca335ac28..307355570cff0 100644 --- a/test/decl/enum/derived_hashable_equatable_macos.swift +++ b/test/decl/enum/derived_hashable_equatable_macos.swift @@ -25,7 +25,7 @@ enum HasElementsWithAvailability: Hashable { case introduced10_50 // CHECK: @_implements(Equatable, ==(_:_:)) internal static func __derived_enum_equals(_ a: HasElementsWithAvailability, _ b: HasElementsWithAvailability) -> Bool { - // CHECK-NEXT: private var index_a: Int + // CHECK-NEXT: var index_a: Int // CHECK-NEXT: switch a { // CHECK-NEXT: case .alwaysAvailable: // CHECK-NEXT: index_a = 0 @@ -40,7 +40,7 @@ enum HasElementsWithAvailability: Hashable { // CHECK-NEXT: case .introduced10_50: // CHECK-NEXT: index_a = 2 // CHECK-NEXT: } - // CHECK-NEXT: private var index_b: Int + // CHECK-NEXT: var index_b: Int // CHECK-NEXT: switch b { // CHECK-NEXT: case .alwaysAvailable: // CHECK-NEXT: index_b = 0 @@ -59,7 +59,7 @@ enum HasElementsWithAvailability: Hashable { // CHECK-NEXT: } // CHECK: internal func hash(into hasher: inout Hasher) { - // CHECK-NEXT: private var discriminator: Int + // CHECK-NEXT: var discriminator: Int // CHECK-NEXT: switch self { // CHECK-NEXT: case .alwaysAvailable: // CHECK-NEXT: discriminator = 0 diff --git a/test/expr/print/conditions.swift b/test/expr/print/conditions.swift index 8352e0aae68e0..d9c446a1ec6de 100644 --- a/test/expr/print/conditions.swift +++ b/test/expr/print/conditions.swift @@ -36,3 +36,23 @@ repeat { // CHECK: repeat { // CHECK: b += 1 // CHECK: } while b < 10 + +var p = (17 > 7 ? true : false) +// CHECK: @_hasInitialValue internal var p: (Bool) = (17 > 7 ? true : false) + +var x: Int = 3 +var y: Bool = x is Int +// CHECK: @_hasInitialValue internal var y: Bool = x is Int + +enum SomeError: Error { + case errorType +} + +func someThrowingFunc() throws -> SomeError { + throw SomeError.errorType +} + +var tryExpr = try? someThrowingFunc() +// CHECK: @_hasInitialValue internal var tryExpr: SomeError? = try? someThrowingFunc() + +var tryForceExpr = try! someThrowingFunc() diff --git a/test/expr/print/func_closures.swift b/test/expr/print/func_closures.swift new file mode 100644 index 0000000000000..67dbe84575a65 --- /dev/null +++ b/test/expr/print/func_closures.swift @@ -0,0 +1,55 @@ +// RUN: %target-swift-frontend -print-ast -disable-availability-checking %s 2>&1 | %FileCheck %s + +func fetch() async throws -> String { +} +// CHECK: internal func fetch() async throws -> String { +// CHECK: } + +let fn = { (x: Int) in +} +// CHECK: @_hasInitialValue internal let fn: (_ x: Int) -> () = { (x: Int) in +// CHECK: } + +let fn1 = {} +// CHECK: @_hasInitialValue internal let fn1: () -> () = { () in +// CHECK: } + +let fn2: (Int) -> Void = { x in } +// CHECK: @_hasInitialValue internal let fn2: (Int) -> Void = { (x: Int) in +// CHECK: } + +let fn3: (Int, Int) -> Void = { x, y in } +// CHECK: @_hasInitialValue internal let fn3: (Int, Int) -> Void = { (x: Int, y: Int) in +// CHECK: } + +let fn4: (Int, Int) -> Void = { (x, y) in } +// CHECK: @_hasInitialValue internal let fn4: (Int, Int) -> Void = { (x: Int, y: Int) in +// CHECK: } + +let fn5 = { (x: String, y: Int) in } +// CHECK: @_hasInitialValue internal let fn5: (_ x: String, _ y: Int) -> () = { (x: String, y: Int) in +// CHECK: } + +let fn6: (Int) -> Int = { x -> Int in x } +// CHECK: @_hasInitialValue internal let fn6: (Int) -> Int = { (x: Int) -> Int in +// CHECK: return x +// CHECK: } + +let fn7: (Int, Int) -> Int = { (x, y) -> Int in x + y } +// CHECK: @_hasInitialValue internal let fn7: (Int, Int) -> Int = { (x: Int, y: Int) -> Int in +// CHECK: return x + y +// CHECK: } + +let fn8 = { (x: Int, y: Int) -> Int in x + y } +// CHECK: @_hasInitialValue internal let fn8: (_ x: Int, _ y: Int) -> Int = { (x: Int, y: Int) -> Int in +// CHECK: return x + y +// CHECK: } + +let fn9 = { () -> Int in 0 } +// CHECK: @_hasInitialValue internal let fn9: () -> Int = { () -> Int in +// CHECK: return 0 +// CHECK: } + +let fn10 = { () in } +// CHECK: @_hasInitialValue internal let fn10: () -> () = { () in +// CHECK: } diff --git a/test/expr/print/misc_expr.swift b/test/expr/print/misc_expr.swift new file mode 100644 index 0000000000000..af60225686d9e --- /dev/null +++ b/test/expr/print/misc_expr.swift @@ -0,0 +1,140 @@ +// RUN: %target-swift-frontend -print-ast -disable-objc-attr-requires-foundation-module -enable-objc-interop %s 2>&1 | %FileCheck %s + +var x = 0.0 + +type(of: x) +// CHECK: type(of: x) + +class A { + var x: Int = 3 + init() { + } +} + +class B: A { + override init() { + super.init() + super.x = 2; + } +} +// CHECK: @_inheritsConvenienceInitializers internal class B : A { +// CHECK: override internal init() { +// CHECK: super.init() +// CHECK: super.x = 2 +// CHECK: } +// CHECK: @objc deinit { +// CHECK: } +// CHECK: } + +var a: [Int] = [1, 3, 2]; + +for i in 0...2 { + a[i] = i; +} +// CHECK: for i in 0 ... 2 { +// CHECK: a[i] = i +// CHECK: } + +let y: Double = 0 as Double +// CHECK: @_hasInitialValue internal let y: Double = 0 as Double + +var stringToInt: Int? = Int("1"); + +var forceInt: Int = stringToInt! +// CHECK: @_hasInitialValue internal var forceInt: Int = stringToInt! + +var prefixUnaryExpr: Int = -a[1]; +// CHECK: @_hasInitialValue internal var prefixUnaryExpr: Int = -a[1] +var postfixUnaryExpr: Int = stringToInt! +// CHECK: @_hasInitialValue internal var postfixUnaryExpr: Int = stringToInt! + +class MyID { + var num = 1 +} + +class SomeJSON { + var id: MyID? +} + +let cnt = SomeJSON().id?.num +// CHECK: @_hasInitialValue internal let cnt: Int? = SomeJSON().id?.num + +struct User { + let name: String + let email: String + let address: Address? + let role: Role +} + +struct Address { + let street: String +} + +enum Role { + case admin + case member + case guest + + var permissions: [Permission] { + switch self { + case .admin: + return [.create, .read, .update, .delete] + case .member: + return [.create, .read] + case .guest: + return [.read] + } + } +} + +enum Permission { + case create + case read + case update + case delete +} + +var user = User( + name: "Swift", + email: "http://www.swift.org", + address: nil, + role: .admin +) + + +let userRoleKeyPath = \User.role +// CHECK: @_hasInitialValue internal let userRoleKeyPath: KeyPath = \User + +let role = user[keyPath: userRoleKeyPath] +// CHECK: @_hasInitialValue internal let role: Role = user[keyPath: userRoleKeyPath] + +struct FakeColor: _ExpressibleByColorLiteral { + init(_colorLiteralRed: Float, green: Float, blue: Float, alpha: Float) {} +} +typealias _ColorLiteralType = FakeColor + +let myColor = #colorLiteral(red: 0.292, green: 0.081, blue: 0.6, alpha: 255) +// CHECK: @_hasInitialValue internal let myColor: FakeColor = #colorLiteral(red: 0.292, green: 0.081, blue: 0.6, alpha: 255) + +enum FileNames { + static let main = FileNames.file(#file) +// CHECK: @_hasInitialValue internal static let main: FileNames = FileNames.file(#file) + case file(String) +} + +class C { + @objc + var foo = 0 +} + +func foo(_ x: AnyObject) { + let y = x.foo +} +// CHECK: internal func foo(_ x: AnyObject) { +// CHECK: @_hasInitialValue let y: Int? = x.foo +// CHECK: } + +struct S { + func foo() {} +} +let fn = S.foo diff --git a/test/expr/print/protocol.swift b/test/expr/print/protocol.swift index 53564113ee864..77816f3fbe686 100644 --- a/test/expr/print/protocol.swift +++ b/test/expr/print/protocol.swift @@ -19,6 +19,6 @@ func cast(_ a: Any) { let forced = a as! Archivable } // CHECK: internal func cast(_ a: Any) { -// CHECK: @_hasInitialValue private let conditional: (any Archivable)? = a as? any Archivable -// CHECK: @_hasInitialValue private let forced: any Archivable = a as! any Archivable +// CHECK: @_hasInitialValue let conditional: (any Archivable)? = a as? any Archivable +// CHECK: @_hasInitialValue let forced: any Archivable = a as! any Archivable // CHECK: }