Merge pull request #16929 from nathawes/add-api-diff-data-dir-option-for-migrator-testing-4.2
[4.2][migrator] Add -api-diff-data-dir option to override the default location for the migrator's platform + version specific api diff json files
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index c451968..f12ffce 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -2603,10 +2603,8 @@
return makeParserErrorResult<Decl>();
}
- if (DeclResult.isParseError() && MayNeedOverrideCompletion &&
- Tok.is(tok::code_complete)) {
- DeclResult = makeParserCodeCompletionStatus();
- if (CodeCompletion) {
+ if (DeclResult.isParseError() && Tok.is(tok::code_complete)) {
+ if (MayNeedOverrideCompletion && CodeCompletion) {
// If we need to complete an override, collect the keywords already
// specified so that we do not duplicate them in code completion
// strings.
@@ -2628,6 +2626,9 @@
}
CodeCompletion->completeNominalMemberBeginning(Keywords);
}
+
+ DeclResult = makeParserCodeCompletionStatus();
+ consumeToken(tok::code_complete);
}
if (auto SF = CurDeclContext->getParentSourceFile()) {
diff --git a/lib/SIL/DynamicCasts.cpp b/lib/SIL/DynamicCasts.cpp
index 3f19cc3..3e72515 100644
--- a/lib/SIL/DynamicCasts.cpp
+++ b/lib/SIL/DynamicCasts.cpp
@@ -1138,22 +1138,19 @@
if (!objectType.isAnyClassReferenceType())
return false;
- if (M.getASTContext().LangOpts.EnableObjCInterop) {
auto super = archetype->getSuperclass();
if (super.isNull())
return false;
- // A base class constraint that isn't NSError rules out the archetype being
- // bound to NSError.
- if (auto nserror = M.Types.getNSErrorType())
- return !super->isEqual(nserror);
- // If NSError wasn't loaded, any base class constraint must not be NSError.
- return true;
- } else {
- // If ObjC bridging isn't enabled, we can do a scalar cast from any
- // reference type to any class-constrained archetype.
- return archetype->requiresClass();
+ // A base class constraint that isn't NSError rules out the archetype being
+ // bound to NSError.
+ if (M.getASTContext().LangOpts.EnableObjCInterop) {
+ if (auto nserror = M.Types.getNSErrorType())
+ return !super->isEqual(nserror);
}
+
+ // If NSError wasn't loaded, any base class constraint must not be NSError.
+ return true;
}
if (M.getASTContext().LangOpts.EnableObjCInterop
diff --git a/lib/Sema/CSApply.cpp b/lib/Sema/CSApply.cpp
index 5670ea0..9aaaad9 100644
--- a/lib/Sema/CSApply.cpp
+++ b/lib/Sema/CSApply.cpp
@@ -3681,10 +3681,7 @@
auto *locator = cs.getConstraintLocator(expr);
if (!choice) {
- if (tc.Context.LangOpts.EnableObjCInterop)
- choice = solution.getDisjunctionChoice(locator);
- else
- choice = 0;
+ choice = solution.getDisjunctionChoice(locator);
}
// Handle the coercion/bridging of the underlying subexpression, where
diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp
index 6b7c48f..6bedfa1 100644
--- a/lib/Sema/CSSimplify.cpp
+++ b/lib/Sema/CSSimplify.cpp
@@ -3637,11 +3637,6 @@
Type type2,
TypeMatchOptions flags,
ConstraintLocatorBuilder locator) {
- // There's no bridging without ObjC interop, so we shouldn't have set up
- // bridging constraints without it.
- assert(TC.Context.LangOpts.EnableObjCInterop
- && "bridging constraint w/o ObjC interop?!");
-
TypeMatchOptions subflags = getDefaultDecompositionOptions(flags);
/// Form an unresolved result.
@@ -5086,14 +5081,11 @@
coerceConstraint->setFavored();
constraints.push_back(coerceConstraint);
- // Bridging.
- if (getASTContext().LangOpts.EnableObjCInterop) {
- // The source type can be explicitly converted to the destination type.
- Constraint *bridgingConstraint =
- Constraint::create(*this, ConstraintKind::BridgingConversion,
- fromType, toType, locatorPtr);
- constraints.push_back(bridgingConstraint);
- }
+ // The source type can be explicitly converted to the destination type.
+ Constraint *bridgingConstraint =
+ Constraint::create(*this, ConstraintKind::BridgingConversion,
+ fromType, toType, locatorPtr);
+ constraints.push_back(bridgingConstraint);
if (allowFixes && shouldAttemptFixes()) {
Constraint *downcastConstraint =
@@ -5104,8 +5096,8 @@
}
addDisjunctionConstraint(constraints, locator,
- getASTContext().LangOpts.EnableObjCInterop && allowFixes ? RememberChoice
- : ForgetChoice);
+ allowFixes ? RememberChoice
+ : ForgetChoice);
}
ConstraintSystem::SolutionKind
diff --git a/lib/Sema/Constraint.cpp b/lib/Sema/Constraint.cpp
index 68a7545..622cfb1 100644
--- a/lib/Sema/Constraint.cpp
+++ b/lib/Sema/Constraint.cpp
@@ -612,10 +612,6 @@
assert((kind != ConstraintKind::LiteralConformsTo) ||
second->is<ProtocolType>());
- // Bridging constraints require bridging to be enabled.
- assert(kind != ConstraintKind::BridgingConversion
- || cs.TC.Context.LangOpts.EnableObjCInterop);
-
// Create the constraint.
unsigned size = totalSizeToAlloc<TypeVariableType*>(typeVars.size());
void *mem = cs.getAllocator().Allocate(size, alignof(Constraint));
diff --git a/lib/Sema/TypeCheckConstraints.cpp b/lib/Sema/TypeCheckConstraints.cpp
index c8a52cd..71782a6 100644
--- a/lib/Sema/TypeCheckConstraints.cpp
+++ b/lib/Sema/TypeCheckConstraints.cpp
@@ -2899,8 +2899,7 @@
bool TypeChecker::isObjCBridgedTo(Type type1, Type type2, DeclContext *dc,
bool *unwrappedIUO) {
- return (Context.LangOpts.EnableObjCInterop &&
- typesSatisfyConstraint(type1, type2,
+ return (typesSatisfyConstraint(type1, type2,
/*openArchetypes=*/false,
ConstraintKind::BridgingConversion,
dc, unwrappedIUO));
@@ -3412,9 +3411,8 @@
}
// Check for a bridging conversion.
- // Anything bridges to AnyObject in ObjC interop mode.
- if (Context.LangOpts.EnableObjCInterop
- && toType->isAnyObject())
+ // Anything bridges to AnyObject.
+ if (toType->isAnyObject())
return CheckedCastKind::BridgingCoercion;
// Do this check later in Swift 3 mode so that we check for NSNumber and
diff --git a/lib/Sema/TypeCheckError.cpp b/lib/Sema/TypeCheckError.cpp
index 7ed5732..9de8ec5 100644
--- a/lib/Sema/TypeCheckError.cpp
+++ b/lib/Sema/TypeCheckError.cpp
@@ -41,23 +41,19 @@
};
unsigned TheKind : 2;
unsigned IsRethrows : 1;
- unsigned IsProtocolMethod : 1;
unsigned ParamCount : 28;
public:
explicit AbstractFunction(Kind kind, Expr *fn)
: TheKind(kind),
IsRethrows(false),
- IsProtocolMethod(false),
ParamCount(1) {
TheExpr = fn;
}
- explicit AbstractFunction(AbstractFunctionDecl *fn,
- bool isProtocolMethod)
+ explicit AbstractFunction(AbstractFunctionDecl *fn)
: TheKind(Kind::Function),
IsRethrows(fn->getAttrs().hasAttribute<RethrowsAttr>()),
- IsProtocolMethod(isProtocolMethod),
ParamCount(fn->getNumParameterLists()) {
TheFunction = fn;
}
@@ -65,7 +61,6 @@
explicit AbstractFunction(AbstractClosureExpr *closure)
: TheKind(Kind::Closure),
IsRethrows(false),
- IsProtocolMethod(false),
ParamCount(1) {
TheClosure = closure;
}
@@ -73,7 +68,6 @@
explicit AbstractFunction(ParamDecl *parameter)
: TheKind(Kind::Parameter),
IsRethrows(false),
- IsProtocolMethod(false),
ParamCount(1) {
TheParameter = parameter;
}
@@ -84,7 +78,7 @@
bool isBodyRethrows() const { return IsRethrows; }
unsigned getNumArgumentsForFullApply() const {
- return (ParamCount - unsigned(IsProtocolMethod));
+ return ParamCount;
}
Type getType() const {
@@ -120,10 +114,6 @@
return TheExpr;
}
- bool isProtocolMethod() const {
- return IsProtocolMethod;
- }
-
static AbstractFunction decomposeApply(ApplyExpr *apply,
SmallVectorImpl<Expr*> &args) {
Expr *fn;
@@ -150,6 +140,9 @@
// Look through base-ignored qualified references (Module.methodName).
} else if (auto baseIgnored = dyn_cast<DotSyntaxBaseIgnoredExpr>(fn)) {
fn = baseIgnored->getRHS();
+ // Look through closure capture lists.
+ } else if (auto captureList = dyn_cast<CaptureListExpr>(fn)) {
+ fn = captureList->getClosureBody();
} else {
break;
}
@@ -159,18 +152,11 @@
if (auto declRef = dyn_cast<DeclRefExpr>(fn)) {
ValueDecl *decl = declRef->getDecl();
if (auto fn = dyn_cast<AbstractFunctionDecl>(decl)) {
- return AbstractFunction(fn, false);
+ return AbstractFunction(fn);
} else if (auto param = dyn_cast<ParamDecl>(decl)) {
return AbstractFunction(param);
}
- // Archetype function references.
- } else if (auto memberRef = dyn_cast<MemberRefExpr>(fn)) {
- if (auto fn = dyn_cast<AbstractFunctionDecl>(
- memberRef->getMember().getDecl())) {
- return AbstractFunction(fn, true);
- }
-
// Closures.
} else if (auto closure = dyn_cast<AbstractClosureExpr>(fn)) {
return AbstractFunction(closure);
@@ -459,14 +445,6 @@
Type type = fnRef.getType();
if (!type) return Classification::forInvalidCode();
- if (fnRef.isProtocolMethod()) {
- if (auto fnType = type->getAs<AnyFunctionType>()) {
- type = fnType->getResult();
- } else {
- Classification::forInvalidCode();
- }
- }
-
// Use the most significant result from the arguments.
Classification result;
for (auto arg : reversed(args)) {
diff --git a/stdlib/public/core/BridgeObjectiveC.swift b/stdlib/public/core/BridgeObjectiveC.swift
index f905f82..8f32d33 100644
--- a/stdlib/public/core/BridgeObjectiveC.swift
+++ b/stdlib/public/core/BridgeObjectiveC.swift
@@ -10,7 +10,6 @@
//
//===----------------------------------------------------------------------===//
-#if _runtime(_ObjC)
/// A Swift Array or Dictionary of types conforming to
/// `_ObjectiveCBridgeable` can be passed to Objective-C as an NSArray or
/// NSDictionary, respectively. The elements of the resulting NSArray
@@ -83,6 +82,8 @@
-> Self
}
+#if _runtime(_ObjC)
+
//===--- Bridging for metatypes -------------------------------------------===//
/// A stand-in for a value of metatype type.
@@ -640,3 +641,182 @@
}
#endif
+
+//===--- Bridging without the ObjC runtime --------------------------------===//
+
+#if !_runtime(_ObjC)
+
+/// Convert `x` from its Objective-C representation to its Swift
+/// representation.
+/// COMPILER_INTRINSIC
+@_inlineable // FIXME(sil-serialize-all)
+public func _forceBridgeFromObjectiveC_bridgeable<T:_ObjectiveCBridgeable> (
+ _ x: T._ObjectiveCType,
+ _: T.Type
+) -> T {
+ var result: T?
+ T._forceBridgeFromObjectiveC(x, result: &result)
+ return result!
+}
+
+/// Attempt to convert `x` from its Objective-C representation to its Swift
+/// representation.
+/// COMPILER_INTRINSIC
+@_inlineable // FIXME(sil-serialize-all)
+public func _conditionallyBridgeFromObjectiveC_bridgeable<T:_ObjectiveCBridgeable>(
+ _ x: T._ObjectiveCType,
+ _: T.Type
+) -> T? {
+ var result: T?
+ T._conditionallyBridgeFromObjectiveC (x, result: &result)
+ return result
+}
+
+public // SPI(Foundation)
+protocol _NSSwiftValue: class {
+ init(_ value: Any)
+ var value: Any { get }
+ static var null: AnyObject { get }
+}
+
+@usableFromInline
+internal class _SwiftValue {
+ @usableFromInline
+ let value: Any
+
+ @usableFromInline
+ init(_ value: Any) {
+ self.value = value
+ }
+
+ @usableFromInline
+ static let null = _SwiftValue(Optional<Any>.none as Any)
+}
+
+// Internal stdlib SPI
+@_silgen_name("swift_unboxFromSwiftValueWithType")
+public func swift_unboxFromSwiftValueWithType<T>(
+ _ source: inout AnyObject,
+ _ result: UnsafeMutablePointer<T>
+ ) -> Bool {
+
+ if source === _nullPlaceholder {
+ if let unpacked = Optional<Any>.none as? T {
+ result.initialize(to: unpacked)
+ return true
+ }
+ }
+
+ if let box = source as? _SwiftValue {
+ if let value = box.value as? T {
+ result.initialize(to: value)
+ return true
+ }
+ } else if let box = source as? _NSSwiftValue {
+ if let value = box.value as? T {
+ result.initialize(to: value)
+ return true
+ }
+ }
+
+ return false
+}
+
+// Internal stdlib SPI
+@_silgen_name("swift_swiftValueConformsTo")
+public func _swiftValueConformsTo<T>(_ type: T.Type) -> Bool {
+ if let foundationType = _foundationSwiftValueType {
+ return foundationType is T.Type
+ } else {
+ return _SwiftValue.self is T.Type
+ }
+}
+
+@_silgen_name("_swift_extractDynamicValue")
+public func _extractDynamicValue<T>(_ value: T) -> AnyObject?
+
+@_silgen_name("_swift_bridgeToObjectiveCUsingProtocolIfPossible")
+public func _bridgeToObjectiveCUsingProtocolIfPossible<T>(_ value: T) -> AnyObject?
+
+@usableFromInline
+protocol _Unwrappable {
+ func unwrap() -> Any?
+}
+
+extension Optional: _Unwrappable {
+ func unwrap() -> Any? {
+ return self
+ }
+}
+
+private let _foundationSwiftValueType = _typeByName("Foundation._SwiftValue") as? _NSSwiftValue.Type
+
+@usableFromInline
+internal var _nullPlaceholder: AnyObject {
+ if let foundationType = _foundationSwiftValueType {
+ return foundationType.null
+ } else {
+ return _SwiftValue.null
+ }
+}
+
+@usableFromInline
+func _makeSwiftValue(_ value: Any) -> AnyObject {
+ if let foundationType = _foundationSwiftValueType {
+ return foundationType.init(value)
+ } else {
+ return _SwiftValue(value)
+ }
+}
+
+/// Bridge an arbitrary value to an Objective-C object.
+///
+/// - If `T` is a class type, it is always bridged verbatim, the function
+/// returns `x`;
+///
+/// - otherwise, if `T` conforms to `_ObjectiveCBridgeable`,
+/// returns the result of `x._bridgeToObjectiveC()`;
+///
+/// - otherwise, we use **boxing** to bring the value into Objective-C.
+/// The value is wrapped in an instance of a private Objective-C class
+/// that is `id`-compatible and dynamically castable back to the type of
+/// the boxed value, but is otherwise opaque.
+///
+/// COMPILER_INTRINSIC
+@inlinable // FIXME(sil-serialize-all)
+public func _bridgeAnythingToObjectiveC<T>(_ x: T) -> AnyObject {
+ var done = false
+ var result: AnyObject!
+
+ var source: Any = x
+
+ if let dynamicSource = _extractDynamicValue(x) {
+ result = dynamicSource as AnyObject
+ done = true
+ }
+
+ if !done, let wrapper = source as? _Unwrappable {
+ if let value = wrapper.unwrap() {
+ result = value as AnyObject
+ } else {
+ result = _nullPlaceholder
+ }
+
+ done = true
+ }
+
+ if !done {
+ if type(of: source) as? AnyClass != nil {
+ result = unsafeBitCast(x, to: AnyObject.self)
+ } else if let object = _bridgeToObjectiveCUsingProtocolIfPossible(source) {
+ result = object
+ } else {
+ result = _makeSwiftValue(source)
+ }
+ }
+
+ return result
+}
+
+#endif // !_runtime(_ObjC)
+
diff --git a/stdlib/public/core/Codable.swift.gyb b/stdlib/public/core/Codable.swift.gyb
index cd4a284..5a19c3b 100644
--- a/stdlib/public/core/Codable.swift.gyb
+++ b/stdlib/public/core/Codable.swift.gyb
@@ -1180,7 +1180,7 @@
public var _userInfo: AnyObject? {
// The error dictionary must be returned as an AnyObject. We can do this
// only on platforms with bridging, unfortunately.
- #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
+ #if _runtime(_ObjC)
let context: Context
switch self {
case .invalidValue(_, let c): context = c
@@ -1290,7 +1290,7 @@
public var _userInfo: AnyObject? {
// The error dictionary must be returned as an AnyObject. We can do this
// only on platforms with bridging, unfortunately.
- #if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
+ #if _runtime(_ObjC)
let context: Context
switch self {
case .keyNotFound(_, let c): context = c
diff --git a/stdlib/public/runtime/Casting.cpp b/stdlib/public/runtime/Casting.cpp
index 1629fe1..70605741 100644
--- a/stdlib/public/runtime/Casting.cpp
+++ b/stdlib/public/runtime/Casting.cpp
@@ -196,7 +196,6 @@
targetType, targetName.c_str(), message);
}
-#if SWIFT_OBJC_INTEROP
// Objective-C bridging helpers.
namespace {
struct _ObjectiveCBridgeableWitnessTable;
@@ -227,7 +226,6 @@
const Metadata *targetType,
const _ObjectiveCBridgeableWitnessTable *targetBridgeWitness,
DynamicCastFlags flags);
-#endif
/// A convenient method for failing out of a dynamic cast.
static bool _fail(OpaqueValue *srcValue, const Metadata *srcType,
@@ -718,6 +716,16 @@
/******************************** Existentials ********************************/
/******************************************************************************/
+#if !SWIFT_OBJC_INTEROP // _SwiftValue is a native class
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
+bool swift_swiftValueConformsTo(const Metadata *destinationType);
+
+#define _bridgeAnythingToObjectiveC \
+ MANGLE_SYM(s27_bridgeAnythingToObjectiveCyyXlxlF)
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
+HeapObject *_bridgeAnythingToObjectiveC(OpaqueValue *src, const Metadata *srcType);
+#endif
+
/// Perform a dynamic cast to an existential type.
static bool _dynamicCastToExistential(OpaqueValue *dest,
OpaqueValue *src,
@@ -812,6 +820,15 @@
maybeDeallocateSource(true);
return true;
}
+#else // !SWIFT_OBJC_INTEROP -- _SwiftValue is a native class
+ bool isMetatype = kind == MetadataKind::ExistentialMetatype || kind == MetadataKind::Metatype;
+ if (!isMetatype && (isTargetTypeAnyObject || swift_swiftValueConformsTo(targetType))) {
+ auto object = _bridgeAnythingToObjectiveC(src, srcType);
+ swift_retain(object);
+ destExistential->Value = object;
+ maybeDeallocateSource(true);
+ return true;
+ }
#endif
return _fail(src, srcType, targetType, flags);
@@ -860,7 +877,6 @@
case MetadataKind::Enum:
case MetadataKind::Optional:
-#if SWIFT_OBJC_INTEROP
// If the source type is bridged to Objective-C, try to bridge.
if (auto srcBridgeWitness = findBridgeWitness(srcDynamicType)) {
bool success = _dynamicCastValueToClassExistentialViaObjCBridgeable(
@@ -873,7 +889,6 @@
maybeDeallocateSource(success);
return success;
}
-#endif
LLVM_FALLTHROUGH;
case MetadataKind::Function:
@@ -1331,7 +1346,6 @@
/********************************** Classes ***********************************/
/******************************************************************************/
-#if SWIFT_OBJC_INTEROP
/// Do a dynamic cast to the target class.
static void *_dynamicCastUnknownClass(void *object,
const Metadata *targetType,
@@ -1344,7 +1358,6 @@
return const_cast<void*>(swift_dynamicCastUnknownClass(object, targetType));
}
-#endif
static bool _dynamicCastUnknownClassIndirect(OpaqueValue *dest,
void *object,
@@ -2056,7 +2069,13 @@
/**************************** Bridging _SwiftValue ****************************/
/******************************************************************************/
-#if SWIFT_OBJC_INTEROP
+#if !SWIFT_OBJC_INTEROP // _SwiftValue is a native class
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
+bool swift_unboxFromSwiftValueWithType(OpaqueValue *source,
+ OpaqueValue *result,
+ const Metadata *destinationType);
+#endif
+
/// Try to unbox a _SwiftValue box to perform a dynamic cast.
static bool tryDynamicCastBoxedSwiftValue(OpaqueValue *dest,
OpaqueValue *src,
@@ -2074,6 +2093,13 @@
return false;
}
+#if !SWIFT_OBJC_INTEROP // _SwiftValue is a native class:
+ if (swift_unboxFromSwiftValueWithType(src, dest, targetType)) {
+ return true;
+ }
+#endif
+
+#if SWIFT_OBJC_INTEROP // _SwiftValue is an ObjC class:
id srcObject;
memcpy(&srcObject, src, sizeof(id));
@@ -2113,10 +2139,10 @@
objc_release((id)srcSwiftValue);
return true;
}
+#endif
return false;
}
-#endif
/******************************************************************************/
/******************************** Collections *********************************/
@@ -2411,7 +2437,6 @@
if (!srcType)
return unwrapResult.success;
-#if SWIFT_OBJC_INTEROP
// A class or AnyObject reference may point to a _SwiftValue box.
{
auto innerFlags = flags - DynamicCastFlags::Unconditional
@@ -2426,7 +2451,6 @@
// (for example, casting _SwiftValue to NSObject will be successful)
}
}
-#endif
switch (targetType->getKind()) {
// Handle wrapping an Optional target.
@@ -2435,7 +2459,6 @@
// unwrapping the target. This handles an optional source wrapped within an
// existential that Optional conforms to (Any).
if (auto srcExistentialType = dyn_cast<ExistentialTypeMetadata>(srcType)) {
-#if SWIFT_OBJC_INTEROP
// If coming from AnyObject, we may want to bridge.
if (isAnyObjectExistentialType(srcExistentialType)) {
if (auto targetBridgeWitness = findBridgeWitness(targetType)) {
@@ -2445,7 +2468,6 @@
flags);
}
}
-#endif
return _dynamicCastFromExistential(dest, src, srcExistentialType,
targetType, flags);
}
@@ -2510,7 +2532,6 @@
case MetadataKind::Enum:
case MetadataKind::Optional: {
-#if SWIFT_OBJC_INTEROP
// If the source type is bridged to Objective-C, try to bridge.
if (auto srcBridgeWitness = findBridgeWitness(srcType)) {
return _dynamicCastValueToClassViaObjCBridgeable(dest, src, srcType,
@@ -2518,7 +2539,6 @@
srcBridgeWitness,
flags);
}
-#endif
return _fail(src, srcType, targetType, flags);
}
@@ -2567,7 +2587,6 @@
return _dynamicCastToAnyHashable(dest, src, srcType, targetType, flags);
}
-#if SWIFT_OBJC_INTEROP
// If the target type is bridged to Objective-C, try to bridge.
if (auto targetBridgeWitness = findBridgeWitness(targetType)) {
return _dynamicCastClassToValueViaObjCBridgeable(dest, src, srcType,
@@ -2576,6 +2595,7 @@
flags);
}
+#if SWIFT_OBJC_INTEROP
// If the source is an NSError, and the target is a bridgeable
// Error, try to bridge.
if (tryDynamicCastNSErrorToValue(dest, src, srcType, targetType, flags)) {
@@ -2674,7 +2694,6 @@
/********************************** Bridging **********************************/
/******************************************************************************/
-#if SWIFT_OBJC_INTEROP
//===----------------------------------------------------------------------===//
// Bridging to and from Objective-C
//===----------------------------------------------------------------------===//
@@ -2851,7 +2870,7 @@
// Allocate a buffer to store the T? returned by bridging.
// The extra byte is for the tag.
const std::size_t inlineValueSize = 3 * sizeof(void*);
- alignas(std::max_align_t) char inlineBuffer[inlineValueSize + 1];
+ alignas(max_align_t) char inlineBuffer[inlineValueSize + 1];
void *optDestBuffer;
if (targetType->getValueWitnesses()->getStride() <= inlineValueSize) {
// Use the inline buffer.
@@ -2895,6 +2914,13 @@
return success;
}
+#if !SWIFT_OBJC_INTEROP // _SwiftValue is a native class:
+
+
+
+#endif // !_SWIFT_OBJC_INTEROP
+
+#if SWIFT_OBJC_INTEROP
static id bridgeAnythingNonVerbatimToObjectiveC(OpaqueValue *src,
const Metadata *srcType,
bool consume) {
@@ -2994,6 +3020,7 @@
return bridgeAnythingNonVerbatimToObjectiveC(src, srcType,
/*consume*/shouldConsume);
}
+#endif
//===--- Bridging helpers for the Swift stdlib ----------------------------===//
// Functions that must discover and possibly use an arbitrary type's
@@ -3001,10 +3028,12 @@
// documentation.
//===----------------------------------------------------------------------===//
+#if SWIFT_OBJC_INTEROP
#define BRIDGING_CONFORMANCE_SYM \
MANGLE_SYM(s19_BridgeableMetatypeVs21_ObjectiveCBridgeablesWP)
extern "C" const _ObjectiveCBridgeableWitnessTable BRIDGING_CONFORMANCE_SYM;
+#endif
static const _ObjectiveCBridgeableWitnessTable *
findBridgeWitness(const Metadata *T) {
@@ -3017,16 +3046,20 @@
// that looks like a metatype value if the metatype can be bridged.
switch (T->getKind()) {
case MetadataKind::Metatype: {
+#if SWIFT_OBJC_INTEROP
auto metaTy = static_cast<const MetatypeMetadata *>(T);
if (metaTy->InstanceType->isAnyClass())
return &BRIDGING_CONFORMANCE_SYM;
+#endif
break;
}
case MetadataKind::ExistentialMetatype: {
+#if SWIFT_OBJC_INTEROP
auto existentialMetaTy =
static_cast<const ExistentialMetatypeMetadata *>(T);
if (existentialMetaTy->isObjC())
return &BRIDGING_CONFORMANCE_SYM;
+#endif
break;
}
@@ -3068,6 +3101,8 @@
return nullptr;
}
+#if SWIFT_OBJC_INTEROP
+
// @_silgen_name("_bridgeNonVerbatimFromObjectiveCToAny")
// func _bridgeNonVerbatimFromObjectiveCToAny(
// x: AnyObject,
@@ -3104,7 +3139,6 @@
return true;
}
}
-
// Check if the value is a box containing a value of the desired type.
if (auto srcBox = getAsSwiftValue((id)sourceValue)) {
const Metadata *sourceType;
@@ -3136,6 +3170,7 @@
OpaqueValue *destValue,
const Metadata *nativeType_
) {
+
if (tryBridgeNonVerbatimFromObjectiveCUniversal(sourceValue, nativeType,
destValue))
return;
@@ -3213,6 +3248,8 @@
destValue, nativeType, nativeType, bridgeWitness);
}
+#endif // SWIFT_OBJC_INTEROP
+
// func _isBridgedNonVerbatimToObjectiveC<T>(_: T.Type) -> Bool
// Called by inlined stdlib code.
#define _isBridgedNonVerbatimToObjectiveC \
@@ -3225,7 +3262,6 @@
auto bridgeWitness = findBridgeWitness(T);
return (bool)bridgeWitness;
}
-#endif
// func _isClassOrObjCExistential<T>(x: T.Type) -> Bool
SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERFACE
@@ -3254,6 +3290,55 @@
return type->getKind() == MetadataKind::Optional;
}
+#if !SWIFT_OBJC_INTEROP
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
+bool _swift_isOptional(OpaqueValue *src, const Metadata *type) {
+ return swift_isOptionalType(type);
+}
+
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
+HeapObject *_swift_extractDynamicValue(OpaqueValue *value, const Metadata *self) {
+ OpaqueValue *outValue;
+ const Metadata *outType;
+ bool canTake = false;
+
+ findDynamicValueAndType(value, self, outValue, outType, canTake,
+ /*isAnyObject*/ true,
+ /*isExistentialMetatype*/ true);
+
+ if (!outType || (outType != self && outType->isAnyClass())) {
+ HeapObject *object = *(reinterpret_cast<HeapObject**>(outValue));
+ swift_retain(object);
+ return object;
+ }
+
+ return nullptr;
+}
+
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
+HeapObject *_swift_bridgeToObjectiveCUsingProtocolIfPossible(
+ OpaqueValue *src, const Metadata *srcType) {
+ assert(!swift_isClassOrObjCExistentialTypeImpl(srcType));
+
+ OpaqueValue *outValue;
+ const Metadata *outType;
+ bool canTake = false;
+
+ findDynamicValueAndType(src, srcType, outValue, outType, canTake,
+ /*isAnyObject*/ false,
+ /*isExistentialMetatype*/ true);
+
+ auto bridgeWitness = findBridgeWitness(outType);
+ if (bridgeWitness) {
+ auto bridgedObject =
+ bridgeWitness->bridgeToObjectiveC(outValue, outType, bridgeWitness);
+ return bridgedObject;
+ } else {
+ return nullptr;
+ }
+}
+#endif
+
#define OVERRIDE_CASTING COMPATIBILITY_OVERRIDE
#include "CompatibilityOverride.def"
diff --git a/test/Constraints/bridging_nonobjc.swift b/test/Constraints/bridging_nonobjc.swift
index f2c06ee..df05f59 100644
--- a/test/Constraints/bridging_nonobjc.swift
+++ b/test/Constraints/bridging_nonobjc.swift
@@ -2,4 +2,4 @@
var x: Any = 1
-var y = x as AnyObject // expected-error{{not convertible}}
+var y = x as AnyObject
diff --git a/test/IDE/complete_declname.swift b/test/IDE/complete_declname.swift
new file mode 100644
index 0000000..ae10ba7
--- /dev/null
+++ b/test/IDE/complete_declname.swift
@@ -0,0 +1,44 @@
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=CLASSNAME | %FileCheck %s --check-prefix=NO_COMPLETIONS
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=STRUCTNAME | %FileCheck %s --check-prefix=NO_COMPLETIONS
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ENUMNAME | %FileCheck %s --check-prefix=NO_COMPLETIONS
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=PROTOCOLNAME | %FileCheck %s --check-prefix=NO_COMPLETIONS
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=PRECEDENCEGROUPNAME | %FileCheck %s --check-prefix=NO_COMPLETIONS
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=OPERATORNAME | %FileCheck %s --check-prefix=NO_COMPLETIONS
+
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-keywords=false -code-completion-token=METHODNAME | %FileCheck %s --check-prefix=NO_COMPLETIONS
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-keywords=false -code-completion-token=METHODNAME_OVERRIDE | %FileCheck %s --check-prefix=METHODNAME_OVERRIDE
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-keywords=false -code-completion-token=METHODNAME_PROTOCOL | %FileCheck %s --check-prefix=NO_COMPLETIONS
+// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-keywords=false -code-completion-token=METHODNAME_CONFORMANCE | %FileCheck %s --check-prefix=METHODNAME_CONFORMANCE
+
+// NO_COMPLETIONS-NOT: Begin completions
+
+class #^CLASSNAME^# {}
+struct #^STRUCTNAME^#
+enum #^ENUMNAME^#
+protocol #^PROTOCOLNAME^# {}
+precedencegroup #^PRECEDENCEGROUPNAME^#
+infix operator #^OPERATORNAME^#
+
+class MyCls {
+ func foo() {}
+ func #^METHODNAME^#
+}
+
+class MySub : MyCls {
+ func #^METHODNAME_OVERRIDE^#
+// METHODNAME_OVERRIDE: Begin completions, 1 items
+// METHODNAME_OVERRIDE-NEXT: Decl[InstanceMethod]/Super: foo() {|}; name=foo()
+// METHODNAME_OVERRIDE-NEXT: End completions
+}
+
+protocol P {
+ func foo() {}
+ func #^METHODNAME_PROTOCOL^#
+}
+
+struct MyStruct : P {
+ func #^METHODNAME_CONFORMANCE^#
+// METHODNAME_CONFORMANCE: Begin completions, 1 items
+// METHODNAME_CONFORMANCE-NEXT: Decl[InstanceMethod]/Super: foo() {|}; name=foo()
+// METHODNAME_CONFORMANCE-NEXT: End completions
+}
diff --git a/test/Interpreter/generic_casts.swift b/test/Interpreter/generic_casts.swift
index 0705141..262fdc0 100644
--- a/test/Interpreter/generic_casts.swift
+++ b/test/Interpreter/generic_casts.swift
@@ -4,9 +4,10 @@
// REQUIRES: executable_test
// FIXME: rdar://problem/19648117 Needs splitting objc parts out
-// XFAIL: linux
+#if canImport(Foundation)
import Foundation
+#endif
func allToInt<T>(_ x: T) -> Int {
return x as! Int
@@ -153,21 +154,35 @@
// FIXME: Can't spell AnyObject.Protocol
// CHECK-LABEL: AnyObject casts:
print("AnyObject casts:")
-print(allToAll(C(), AnyObject.self)) // CHECK-NEXT: true
-print(allToAll(type(of: C()), AnyObject.self)) // CHECK-NEXT: true
+print(allToAll(C(), AnyObject.self)) // CHECK: true
+
+// On Darwin, the object will be the ObjC-runtime-class object;
+// out of Darwin, this should not succeed.
+print(allToAll(type(of: C()), AnyObject.self))
+// CHECK-objc: true
+// CHECK-native: false
+
// Bridging
-print(allToAll(0, AnyObject.self)) // CHECK-NEXT: true
+// NSNumber on Darwin, _SwiftValue on Linux.
+print(allToAll(0, AnyObject.self)) // CHECK: true
// This will get bridged using _SwiftValue.
struct NotBridged { var x: Int }
-print(allToAll(NotBridged(x: 0), AnyObject.self)) // CHECK-NEXT: true
-print(allToAll(NotBridged(x: 0), NSCopying.self)) // CHECK-NEXT: true
+print(allToAll(NotBridged(x: 0), AnyObject.self)) // CHECK: true
-// These casts fail (intentionally) even though _SwiftValue does
+#if canImport(Foundation)
+// This requires Foundation (for NSCopying):
+print(allToAll(NotBridged(x: 0), NSCopying.self)) // CHECK-objc: true
+#endif
+
+// On Darwin, these casts fail (intentionally) even though _SwiftValue does
// technically conform to these protocols through NSObject.
-print(allToAll(NotBridged(x: 0), CustomStringConvertible.self)) // CHECK-NEXT: false
-print(allToAll(NotBridged(x: 0), (AnyObject & CustomStringConvertible).self)) // CHECK-NEXT: false
+// Off Darwin, it should not conform at all.
+print(allToAll(NotBridged(x: 0), CustomStringConvertible.self)) // CHECK: false
+print(allToAll(NotBridged(x: 0), (AnyObject & CustomStringConvertible).self)) // CHECK: false
+#if canImport(Foundation)
+// This requires Foundation (for NSArray):
//
// rdar://problem/19482567
//
@@ -183,4 +198,5 @@
}
let result = swiftOptimizesThisFunctionIncorrectly()
-print("Bridge cast result: \(result)") // CHECK-NEXT: Bridge cast result: true
+print("Bridge cast result: \(result)") // CHECK-NEXT-objc: Bridge cast result: true
+#endif
diff --git a/test/SILGen/generic_casts.swift b/test/SILGen/generic_casts.swift
index 7a8facb..d1e3198 100644
--- a/test/SILGen/generic_casts.swift
+++ b/test/SILGen/generic_casts.swift
@@ -59,11 +59,9 @@
<T:ClassBound, U:ClassBound>(_ t:T) -> U {
return t as! U
// Error bridging can change the identity of class-constrained archetypes.
- // CHECK-objc: unconditional_checked_cast_addr T in {{%.*}} : $*T to U in [[DOWNCAST_ADDR:%.*]] : $*U
- // CHECK-objc: [[DOWNCAST:%.*]] = load [take] [[DOWNCAST_ADDR]]
- // CHECK-objc: return [[DOWNCAST]] : $U
-
- // CHECK-native: [[DOWNCAST:%.*]] = unconditional_checked_cast {{.*}} : $T to $U
+ // CHECK: unconditional_checked_cast_addr T in {{%.*}} : $*T to U in [[DOWNCAST_ADDR:%.*]] : $*U
+ // CHECK: [[DOWNCAST:%.*]] = load [take] [[DOWNCAST_ADDR]]
+ // CHECK: return [[DOWNCAST]] : $U
}
// CHECK-LABEL: sil hidden @$S13generic_casts019class_archetype_is_c1_D0{{[_0-9a-zA-Z]*}}F
@@ -71,8 +69,7 @@
<T:ClassBound, U:ClassBound>(_ t:T, u:U.Type) -> Bool {
return t is U
// Error bridging can change the identity of class-constrained archetypes.
- // CHECK-objc: checked_cast_addr_br {{.*}} T in {{%.*}} : $*T to U in {{%.*}} : $*U
- // CHECK-native: checked_cast_br {{.*}} : $T to $U
+ // CHECK: checked_cast_addr_br {{.*}} T in {{%.*}} : $*T to U in {{%.*}} : $*U
}
// CHECK-LABEL: sil hidden @$S13generic_casts38opaque_archetype_to_addr_only_concrete{{[_0-9a-zA-Z]*}}F
@@ -161,19 +158,16 @@
func class_existential_to_class_archetype
<T:ClassBound>(_ p:ClassBound) -> T {
return p as! T
- // CHECK-objc: unconditional_checked_cast_addr ClassBound in {{%.*}} : $*ClassBound to T in [[DOWNCAST_ADDR:%.*]] : $*T
- // CHECK-objc: [[DOWNCAST:%.*]] = load [take] [[DOWNCAST_ADDR]]
- // CHECK-objc: return [[DOWNCAST]] : $T
-
- // CHECK-native: [[DOWNCAST:%.*]] = unconditional_checked_cast {{.*}} : $ClassBound to $T
+ // CHECK: unconditional_checked_cast_addr ClassBound in {{%.*}} : $*ClassBound to T in [[DOWNCAST_ADDR:%.*]] : $*T
+ // CHECK: [[DOWNCAST:%.*]] = load [take] [[DOWNCAST_ADDR]]
+ // CHECK: return [[DOWNCAST]] : $T
}
// CHECK-LABEL: sil hidden @$S13generic_casts021class_existential_is_C10_archetype{{[_0-9a-zA-Z]*}}F
func class_existential_is_class_archetype
<T:ClassBound>(_ p:ClassBound, _: T) -> Bool {
return p is T
- // CHECK-objc: checked_cast_addr_br {{.*}} ClassBound in {{%.*}} : $*ClassBound to T in {{%.*}} : $*T
- // CHECK-native: checked_cast_br {{.*}} : $ClassBound to $T
+ // CHECK: checked_cast_addr_br {{.*}} ClassBound in {{%.*}} : $*ClassBound to T in {{%.*}} : $*T
}
// CHECK-LABEL: sil hidden @$S13generic_casts40opaque_existential_to_addr_only_concrete{{[_0-9a-zA-Z]*}}F
diff --git a/test/SourceKit/CompileNotifications/arg-parsing.swift b/test/SourceKit/CompileNotifications/arg-parsing.swift
new file mode 100644
index 0000000..e7372fa
--- /dev/null
+++ b/test/SourceKit/CompileNotifications/arg-parsing.swift
@@ -0,0 +1,41 @@
+// RUN: not %sourcekitd-test -req=track-compiles == -req=complete %s -offset=0 -- %s -no-such-arg | %FileCheck %s -check-prefix=ARG_PARSE_1
+// RUN: %sourcekitd-test -req=track-compiles == -req=sema %s -print-raw-response -- %s -no-such-arg | %FileCheck %s -check-prefix=ARG_PARSE_1
+// RUN: %sourcekitd-test -req=track-compiles == -req=cursor -offset=0 %s -- %s -no-such-arg | %FileCheck %s -check-prefix=ARG_PARSE_1
+// ARG_PARSE_1: {
+// ARG_PARSE_1: key.notification: source.notification.compile-will-start
+// ARG_PARSE_1: key.compileid: [[CID1:".*"]]
+// ARG_PARSE_1: key.compilerargs-string: "{{.*}}.swift -no-such-arg"
+// ARG_PARSE_1: }
+// ARG_PARSE_1: {
+// ARG_PARSE_1: key.notification: source.notification.compile-did-finish
+// ARG_PARSE_1: key.diagnostics: [
+// ARG_PARSE_1: {
+// ARG_PARSE_1: key.filepath: "<unknown>",
+// ARG_PARSE_1: key.severity: source.diagnostic.severity.error,
+// ARG_PARSE_1: key.description: "unknown argument: '-no-such-arg'"
+// ARG_PARSE_1: }
+// ARG_PARSE_1: ]
+// ARG_PARSE_1: key.compileid: [[CID1]]
+// ARG_PARSE_1: }
+// ARG_PARSE_1-NOT: compile-will-start
+// ARG_PARSE_1-NOT: compile-did-finish
+
+// RUN: not %sourcekitd-test -req=track-compiles == -req=complete %s -offset=0 | %FileCheck %s -check-prefix=ARG_PARSE_2
+// RUN: %sourcekitd-test -req=track-compiles == -req=sema %s -print-raw-response | %FileCheck %s -check-prefix=ARG_PARSE_2
+// ARG_PARSE_2: {
+// ARG_PARSE_2: key.notification: source.notification.compile-will-start
+// ARG_PARSE_2: key.compileid: [[CID1:".*"]]
+// ARG_PARSE_2: }
+// ARG_PARSE_2: {
+// ARG_PARSE_2: key.notification: source.notification.compile-did-finish
+// ARG_PARSE_2: key.diagnostics: [
+// ARG_PARSE_2: {
+// ARG_PARSE_2: key.filepath: "<unknown>",
+// ARG_PARSE_2: key.severity: source.diagnostic.severity.error,
+// ARG_PARSE_2: key.description: "no input files"
+// ARG_PARSE_2: }
+// ARG_PARSE_2: ]
+// ARG_PARSE_2: key.compileid: [[CID1]]
+// ARG_PARSE_2: }
+// ARG_PARSE_2-NOT: compile-will-start
+// ARG_PARSE_2-NOT: compile-did-finish
diff --git a/test/SwiftSyntax/ParseFile.swift b/test/SwiftSyntax/ParseFile.swift
index aa6e51c..79402d4 100644
--- a/test/SwiftSyntax/ParseFile.swift
+++ b/test/SwiftSyntax/ParseFile.swift
@@ -37,4 +37,13 @@
})
}
+ParseFile.test("ParseBuffer") {
+ expectDoesNotThrow({
+ let content = "func foo() {}"
+ let parsed = try SourceFileSyntax.decodeSourceFileSyntax(try
+ SwiftLang.parse(content))
+ expectEqual("\(parsed)", content)
+ })
+}
+
runAllTests()
diff --git a/test/decl/func/rethrows.swift b/test/decl/func/rethrows.swift
index cfa98ac..762c499 100644
--- a/test/decl/func/rethrows.swift
+++ b/test/decl/func/rethrows.swift
@@ -535,3 +535,13 @@
doRethrow(fn:) { (a, b) in return a }
DoRethrowGeneric<Int>().method(fn:) { (a, b) in return a }
}
+
+// https://bugs.swift.org/browse/SR-7120 - capture lists
+func rethrowsWithCaptureList<R, T>(
+ array: [T],
+ operation: (Int) throws -> R
+) rethrows -> R {
+ return try array.withUnsafeBytes { [array] _ in
+ return try operation(array.count)
+ }
+}
diff --git a/test/expr/cast/array_downcast.swift b/test/expr/cast/array_downcast.swift
index 475036d..fddea8a 100644
--- a/test/expr/cast/array_downcast.swift
+++ b/test/expr/cast/array_downcast.swift
@@ -1,7 +1,5 @@
// RUN: %target-typecheck-verify-swift
-// XFAIL: linux
-
// FIXME: Should go into the standard library.
public extension _ObjectiveCBridgeable {
static func _unconditionallyBridgeFromObjectiveC(_ source: _ObjectiveCType?)
diff --git a/test/stmt/errors_nonobjc.swift b/test/stmt/errors_nonobjc.swift
index 7f710f7..5d09db2 100644
--- a/test/stmt/errors_nonobjc.swift
+++ b/test/stmt/errors_nonobjc.swift
@@ -5,14 +5,13 @@
import Foundation
-// Catching `as NSError` ought *not* to be exhaustive when ObjC interop is
-// disabled. It's just another error type.
+// Since we enabled bridging on non-ObjC platforms, NSError ought to be treated as exhaustive.
func bar() throws {}
func foo() {
do {
- try bar() // expected-error{{enclosing catch is not exhaustive}}
+ try bar()
} catch _ as NSError {
}
}
diff --git a/tools/SourceKit/include/SourceKit/Support/Tracing.h b/tools/SourceKit/include/SourceKit/Support/Tracing.h
index 87cc03c..aeec80e 100644
--- a/tools/SourceKit/include/SourceKit/Support/Tracing.h
+++ b/tools/SourceKit/include/SourceKit/Support/Tracing.h
@@ -14,6 +14,7 @@
#define LLVM_SOURCEKIT_SUPPORT_TRACING_H
#include "SourceKit/Core/LLVM.h"
+#include "SourceKit/Core/LangSupport.h"
#include "SourceKit/Support/UIdent.h"
#include "swift/Basic/OptionSet.h"
#include "llvm/ADT/ArrayRef.h"
@@ -91,8 +92,11 @@
// Class that utilizes the RAII idiom for the operations being traced
class TracedOperation final {
+ using DiagnosticProvider = std::function<void(SmallVectorImpl<DiagnosticEntryInfo> &)>;
+
OperationKind OpKind;
llvm::Optional<uint64_t> OpId;
+ llvm::Optional<DiagnosticProvider> DiagProvider;
bool Enabled;
public:
@@ -116,13 +120,20 @@
OpId = startOperation(OpKind, Inv, OpArgs);
}
- void finish(ArrayRef<DiagnosticEntryInfo> Diagnostics = llvm::None) {
+ void finish() {
if (OpId.hasValue()) {
+ SmallVector<DiagnosticEntryInfo, 8> Diagnostics;
+ if (DiagProvider.hasValue())
+ (*DiagProvider)(Diagnostics);
operationFinished(OpId.getValue(), OpKind, Diagnostics);
OpId.reset();
}
}
+ void setDiagnosticProvider(DiagnosticProvider &&DiagProvider) {
+ assert(!this->DiagProvider.hasValue());
+ this->DiagProvider = std::move(DiagProvider);
+ }
};
} // namespace sourcekitd
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp
index 51487d7..a149d95 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp
@@ -512,8 +512,26 @@
SwiftASTManager::getInvocation(ArrayRef<const char *> OrigArgs,
StringRef PrimaryFile,
std::string &Error) {
+
+ DiagnosticEngine Diags(Impl.SourceMgr);
+ EditorDiagConsumer CollectDiagConsumer;
+ Diags.addConsumer(CollectDiagConsumer);
+
CompilerInvocation CompInvok;
- if (initCompilerInvocation(CompInvok, OrigArgs, PrimaryFile, Error)) {
+ if (initCompilerInvocation(CompInvok, OrigArgs, Diags, PrimaryFile, Error)) {
+ // We create a traced operation here to represent the failure to parse
+ // arguments since we cannot reach `createAST` where that would normally
+ // happen.
+ trace::TracedOperation TracedOp(trace::OperationKind::PerformSema);
+ if (TracedOp.enabled()) {
+ trace::SwiftInvocation TraceInfo;
+ trace::initTraceInfo(TraceInfo, PrimaryFile, OrigArgs);
+ TracedOp.setDiagnosticProvider(
+ [&CollectDiagConsumer](SmallVectorImpl<DiagnosticEntryInfo> &diags) {
+ CollectDiagConsumer.getAllDiagnostics(diags);
+ });
+ TracedOp.start(TraceInfo);
+ }
return nullptr;
}
@@ -794,13 +812,6 @@
for (auto &Content : Contents)
Stamps.push_back(Content.Stamp);
- trace::TracedOperation TracedOp(trace::OperationKind::PerformSema);
- trace::SwiftInvocation TraceInfo;
- if (TracedOp.enabled()) {
- trace::initTraceInfo(TraceInfo, InvokRef->Impl.Opts.PrimaryFile,
- InvokRef->Impl.Opts.Args);
- }
-
ASTUnitRef ASTRef = new ASTUnit(++ASTUnitGeneration, MgrImpl.Stats);
for (auto &Content : Contents) {
if (Content.Snapshot)
@@ -808,10 +819,20 @@
}
auto &CompIns = ASTRef->Impl.CompInst;
auto &Consumer = ASTRef->Impl.CollectDiagConsumer;
-
// Display diagnostics to stderr.
CompIns.addDiagnosticConsumer(&Consumer);
+ trace::TracedOperation TracedOp(trace::OperationKind::PerformSema);
+ trace::SwiftInvocation TraceInfo;
+ if (TracedOp.enabled()) {
+ trace::initTraceInfo(TraceInfo, InvokRef->Impl.Opts.PrimaryFile,
+ InvokRef->Impl.Opts.Args);
+ TracedOp.setDiagnosticProvider(
+ [&Consumer](SmallVectorImpl<DiagnosticEntryInfo> &diags) {
+ Consumer.getAllDiagnostics(diags);
+ });
+ }
+
CompilerInvocation Invocation;
InvokRef->Impl.Opts.applyToSubstitutingInputs(
Invocation, convertFileContentsToInputs(Contents));
@@ -875,12 +896,6 @@
// TypeResolver is set before.
ASTRef->Impl.TypeResolver = createLazyResolver(CompIns.getASTContext());
- if (TracedOp.enabled()) {
- SmallVector<DiagnosticEntryInfo, 8> Diagnostics;
- Consumer.getAllDiagnostics(Diagnostics);
- TracedOp.finish(Diagnostics);
- }
-
return ASTRef;
}
diff --git a/tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp b/tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp
index 59b1b92..5b9907c 100644
--- a/tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp
+++ b/tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp
@@ -119,6 +119,12 @@
UnresolvedInputFile->getBuffer(),
Lang.resolvePathSymlinks(UnresolvedInputFile->getBufferIdentifier()));
+ auto origBuffSize = InputFile->getBufferSize();
+ unsigned CodeCompletionOffset = Offset;
+ if (CodeCompletionOffset > origBuffSize) {
+ CodeCompletionOffset = origBuffSize;
+ }
+
CompilerInstance CI;
// Display diagnostics to stderr.
PrintingDiagnosticConsumer PrintDiags;
@@ -128,6 +134,16 @@
trace::TracedOperation TracedOp(trace::OperationKind::CodeCompletion);
if (TracedOp.enabled()) {
CI.addDiagnosticConsumer(&TraceDiags);
+ trace::SwiftInvocation SwiftArgs;
+ trace::initTraceInfo(SwiftArgs, InputFile->getBufferIdentifier(), Args);
+ TracedOp.setDiagnosticProvider(
+ [&TraceDiags](SmallVectorImpl<DiagnosticEntryInfo> &diags) {
+ TraceDiags.getAllDiagnostics(diags);
+ });
+ TracedOp.start(SwiftArgs,
+ {std::make_pair("OriginalOffset", std::to_string(Offset)),
+ std::make_pair("Offset",
+ std::to_string(CodeCompletionOffset))});
}
CompilerInvocation Invocation;
@@ -141,12 +157,6 @@
return false;
}
- auto origBuffSize = InputFile->getBufferSize();
- unsigned CodeCompletionOffset = Offset;
- if (CodeCompletionOffset > origBuffSize) {
- CodeCompletionOffset = origBuffSize;
- }
-
const char *Position = InputFile->getBufferStart() + CodeCompletionOffset;
std::unique_ptr<llvm::WritableMemoryBuffer> NewBuffer =
llvm::WritableMemoryBuffer::getNewUninitMemBuffer(
@@ -178,15 +188,6 @@
return true;
}
- if (TracedOp.enabled()) {
- trace::SwiftInvocation SwiftArgs;
- trace::initTraceInfo(SwiftArgs, InputFile->getBufferIdentifier(), Args);
- TracedOp.start(SwiftArgs,
- {std::make_pair("OriginalOffset", std::to_string(Offset)),
- std::make_pair("Offset",
- std::to_string(CodeCompletionOffset))});
- }
-
CloseClangModuleFiles scopedCloseFiles(
*CI.getASTContext().getClangModuleLoader());
SwiftConsumer.setContext(&CI.getASTContext(), &Invocation,
@@ -194,12 +195,6 @@
CI.performSema();
SwiftConsumer.clearContext();
- if (TracedOp.enabled()) {
- SmallVector<DiagnosticEntryInfo, 8> Diagnostics;
- TraceDiags.getAllDiagnostics(Diagnostics);
- TracedOp.finish(Diagnostics);
- }
-
return true;
}
diff --git a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
index 18903e8..bc4765d 100644
--- a/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
+++ b/tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp
@@ -139,6 +139,12 @@
};
static NotificationBuffer notificationBuffer;
+static void printBufferedNotifications() {
+ notificationBuffer.handleNotifications([](sourcekitd_response_t note) {
+ sourcekitd_response_description_dump_filedesc(note, STDOUT_FILENO);
+ });
+}
+
static int skt_main(int argc, const char **argv);
int main(int argc, const char **argv) {
@@ -173,12 +179,6 @@
#define REFACTORING(KIND, NAME, ID) Kind##Refactoring##KIND = sourcekitd_uid_get_from_cstr("source.refactoring.kind."#ID);
#include "swift/IDE/RefactoringKinds.def"
- auto printBufferedNotifications = []{
- notificationBuffer.handleNotifications([](sourcekitd_response_t note) {
- sourcekitd_response_description_dump_filedesc(note, STDOUT_FILENO);
- });
- };
-
// A test invocation may initialize the options to be used for subsequent
// invocations.
TestOptions InitOpts;
@@ -196,7 +196,6 @@
sourcekitd_shutdown();
return ret;
}
- printBufferedNotifications();
Args = Args.slice(i+1);
}
@@ -343,7 +342,9 @@
assert(Opts.repeatRequest >= 1);
for (unsigned i = 0; i < Opts.repeatRequest; ++i) {
- if (int ret = handleTestInvocation(Opts, InitOpts)) {
+ int ret = handleTestInvocation(Opts, InitOpts);
+ printBufferedNotifications();
+ if (ret) {
return ret;
}
}
diff --git a/tools/SourceKit/tools/swift-lang/SwiftLang.swift b/tools/SourceKit/tools/swift-lang/SwiftLang.swift
index 8aa9d30..40f19ee 100644
--- a/tools/SourceKit/tools/swift-lang/SwiftLang.swift
+++ b/tools/SourceKit/tools/swift-lang/SwiftLang.swift
@@ -14,22 +14,64 @@
import Foundation
+enum SourceKitdError: Error, CustomStringConvertible {
+ case EditorOpenError(message: String)
+ case EditorCloseError(message: String)
+
+ var description: String {
+ switch self {
+ case .EditorOpenError(let message):
+ return "cannot open document: \(message)"
+ case .EditorCloseError(let message):
+ return "cannot close document: \(message)"
+ }
+ }
+}
+
public class SwiftLang {
- /// Parses the Swift file at the provided URL into a `Syntax` tree in Json
- /// serialization format by querying SourceKitd service.
- /// - Parameter url: The URL you wish to parse.
- /// - Returns: The syntax tree in Json format string.
- public static func parse(_ url: URL) throws -> String {
+ fileprivate static func parse(content: String, name: String, isURL: Bool) throws -> String {
let Service = SourceKitdService()
let Request = SourceKitdRequest(uid: .request_EditorOpen)
- let Path = url.path
- Request.addParameter(.key_SourceFile, value: Path)
- Request.addParameter(.key_Name, value: Path)
+ if isURL {
+ Request.addParameter(.key_SourceFile, value: content)
+ } else {
+ Request.addParameter(.key_SourceText, value: content)
+ }
+ Request.addParameter(.key_Name, value: name)
Request.addParameter(.key_EnableSyntaxTree, value: 1)
+ Request.addParameter(.key_SyntacticOnly, value: 1)
// FIXME: SourceKitd error handling.
let Resp = Service.sendSyn(request: Request)
+ if Resp.isError {
+ throw SourceKitdError.EditorOpenError(message: Resp.description)
+ }
+
+ let CloseReq = SourceKitdRequest(uid: .request_EditorClose)
+ CloseReq.addParameter(.key_Name, value: name)
+ let CloseResp = Service.sendSyn(request: CloseReq)
+ if CloseResp.isError {
+ throw SourceKitdError.EditorCloseError(message: CloseResp.description)
+ }
return Resp.value.getString(.key_SerializedSyntaxTree)
}
-}
\ No newline at end of file
+
+ /// Parses the Swift file at the provided URL into a `Syntax` tree in Json
+ /// serialization format by querying SourceKitd service. This function isn't
+ /// thread safe.
+ /// - Parameter url: The URL you wish to parse.
+ /// - Returns: The syntax tree in Json format string.
+ public static func parse(_ url: URL) throws -> String {
+ let Path = url.path
+ return try parse(content: Path, name: Path, isURL: true)
+ }
+
+ /// Parses a given source buffer into a `Syntax` tree in Json serialization
+ /// format by querying SourceKitd service. This function isn't thread safe.
+ /// - Parameter source: The source buffer you wish to parse.
+ /// - Returns: The syntax tree in Json format string.
+ public static func parse(_ source: String) throws -> String {
+ return try parse(content: source, name: "foo", isURL: false)
+ }
+}
diff --git a/unittests/runtime/Stdlib.cpp b/unittests/runtime/Stdlib.cpp
index 6495133..7f70036 100644
--- a/unittests/runtime/Stdlib.cpp
+++ b/unittests/runtime/Stdlib.cpp
@@ -11,6 +11,7 @@
//===----------------------------------------------------------------------===//
#include "swift/Runtime/Metadata.h"
+#include "swift/Demangling/ManglingMacros.h"
using namespace swift;
@@ -135,6 +136,22 @@
abort();
}
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
+bool swift_unboxFromSwiftValueWithType(OpaqueValue *source,
+ OpaqueValue *result,
+ const Metadata *destinationType) {
+ abort();
+}
+
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_INTERNAL
+bool swift_swiftValueConformsTo(const Metadata *destinationType) {
+ abort();
+}
+
+SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API
+HeapObject *$Ss27_bridgeAnythingToObjectiveCyyXlxlF(OpaqueValue *src, const Metadata *srcType) {
+ abort();
+}
// ErrorObject