Skip to content

Commit

Permalink
Merge pull request mac-cain13#190 from mac-cain13/feature/stringsdict
Browse files Browse the repository at this point in the history
stringsdict support
  • Loading branch information
mac-cain13 committed May 2, 2016
2 parents ecffb7e + 4a2af9a commit f6e9b00
Show file tree
Hide file tree
Showing 17 changed files with 1,141 additions and 256 deletions.
8 changes: 8 additions & 0 deletions Documentation/Examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,11 @@ There are some points to keep in mind when using Color palettes, see [About Colo
let welcomeMessage = NSLocalizedString("welcome.message", comment: "")
let settingsTitle = NSLocalizedString("title", tableName: "Settings", comment: "")

// Formatted strings
let welcomeName = String(format: NSLocalizedString("welcome.withName", comment: ""), locale: NSLocale.currentLocale(), "Alice")

// Stringsdict files
let progress = String(format: NSLocalizedString("copy.progress", comment: ""), locale: NSLocale.currentLocale(), 4, 23)
```

*With R.swift*
Expand All @@ -87,7 +91,11 @@ let welcomeName = String(format: NSLocalizedString("welcome.withName", comment:
let welcomeMessage = R.string.localizable.welcomeMessage()
let settingsTitle = R.string.settings.title()

// Functions with parameters are generated for format strings
let welcomeName = R.string.localizable.welcomeWithName("Alice")

// Functions with named argument labels are generated for stringsdict keys
let progress = R.string.localizable.copyProgress(completed: 4, total: 23)
```

## Storyboards
Expand Down
36 changes: 24 additions & 12 deletions R.swift.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@

/* Begin PBXBuildFile section */
5D45C2191CA12913000B8DC9 /* StringsGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D997C941C7C291900B2F376 /* StringsGenerator.swift */; };
5D45C21B1CA1294A000B8DC9 /* LocalizableStrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D997C961C7C2BEE00B2F376 /* LocalizableStrings.swift */; };
5D997C951C7C291900B2F376 /* StringsGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D997C941C7C291900B2F376 /* StringsGenerator.swift */; };
5D997C971C7C2BEE00B2F376 /* LocalizableStrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D997C961C7C2BEE00B2F376 /* LocalizableStrings.swift */; };
D5646DE41BE2016E0034F4D7 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5646DE11BE2016E0034F4D7 /* Extensions.swift */; };
D5646DE51BE2016E0034F4D7 /* PBXObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5646DE21BE2016E0034F4D7 /* PBXObject.swift */; };
D5646DE61BE2016E0034F4D7 /* Serialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5646DE31BE2016E0034F4D7 /* Serialization.swift */; };
Expand Down Expand Up @@ -96,17 +94,22 @@
D5F97E4C1C1819160066D7C0 /* Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F97E411C1816360066D7C0 /* Image.swift */; };
D5F97E4D1C1819160066D7C0 /* ResourceFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F97E431C1816790066D7C0 /* ResourceFile.swift */; };
D5F97E4E1C1819160066D7C0 /* Nib.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5F97E451C18169E0066D7C0 /* Nib.swift */; };
E2156B8E1CC5254A00F341DC /* FormatSpecifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2156B8D1CC5254A00F341DC /* FormatSpecifier.swift */; };
E2156B8F1CC5255000F341DC /* FormatSpecifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2156B8D1CC5254A00F341DC /* FormatSpecifier.swift */; };
E2156B8E1CC5254A00F341DC /* StringParam.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2156B8D1CC5254A00F341DC /* StringParam.swift */; };
E2156B8F1CC5255000F341DC /* StringParam.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2156B8D1CC5254A00F341DC /* StringParam.swift */; };
E22D43631C9582CA00692FFF /* ColorGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E22D43621C9582CA00692FFF /* ColorGenerator.swift */; };
E22D43651C95845200692FFF /* ColorPalette.swift in Sources */ = {isa = PBXBuildFile; fileRef = E22D43641C95845200692FFF /* ColorPalette.swift */; };
E241E4A11CD6545200F449E3 /* Unifiable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2A918741CD4B61200394F6F /* Unifiable.swift */; };
E24720CB1C96B6A600DF291D /* ColorPalette.swift in Sources */ = {isa = PBXBuildFile; fileRef = E22D43641C95845200692FFF /* ColorPalette.swift */; };
E24720CC1C96B6AB00DF291D /* ColorGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = E22D43621C9582CA00692FFF /* ColorGenerator.swift */; };
E2762AC71CCCEC2A0009BCAA /* Locale.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2762AC61CCCEC2A0009BCAA /* Locale.swift */; };
E2762AC91CCCEE120009BCAA /* Locale.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2762AC61CCCEC2A0009BCAA /* Locale.swift */; };
E2762ACF1CCD0B970009BCAA /* LocalizableStrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2762ACE1CCD0B970009BCAA /* LocalizableStrings.swift */; };
E2762AD01CCD0CF90009BCAA /* LocalizableStrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2762ACE1CCD0B970009BCAA /* LocalizableStrings.swift */; };
E2A918751CD4B61200394F6F /* Unifiable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E2A918741CD4B61200394F6F /* Unifiable.swift */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
5D997C941C7C291900B2F376 /* StringsGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringsGenerator.swift; sourceTree = "<group>"; };
5D997C961C7C2BEE00B2F376 /* LocalizableStrings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocalizableStrings.swift; sourceTree = "<group>"; };
D5646DE11BE2016E0034F4D7 /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = "<group>"; };
D5646DE21BE2016E0034F4D7 /* PBXObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PBXObject.swift; sourceTree = "<group>"; };
D5646DE31BE2016E0034F4D7 /* Serialization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Serialization.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -153,9 +156,12 @@
D5F97E411C1816360066D7C0 /* Image.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Image.swift; sourceTree = "<group>"; };
D5F97E431C1816790066D7C0 /* ResourceFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResourceFile.swift; sourceTree = "<group>"; };
D5F97E451C18169E0066D7C0 /* Nib.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Nib.swift; sourceTree = "<group>"; };
E2156B8D1CC5254A00F341DC /* FormatSpecifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormatSpecifier.swift; sourceTree = "<group>"; };
E2156B8D1CC5254A00F341DC /* StringParam.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringParam.swift; sourceTree = "<group>"; };
E22D43621C9582CA00692FFF /* ColorGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorGenerator.swift; sourceTree = "<group>"; };
E22D43641C95845200692FFF /* ColorPalette.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ColorPalette.swift; sourceTree = "<group>"; };
E2762AC61CCCEC2A0009BCAA /* Locale.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Locale.swift; sourceTree = "<group>"; };
E2762ACE1CCD0B970009BCAA /* LocalizableStrings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocalizableStrings.swift; sourceTree = "<group>"; };
E2A918741CD4B61200394F6F /* Unifiable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Unifiable.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -279,14 +285,16 @@
D5F97E3F1C1815E70066D7C0 /* AssetFolder.swift */,
E22D43641C95845200692FFF /* ColorPalette.swift */,
D5F97E391C1812AE0066D7C0 /* Font.swift */,
E2156B8D1CC5254A00F341DC /* FormatSpecifier.swift */,
D5F97E411C1816360066D7C0 /* Image.swift */,
5D997C961C7C2BEE00B2F376 /* LocalizableStrings.swift */,
E2762AC61CCCEC2A0009BCAA /* Locale.swift */,
E2762ACE1CCD0B970009BCAA /* LocalizableStrings.swift */,
D5F97E451C18169E0066D7C0 /* Nib.swift */,
D5F97E431C1816790066D7C0 /* ResourceFile.swift */,
D5F97E371C178A4F0066D7C0 /* Resources.swift */,
D59F723E1C19651F0089767C /* ReusableContainer.swift */,
D5F97E3B1C1813A70066D7C0 /* Storyboard.swift */,
E2156B8D1CC5254A00F341DC /* StringParam.swift */,
E2A918741CD4B61200394F6F /* Unifiable.swift */,
D5B799781C19C082009EA901 /* WhiteListedExtensionsResourceType.swift */,
D5F97E3D1C1815780066D7C0 /* Xcodeproj.swift */,
);
Expand Down Expand Up @@ -421,9 +429,11 @@
D5B799771C199755009EA901 /* StoryboardGenerator.swift in Sources */,
D5B799811C1B0943009EA901 /* ErrorOutput.swift in Sources */,
D5F12D431BDACB87009A2C88 /* ResourceGenerator.swift in Sources */,
E2762AC91CCCEE120009BCAA /* Locale.swift in Sources */,
D5F97E4A1C1819160066D7C0 /* Storyboard.swift in Sources */,
5D45C2191CA12913000B8DC9 /* StringsGenerator.swift in Sources */,
D5B129B21C3BA75A00A1C5FC /* Property.swift in Sources */,
E2762AD01CCD0CF90009BCAA /* LocalizableStrings.swift in Sources */,
D59F72401C19651F0089767C /* ReusableContainer.swift in Sources */,
D5B799741C199755009EA901 /* ResourceFileGenerator.swift in Sources */,
D5B799751C199755009EA901 /* ReuseIdentifierGenerator.swift in Sources */,
Expand All @@ -435,7 +445,6 @@
D5F97E4B1C1819160066D7C0 /* AssetFolder.swift in Sources */,
D5F12D421BDACB87009A2C88 /* input.swift in Sources */,
D5F795C11BB9983900844EA2 /* MainTests.swift in Sources */,
5D45C21B1CA1294A000B8DC9 /* LocalizableStrings.swift in Sources */,
D59F723D1C1964B20089767C /* Typealias.swift in Sources */,
D5F12D481BDACB8E009A2C88 /* XCProjectFile.swift in Sources */,
D5B7998A1C1B91A9009EA901 /* Module.swift in Sources */,
Expand All @@ -448,10 +457,11 @@
D586724A1C21FF7D00A760EC /* TypeSequenceProvider.swift in Sources */,
D5F97E4E1C1819160066D7C0 /* Nib.swift in Sources */,
D59F72311C19644F0089767C /* Function.swift in Sources */,
E241E4A11CD6545200F449E3 /* Unifiable.swift in Sources */,
D5B799721C199755009EA901 /* ImageGenerator.swift in Sources */,
D5B7997A1C19C1BD009EA901 /* WhiteListedExtensionsResourceType.swift in Sources */,
D59F722A1C1963EA0089767C /* Struct.swift in Sources */,
E2156B8F1CC5255000F341DC /* FormatSpecifier.swift in Sources */,
E2156B8F1CC5255000F341DC /* StringParam.swift in Sources */,
D5A0A82E1C4793C20089ED2C /* TypePrinter.swift in Sources */,
D5A0A82D1C4793C20089ED2C /* SwiftCodeConverible.swift in Sources */,
D5B799731C199755009EA901 /* NibGenerator.swift in Sources */,
Expand All @@ -473,18 +483,21 @@
files = (
5D997C951C7C291900B2F376 /* StringsGenerator.swift in Sources */,
D5B799831C1B8C78009EA901 /* Module.swift in Sources */,
E2156B8E1CC5254A00F341DC /* FormatSpecifier.swift in Sources */,
E2156B8E1CC5254A00F341DC /* StringParam.swift in Sources */,
D5C5A8EF1BB7196000163E71 /* Core.swift in Sources */,
D58672491C21FC9700A760EC /* TypeSequenceProvider.swift in Sources */,
D5F97E461C18169E0066D7C0 /* Nib.swift in Sources */,
D59F72391C1964950089767C /* Var.swift in Sources */,
D5B7997F1C1B07EB009EA901 /* ErrorOutput.swift in Sources */,
E2A918751CD4B61200394F6F /* Unifiable.swift in Sources */,
D5B129B11C3BA65C00A1C5FC /* Property.swift in Sources */,
E22D43651C95845200692FFF /* ColorPalette.swift in Sources */,
D5F97E421C1816360066D7C0 /* Image.swift in Sources */,
D56F923D1C29421600177FF7 /* TypeVar.swift in Sources */,
D5B7996E1C19940F009EA901 /* ResourceFileGenerator.swift in Sources */,
E2762ACF1CCD0B970009BCAA /* LocalizableStrings.swift in Sources */,
D5F97E401C1815E70066D7C0 /* AssetFolder.swift in Sources */,
E2762AC71CCCEC2A0009BCAA /* Locale.swift in Sources */,
D5F97E3C1C1813A70066D7C0 /* Storyboard.swift in Sources */,
D59F723C1C1964B20089767C /* Typealias.swift in Sources */,
D5B799661C19939D009EA901 /* SegueGenerator.swift in Sources */,
Expand All @@ -508,7 +521,6 @@
D5B7996A1C1993E3009EA901 /* NibGenerator.swift in Sources */,
E22D43631C9582CA00692FFF /* ColorGenerator.swift in Sources */,
D5646DE51BE2016E0034F4D7 /* PBXObject.swift in Sources */,
5D997C971C7C2BEE00B2F376 /* LocalizableStrings.swift in Sources */,
D56DC76D1C41758800623437 /* AccessModifier.swift in Sources */,
D5B129AF1C3BA5F900A1C5FC /* Let.swift in Sources */,
D5B7997D1C1B07C3009EA901 /* SanitizedSwiftName.swift in Sources */,
Expand Down
71 changes: 38 additions & 33 deletions R.swift/Generators/StringsGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,17 @@ struct StringsGenerator: Generator {

// Ahem, this code is a bit of a mess. It might need cleaning up... ;-)
// Maybe when we pick up this issue: https://github.com/mac-cain13/R.swift/issues/136
private static func computeParams(filename: String, strings: [LocalizableStrings]) -> [StringValues]
{
var allParams: [String: [(Locale, String, [FormatSpecifier])]] = [:]
let baseKeys = strings
.filter { $0.locale.isBase }
.map { Set($0.dictionary.keys) }
.first
private static func computeParams(filename: String, strings: [LocalizableStrings]) -> [StringValues] {

var allParams: [String: [(Locale, String, [StringParam])]] = [:]
let baseKeys: Set<String>?
let bases = strings.filter { $0.locale.isBase }
if bases.isEmpty {
baseKeys = nil
}
else {
baseKeys = Set(bases.flatMap { $0.dictionary.keys })
}

// Warnings about duplicates and empties
for ls in strings {
Expand All @@ -85,23 +89,23 @@ struct StringsGenerator: Generator {

// Save uniques
for key in groupedKeys.uniques {
if let (value, params) = ls.dictionary[key] {
if let (params, commentValue) = ls.dictionary[key] {
if let _ = allParams[key] {
allParams[key]?.append((ls.locale, value, params))
allParams[key]?.append((ls.locale, commentValue, params))
}
else {
allParams[key] = [(ls.locale, value, params)]
allParams[key] = [(ls.locale, commentValue, params)]
}
}
}
}

// Warnings about missing translations
for ls in strings {
let filenameLocale = ls.locale.withFilename(filename)
for (locale, lss) in strings.groupBy({ $0.locale }) {
let filenameLocale = locale.withFilename(filename)
let sourceKeys = baseKeys ?? Set(allParams.keys)

let missing = sourceKeys.subtract(ls.dictionary.keys)
let missing = sourceKeys.subtract(lss.flatMap { $0.dictionary.keys })

if missing.isEmpty {
continue
Expand All @@ -126,12 +130,12 @@ struct StringsGenerator: Generator {
var badFormatSpecifiersKeys = Set<String>()

// Unify format specifiers
for (key, params) in allParams.filter({ includeTranslation($0.0) }).sortBy({ $0.0 }) {
var formatSpecifiers: [FormatSpecifier] = []
for (key, keyParams) in allParams.filter({ includeTranslation($0.0) }).sortBy({ $0.0 }) {
var params: [StringParam] = []
var areCorrectFormatSpecifiers = true

for (locale, _, fs) in params {
if fs.contains(FormatSpecifier.TopType) {
for (locale, _, ps) in keyParams {
if ps.any({ $0.spec == FormatSpecifier.TopType }) {
let name = locale.withFilename(filename)
warn("Skipping string \(key) in \(name), not all format specifiers are consecutive")

Expand All @@ -141,13 +145,9 @@ struct StringsGenerator: Generator {

if !areCorrectFormatSpecifiers { continue }

for (_, _, fs) in params {
let length = min(formatSpecifiers.count, fs.count)

if formatSpecifiers.prefix(length) == fs.prefix(length) {
if fs.count > formatSpecifiers.count {
formatSpecifiers = fs
}
for (_, _, ps) in keyParams {
if let unified = params.unify(ps) {
params = unified
}
else {
badFormatSpecifiersKeys.insert(key)
Expand All @@ -158,8 +158,8 @@ struct StringsGenerator: Generator {

if !areCorrectFormatSpecifiers { continue }

let vals = params.map { ($0.0, $0.1) }
let values = StringValues(key: key, params: formatSpecifiers, tableName: filename, values: vals )
let vals = keyParams.map { ($0.0, $0.1) }
let values = StringValues(key: key, params: params, tableName: filename, values: vals )
results.append(values)
}

Expand Down Expand Up @@ -219,18 +219,23 @@ struct StringsGenerator: Generator {

private static func stringFunctionParams(values: StringValues) -> Function {

let params = values.params.enumerate().map { ix, formatSpecifier -> Function.Parameter in
let name = "value\(ix + 1)"
let params = values.params.enumerate().map { ix, param -> Function.Parameter in
let valueName = "value\(ix + 1)"

if ix == 0 {
return Function.Parameter(name: name, type: formatSpecifier.type)
if let paramName = param.name {
return Function.Parameter(name: paramName, localName: valueName, type: param.spec.type)
}
else {
return Function.Parameter(name: "_", localName: name, type: formatSpecifier.type)
if ix == 0 {
return Function.Parameter(name: valueName, type: param.spec.type)
}
else {
return Function.Parameter(name: "_", localName: valueName, type: param.spec.type)
}
}
}

let args = params.enumerate().map { ix, _ in "value\(ix + 1)" }.joinWithSeparator(", ")
let args = params.map { $0.localName ?? $0.name }.joinWithSeparator(", ")

return Function(
comments: values.comments,
Expand Down Expand Up @@ -261,7 +266,7 @@ extension Locale {

private struct StringValues {
let key: String
let params: [FormatSpecifier]
let params: [StringParam]
let tableName: String
let values: [(Locale, String)]

Expand Down
Loading

0 comments on commit f6e9b00

Please sign in to comment.