Skip to content

Commit 8aec40d

Browse files
committed
---
yaml --- r: 346833 b: refs/heads/master c: c99da10 h: refs/heads/master i: 346831: c4d1dc0
1 parent a59b26e commit 8aec40d

File tree

10 files changed

+151
-5
lines changed

10 files changed

+151
-5
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 452429d8d0a279423300d710375e6bb1304b6db5
2+
refs/heads/master: c99da10924b5c5f246808082dc41def5397578e2
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/lib/Frontend/ParseableInterfaceSupport.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ bool ParseableInterfaceModuleLoader::buildSwiftModuleFromSwiftInterface(
452452
return;
453453
}
454454

455-
SubError = Diags.hadAnyError();
455+
SubError = SubInstance.getDiags().hadAnyError();
456456
});
457457
return !RunSuccess || SubError;
458458
}

trunk/stdlib/public/Darwin/Foundation/NSValue.swift.gyb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,31 @@ ${ ObjectiveCBridgeableImplementationForNSValue("CGVector") }
2323
${ ObjectiveCBridgeableImplementationForNSValue("CGSize") }
2424
${ ObjectiveCBridgeableImplementationForNSValue("CGAffineTransform") }
2525

26+
extension NSValue {
27+
public func value<StoredType>(of type: StoredType.Type) -> StoredType? {
28+
if StoredType.self is AnyObject.Type {
29+
let encoding = String(cString: objCType)
30+
// some subclasses of NSValue can return @ and the default initialized variant returns ^v for encoding
31+
guard encoding == "^v" || encoding == "@" else {
32+
return nil
33+
}
34+
return nonretainedObjectValue as? StoredType
35+
} else if _isPOD(StoredType.self) {
36+
var storedSize = 0
37+
var storedAlignment = 0
38+
NSGetSizeAndAlignment(objCType, &storedSize, &storedAlignment)
39+
guard MemoryLayout<StoredType>.size == storedSize && MemoryLayout<StoredType>.alignment == storedAlignment else {
40+
return nil
41+
}
42+
let allocated = UnsafeMutablePointer<StoredType>.allocate(capacity: 1)
43+
defer { allocated.deallocate() }
44+
if #available(OSX 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) {
45+
getValue(allocated, size: storedSize)
46+
} else {
47+
getValue(allocated)
48+
}
49+
return allocated.pointee
50+
}
51+
return nil
52+
}
53+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/modulecache)
3+
//
4+
// Setup builds a parseable interface for a module SomeModule (built from some-module.swift).
5+
// This test checks we still build and load its corresponding .swiftmodule when the file that imports it contains an error prior to the import statement.
6+
7+
// Setup phase 1: Write the input file.
8+
//
9+
// RUN: echo 'public func SomeFunc() -> Int { return 42; }' >>%t/some-module.swift
10+
11+
// Setup phase 2: build the module.
12+
//
13+
// RUN: %target-swift-frontend -I %t -emit-parseable-module-interface-path %t/SomeModule.swiftinterface -module-name SomeModule %t/some-module.swift -emit-module -o /dev/null
14+
15+
// Actual test: compile and verify the import succeeds (i.e. we only report the error in this file)
16+
//
17+
// RUN: %target-swift-frontend -typecheck -verify -I %t -module-cache-path %t/modulecache -enable-parseable-module-interface %s
18+
19+
unresolved // expected-error {{use of unresolved identifier 'unresolved'}}
20+
21+
import SomeModule
22+
23+
print(SomeFunc())
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
public struct MyPoint {
2+
public let x: Double
3+
public let y: Double
4+
5+
public init(x: Double, y: Double) {
6+
self.x = x
7+
self.y = y
8+
}
9+
10+
public var magnitudeSquared: Double {
11+
return x*x + y*y
12+
}
13+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import MyPoint
2+
3+
public extension MyPoint {
4+
var magnitude: Double {
5+
return magnitudeSquared.squareRoot()
6+
}
7+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/modulecache)
3+
4+
// 1) Build .swiftinterface files for MyPoint and MyExtensions, using a non-default module cache path
5+
// RUN: %target-swift-frontend -emit-parseable-module-interface-path %t/MyPoint.swiftinterface -module-name MyPoint -emit-module -o /dev/null %S/Inputs/parseable-interface/MyPoint.swift
6+
// RUN: %target-swift-frontend -emit-parseable-module-interface-path %t/MyPointExtensions.swiftinterface -module-name MyPointExtensions -emit-module -o /dev/null -enable-parseable-module-interface -module-cache-path %t/modulecache -I %t %S/Inputs/parseable-interface/MyPointExtensions.swift
7+
// RUN: %empty-directory(%t/modulecache)
8+
9+
// 2) Check completion using the default (cold) module cache
10+
// RUN: %target-swift-ide-test -code-completion -code-completion-token=MEMBER -source-filename %s -I %t | %FileCheck %s
11+
12+
// 3) Check completion again with a warm module cache
13+
// RUN: %target-swift-ide-test -code-completion -code-completion-token=MEMBER -source-filename %s -I %t | %FileCheck %s
14+
15+
import MyPoint
16+
import MyPointExtensions
17+
18+
let x = MyPoint(x: 1, y: 10.5)
19+
20+
print(x.#^MEMBER^#)
21+
22+
// CHECK: Begin completions, 5 items
23+
// CHECK: Keyword[self]/CurrNominal: self[#MyPoint#]; name=self
24+
// CHECK: Decl[InstanceVar]/CurrNominal: x[#Double#]; name=x
25+
// CHECK: Decl[InstanceVar]/CurrNominal: y[#Double#]; name=y
26+
// CHECK: Decl[InstanceVar]/CurrNominal: magnitudeSquared[#Double#]; name=magnitudeSquared
27+
// CHECK: Decl[InstanceVar]/CurrNominal: magnitude[#Double#]; name=magnitude
28+
// CHECK: End completions

trunk/test/stdlib/NSValueBridging.swift.gyb

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,31 @@ nsValueBridging.test("NSValue can only be cast back to its original type") {
9191
_ = rangeObject as! CGRect
9292
}
9393

94+
nsValueBridging.test("NSValue fetching method should be able to convert constructed values safely") {
95+
let range = NSRange(location: 17, length: 38)
96+
let value = NSValue(range: range)
97+
expectEqual(value.value(of: NSRange.self)?.location, range.location)
98+
expectEqual(value.value(of: NSRange.self)?.length, range.length)
99+
expectEqual(value.value(of: CGRect.self), .none)
100+
expectEqual(value.value(of: String.self), .none)
101+
expectTrue(value.value(of: AnyObject.self) == nil)
102+
103+
104+
class GenericThingNotRootedInObjC<T> {
105+
init() { }
106+
}
107+
108+
let obj = GenericThingNotRootedInObjC<String>()
109+
// extend the lifetime to ensure that the non retained pointer is valid for the test duration
110+
withExtendedLifetime(obj) { () -> Void in
111+
let value = NSValue(nonretainedObject: obj)
112+
let resString = value.value(of: GenericThingNotRootedInObjC<String>.self)
113+
expectEqual(resString === obj, true) // ensure the value is exactly the same
114+
115+
let resInt = value.value(of: GenericThingNotRootedInObjC<Int>.self)
116+
expectTrue(resInt == nil)
117+
}
118+
119+
}
120+
94121
runAllTests()

trunk/tools/swift-ide-test/swift-ide-test.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,12 @@ static llvm::cl::opt<std::string>
264264
ModuleCachePath("module-cache-path", llvm::cl::desc("Clang module cache path"),
265265
llvm::cl::cat(Category));
266266

267+
static llvm::cl::opt<bool>
268+
EnableParseableModuleInterface("enable-parseable-module-interface",
269+
llvm::cl::desc("Enable loading .swiftinterface files when available"),
270+
llvm::cl::cat(Category),
271+
llvm::cl::init(true));
272+
267273
static llvm::cl::opt<std::string>
268274
PCHOutputDir("pch-output-dir",
269275
llvm::cl::desc("place autogenerated PCH files in this directory"),
@@ -3201,6 +3207,8 @@ int main(int argc, char *argv[]) {
32013207
InitInvok.getLangOptions().EffectiveLanguageVersion = actual.getValue();
32023208
}
32033209
}
3210+
InitInvok.getFrontendOptions().EnableParseableModuleInterface =
3211+
options::EnableParseableModuleInterface;
32043212
InitInvok.getClangImporterOptions().ModuleCachePath =
32053213
options::ModuleCachePath;
32063214
InitInvok.getClangImporterOptions().PrecompiledHeaderOutputDir =

trunk/utils/gyb_foundation_support.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ def ObjectiveCBridgeableImplementationForNSValue(Type):
1212
_getObjCTypeEncoding({Type}.self)) == 0,
1313
"NSValue does not contain the right type to bridge to {Type}")
1414
result = {Type}()
15-
source.getValue(&result!)
15+
if #available(OSX 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) {{
16+
source.getValue(&result!, size: MemoryLayout<{Type}>.size)
17+
}} else {{
18+
source.getValue(&result!)
19+
}}
1620
}}
1721
1822
public static func _conditionallyBridgeFromObjectiveC(_ source: NSValue,
@@ -23,7 +27,11 @@ def ObjectiveCBridgeableImplementationForNSValue(Type):
2327
return false
2428
}}
2529
result = {Type}()
26-
source.getValue(&result!)
30+
if #available(OSX 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) {{
31+
source.getValue(&result!, size: MemoryLayout<{Type}>.size)
32+
}} else {{
33+
source.getValue(&result!)
34+
}}
2735
return true
2836
}}
2937
@@ -34,7 +42,11 @@ def ObjectiveCBridgeableImplementationForNSValue(Type):
3442
_getObjCTypeEncoding({Type}.self)) == 0,
3543
"NSValue does not contain the right type to bridge to {Type}")
3644
var result = {Type}()
37-
unwrappedSource.getValue(&result)
45+
if #available(OSX 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0, *) {{
46+
unwrappedSource.getValue(&result, size: MemoryLayout<{Type}>.size)
47+
}} else {{
48+
unwrappedSource.getValue(&result)
49+
}}
3850
return result
3951
}}
4052
}}

0 commit comments

Comments
 (0)