mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
* [CodeCompletion] Restrict ancestor search to brace
This change allows ExprParentFinder to restrict certain searches for parents to just AST nodes within the nearest surrounding BraceStmt. In the string interpolation rework, BraceStmts can appear in new places in the AST; this keeps code completion from looking at irrelevant context.
NFC in this commit, but keeps code completion from crashing once TapExpr is introduced.
* Remove test relying on ExpressibleByStringInterpolation being deprecated
Since soon enough, it won’t be anymore.
* [AST] Introduce TapExpr
TapExpr allows a block of code to to be inserted between two expressions, accessing and potentially mutating the result of its subexpression before giving it to its parent expression. It’s roughly equivalent to this function:
func _tap<T>(_ value: T, do body: (inout T) throws -> Void) rethrows -> T {
var copy = value
try body(©)
return copy
}
Except that it doesn’t use a closure, so no variables are captured and no call frame is (even notionally) added.
This commit does not include tests because nothing in it actually uses TapExpr yet. It will be used by string interpolation.
* SE-0228: Fix ExpressibleByStringInterpolation
This is the bulk of the implementation of the string interpolation rework. It includes a redesigned AST node, new parsing logic, new constraints and post-typechecking code generation, and new standard library types and members.
* [Sema] Rip out typeCheckExpressionShallow()
With new string interpolation in place, it is no longer used by anything in the compiler.
* [Sema] Diagnose invalid StringInterpolationProtocols
StringInterpolationProtocol informally requires conforming types to provide at least one method with the base name “appendInterpolation” with no (or a discardable) return value and visibility at least as broad as the conforming type’s. This change diagnoses an error when a conforming type does not have a method that meets those criteria.
* [Stdlib] Fix map(String.init) source break
Some users, including some in the source compatibility suite, accidentally used init(stringInterpolationSegment:) by writing code like `map(String.init)`. Now that these intializers have been removed, the remaining initializers often end up tying during overload resolution. This change adds several overloads of `String.init(describing:)` which will break these ties in cases where the compiler previously selected `String.init(stringInterpolationSegment:)`.
* [Sema] Make callWitness() take non-mutable arrays
It doesn’t actually need to mutate them.
* [Stdlib] Improve floating-point interpolation performance
This change avoids constructing a String when interpolating a Float, Double, or Float80. Instead, we write the characters to a fixed-size buffer and then append them directly to the string’s storage.
This seems to improve performance for all three types, but especially for Double and Float80, which cannot always fit into a small string when stringified.
* [NameLookup] Improve MemberLookupTable invalidation
In rare cases usually involving generated code, an overload added by an extension in the middle of a file would not be visible below it if the type had lazy members and the same base name had already been referenced above the extension. This change essentially dirties a type’s member lookup table whenever an extension is added to it, ensuring the entries in it will be updated.
This change also includes some debugging improvements for NameLookup.
* [SILOptimizer] XFAIL dead object removal failure
The DeadObjectRemoval pass in SILOptimizer does not currently remove reworked string interpolations as well as the old design because their effects cannot be described by @_effects(readonly). That causes a test failure on Linux. This change temporarily silences that test. The SILOptimizer issue has been filed as SR-9008.
* Confess string interpolation’s source stability sins
* [Parser] Parse empty interpolations
Previously, the parser had an odd asymmetry which caused the same function to accept foo(), but reject “\()”. This change fixes the issue.
Already tested by test/Parse/try.swift, which uses this construct in one of its throwing interpolation tests.
* [Sema] Fix batch-mode-only lazy var bug
The temporary variable used by string interpolation needs to be recontextualized when it’s inserted into a synthesized getter. Fixes a compilation failure in Alamofire.
I’ll probably follow up on this bug a bit more after merging.
201 lines
7.1 KiB
C++
201 lines
7.1 KiB
C++
//===--- ExprNodes.def - Swift Expression AST Metaprogramming ---*- C++ -*-===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines macros used for macro-metaprogramming with expressions.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
/// EXPR(Id, Parent)
|
|
/// If the expression node is not abstract, its enumerator value is
|
|
/// ExprKind::Id. The node's class name is Id##Expr, and the name of
|
|
/// its base class (in the Expr hierarchy) is Parent.
|
|
#ifndef EXPR
|
|
#define EXPR(Id, Parent)
|
|
#endif
|
|
|
|
/// An abstract expression node is an abstract base class in the hierarchy;
|
|
/// it is never a most-derived type, and it does not have an enumerator in
|
|
/// ExprKind.
|
|
///
|
|
/// Most metaprograms do not care about abstract expressions, so the default
|
|
/// is to ignore them.
|
|
#ifndef ABSTRACT_EXPR
|
|
#define ABSTRACT_EXPR(Id, Parent)
|
|
#endif
|
|
|
|
/// An "unchecked" expression node is removed from valid code by the end
|
|
/// of the type-checking phase.
|
|
///
|
|
/// By default, these are treated like any other expression.
|
|
#ifndef UNCHECKED_EXPR
|
|
#define UNCHECKED_EXPR(Id, Parent) EXPR(Id, Parent)
|
|
#endif
|
|
|
|
/// A literal expression node represents a literal value, such as a number,
|
|
/// boolean, string, etc.
|
|
///
|
|
/// By default, these are treated like any other expression.
|
|
#ifndef LITERAL_EXPR
|
|
#define LITERAL_EXPR(Id, Parent) EXPR(Id, Parent)
|
|
#endif
|
|
|
|
/// A expression node with a DeclContext. For example: closures.
|
|
///
|
|
/// By default, these are treated like any other expression.
|
|
#ifndef CONTEXT_EXPR
|
|
#define CONTEXT_EXPR(Id, Parent) EXPR(Id, Parent)
|
|
#endif
|
|
|
|
/// A convenience for determining the range of expressions. These will always
|
|
/// appear immediately after the last member.
|
|
#ifndef EXPR_RANGE
|
|
#define EXPR_RANGE(Id, First, Last)
|
|
#endif
|
|
|
|
#ifndef LAST_EXPR
|
|
#define LAST_EXPR(Id)
|
|
#endif
|
|
|
|
EXPR(Error, Expr)
|
|
ABSTRACT_EXPR(Literal, Expr)
|
|
LITERAL_EXPR(NilLiteral, LiteralExpr)
|
|
ABSTRACT_EXPR(NumberLiteral, LiteralExpr)
|
|
LITERAL_EXPR(IntegerLiteral, NumberLiteralExpr)
|
|
LITERAL_EXPR(FloatLiteral, NumberLiteralExpr)
|
|
EXPR_RANGE(NumberLiteral, IntegerLiteral, FloatLiteral)
|
|
LITERAL_EXPR(BooleanLiteral, LiteralExpr)
|
|
LITERAL_EXPR(StringLiteral, LiteralExpr)
|
|
LITERAL_EXPR(InterpolatedStringLiteral, LiteralExpr)
|
|
LITERAL_EXPR(ObjectLiteral, LiteralExpr)
|
|
LITERAL_EXPR(MagicIdentifierLiteral, LiteralExpr)
|
|
EXPR_RANGE(Literal, NilLiteral, MagicIdentifierLiteral)
|
|
EXPR(DiscardAssignment, Expr)
|
|
EXPR(DeclRef, Expr)
|
|
EXPR(SuperRef, Expr)
|
|
EXPR(Type, Expr)
|
|
EXPR(OtherConstructorDeclRef, Expr)
|
|
EXPR(DotSyntaxBaseIgnored, Expr)
|
|
ABSTRACT_EXPR(OverloadSetRef, Expr)
|
|
UNCHECKED_EXPR(OverloadedDeclRef, OverloadSetRefExpr)
|
|
EXPR_RANGE(OverloadSetRef, OverloadedDeclRef, OverloadedDeclRef)
|
|
UNCHECKED_EXPR(UnresolvedDeclRef, Expr)
|
|
ABSTRACT_EXPR(Lookup, Expr)
|
|
EXPR(MemberRef, LookupExpr)
|
|
EXPR(Subscript, LookupExpr)
|
|
ABSTRACT_EXPR(DynamicLookup, LookupExpr)
|
|
EXPR(DynamicMemberRef, DynamicLookupExpr)
|
|
EXPR(DynamicSubscript, DynamicLookupExpr)
|
|
EXPR_RANGE(DynamicLookup, DynamicMemberRef, DynamicSubscript)
|
|
EXPR_RANGE(Lookup, MemberRef, DynamicSubscript)
|
|
UNCHECKED_EXPR(UnresolvedSpecialize, Expr)
|
|
UNCHECKED_EXPR(UnresolvedMember, Expr)
|
|
UNCHECKED_EXPR(UnresolvedDot, Expr)
|
|
UNCHECKED_EXPR(Sequence, Expr)
|
|
ABSTRACT_EXPR(Identity, Expr)
|
|
EXPR(Paren, IdentityExpr)
|
|
EXPR(DotSelf, IdentityExpr)
|
|
EXPR_RANGE(Identity, Paren, DotSelf)
|
|
ABSTRACT_EXPR(AnyTry, Expr)
|
|
EXPR(Try, AnyTryExpr)
|
|
EXPR(ForceTry, AnyTryExpr)
|
|
EXPR(OptionalTry, AnyTryExpr)
|
|
EXPR_RANGE(AnyTry, Try, OptionalTry)
|
|
EXPR(Tuple, Expr)
|
|
ABSTRACT_EXPR(Collection, Expr)
|
|
EXPR(Array, CollectionExpr)
|
|
EXPR(Dictionary, CollectionExpr)
|
|
EXPR_RANGE(Collection, Array, Dictionary)
|
|
EXPR(KeyPathApplication, Expr)
|
|
EXPR(TupleElement, Expr)
|
|
EXPR(CaptureList, Expr)
|
|
ABSTRACT_EXPR(AbstractClosure, Expr)
|
|
CONTEXT_EXPR(Closure, AbstractClosureExpr)
|
|
CONTEXT_EXPR(AutoClosure, AbstractClosureExpr)
|
|
EXPR_RANGE(AbstractClosure, Closure, AutoClosure)
|
|
EXPR(InOut, Expr)
|
|
EXPR(VarargExpansion, Expr)
|
|
EXPR(DynamicType, Expr)
|
|
EXPR(RebindSelfInConstructor, Expr)
|
|
EXPR(OpaqueValue, Expr)
|
|
EXPR(BindOptional, Expr)
|
|
EXPR(OptionalEvaluation, Expr)
|
|
EXPR(ForceValue, Expr)
|
|
EXPR(OpenExistential, Expr)
|
|
EXPR(MakeTemporarilyEscapable, Expr)
|
|
ABSTRACT_EXPR(Apply, Expr)
|
|
EXPR(Call, ApplyExpr)
|
|
EXPR(PrefixUnary, ApplyExpr)
|
|
EXPR(PostfixUnary, ApplyExpr)
|
|
EXPR(Binary, ApplyExpr)
|
|
ABSTRACT_EXPR(SelfApply, ApplyExpr)
|
|
EXPR(DotSyntaxCall, SelfApplyExpr)
|
|
EXPR(ConstructorRefCall, SelfApplyExpr)
|
|
EXPR_RANGE(SelfApply, DotSyntaxCall, ConstructorRefCall)
|
|
EXPR_RANGE(Apply, Call, ConstructorRefCall)
|
|
ABSTRACT_EXPR(ImplicitConversion, Expr)
|
|
EXPR(Load, ImplicitConversionExpr)
|
|
EXPR(TupleShuffle, ImplicitConversionExpr)
|
|
EXPR(UnresolvedTypeConversion, ImplicitConversionExpr)
|
|
EXPR(FunctionConversion, ImplicitConversionExpr)
|
|
EXPR(CovariantFunctionConversion, ImplicitConversionExpr)
|
|
EXPR(CovariantReturnConversion, ImplicitConversionExpr)
|
|
EXPR(ImplicitlyUnwrappedFunctionConversion, ImplicitConversionExpr)
|
|
EXPR(MetatypeConversion, ImplicitConversionExpr)
|
|
EXPR(CollectionUpcastConversion, ImplicitConversionExpr)
|
|
EXPR(Erasure, ImplicitConversionExpr)
|
|
EXPR(AnyHashableErasure, ImplicitConversionExpr)
|
|
EXPR(BridgeToObjC, ImplicitConversionExpr)
|
|
EXPR(BridgeFromObjC, ImplicitConversionExpr)
|
|
EXPR(ConditionalBridgeFromObjC, ImplicitConversionExpr)
|
|
EXPR(DerivedToBase, ImplicitConversionExpr)
|
|
EXPR(ArchetypeToSuper, ImplicitConversionExpr)
|
|
EXPR(InjectIntoOptional, ImplicitConversionExpr)
|
|
EXPR(ClassMetatypeToObject, ImplicitConversionExpr)
|
|
EXPR(ExistentialMetatypeToObject, ImplicitConversionExpr)
|
|
EXPR(ProtocolMetatypeToObject, ImplicitConversionExpr)
|
|
EXPR(InOutToPointer, ImplicitConversionExpr)
|
|
EXPR(ArrayToPointer, ImplicitConversionExpr)
|
|
EXPR(StringToPointer, ImplicitConversionExpr)
|
|
EXPR(PointerToPointer, ImplicitConversionExpr)
|
|
EXPR(ForeignObjectConversion, ImplicitConversionExpr)
|
|
EXPR(UnevaluatedInstance, ImplicitConversionExpr)
|
|
EXPR_RANGE(ImplicitConversion, Load, UnevaluatedInstance)
|
|
ABSTRACT_EXPR(ExplicitCast, Expr)
|
|
ABSTRACT_EXPR(CheckedCast, ExplicitCastExpr)
|
|
EXPR(ForcedCheckedCast, CheckedCastExpr)
|
|
EXPR(ConditionalCheckedCast, CheckedCastExpr)
|
|
EXPR(Is, CheckedCastExpr)
|
|
EXPR_RANGE(CheckedCast, ForcedCheckedCast, Is)
|
|
EXPR(Coerce, ExplicitCastExpr)
|
|
EXPR_RANGE(ExplicitCast, ForcedCheckedCast, Coerce)
|
|
UNCHECKED_EXPR(Arrow, Expr)
|
|
EXPR(If, Expr)
|
|
EXPR(EnumIsCase, Expr)
|
|
EXPR(Assign, Expr)
|
|
EXPR(CodeCompletion, Expr)
|
|
UNCHECKED_EXPR(UnresolvedPattern, Expr)
|
|
EXPR(LazyInitializer, Expr)
|
|
EXPR(EditorPlaceholder, Expr)
|
|
EXPR(ObjCSelector, Expr)
|
|
EXPR(KeyPath, Expr)
|
|
UNCHECKED_EXPR(KeyPathDot, Expr)
|
|
EXPR(Tap, Expr)
|
|
LAST_EXPR(Tap)
|
|
|
|
#undef EXPR_RANGE
|
|
#undef LITERAL_EXPR
|
|
#undef UNCHECKED_EXPR
|
|
#undef ABSTRACT_EXPR
|
|
#undef CONTEXT_EXPR
|
|
#undef EXPR
|
|
#undef LAST_EXPR
|