Skip to content

Conversation

fjtrujy
Copy link

@fjtrujy fjtrujy commented Mar 29, 2020

Description

This PR fixes issues with plists/inline-swift4.stencil or plists/inline-swift5.stencil templates to generate the content of a list that contains arrays.

So far the content of the plist is:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Names</key>
	<array>
		<string>Jhon</string>
		<string>Peter</string>
		<string>Nick</string>
	</array>
	<key>Surnames</key>
	<array>
		<string>Smith</string>
		<string>Jhonson</string>
		<string>Williams</string>
	</array>
</dict>
</plist>

And visually it looks:

Screenshot 2019-10-30 at 12 53 11

Then in the .swiftgen.yml I just have somethings as:

.........
plist:
    inputs: Precompile/OriginPlists/
    outputs:
        templateName: inline-swift4
        output: Generated/Plist.swift
.....

When I execute it, it generates wrong data:

internal static let names: [String] = [Jhon, Peter, Nick]
internal static let surnames: [String] = [Smith, Jhonson, Williams]

If you see it misses the quotes in every single element in the array, and in the plist, they are declared as String

Digging into the template I found where the issue "could be", I have created a solution, I tried locally and is working fine, but I don't know if this is breaking something else. Besides I see that the same logic is applied in several templates, so not sure if in these templates is broken as well.

The solution that I applied in the plists/inline-swift4.stencil was:

@@ -55,9 +55,9 @@ import Foundation
     Date(timeIntervalSinceReferenceDate: {{ value.timeIntervalSinceReferenceDate }})
   {% elif metadata.type == "Optional" %}
     nil
-  {% elif metadata.type == "Array" and metadata.element.items %}
-    [{% for itemMetadata in metadata.element.items %}
-      {% call valueBlock value[forloop.counter0] itemMetadata %}
+  {% elif metadata.type == "Array" and value %}
+    [{% for currentValue in value %}
+      {% call valueBlock currentValue metadata.element %}
       {% if not forloop.last %}, {% endif %}
     {% endfor %}]
   {% elif metadata.type == "Dictionary" %}

The new output is:

internal static let names: [String] = ["Jhon", "Peter", "Nick"]
internal static let surnames: [String] = ["Smith", "Jhonson", "Williams"]

🎉 🎉 🎉 🎉 🎉 🎉 🎉

Here you have the reference to the specific github issue that I created time ago. #662

Thanks!

@SwiftGen-Eve
Copy link

SwiftGen-Eve commented Mar 29, 2020

Hey 👋 I'm Eve, the friendly bot watching over SwiftGen 🤖

Thanks a lot for your contribution!


Seems like everything is in order 👍 You did a good job here! 🤝

Generated by 🚫 Danger

@AliSoftware
Copy link
Collaborator

Thanks for the PR!

It seems you didn't update the tests accordingly (or didn't add a test to cover this case that we missed). Could you add one please?
Also don't forget to credit yourself in the CHANGELOG ;)

@djbe djbe added this to the 6.2.1 milestone May 17, 2020
fjtrujy pushed a commit to fjtrujy/SwiftGen that referenced this pull request May 18, 2020
@fjtrujy
Copy link
Author

fjtrujy commented May 18, 2020

Hello,
@AliSoftware I will try to create a proper test to fix this issue.
Thanks!

# Conflicts:
#	CHANGELOG.md
#	templates/plist/inline-swift4.stencil
#	templates/plist/inline-swift5.stencil
@djbe
Copy link
Member

djbe commented Jun 20, 2020

  • I actually started updating this PR, and noticed the same change could be applied to json/yaml inline templates.
  • Then after generating code (and adding a test case), I also noticed that this fix actually breaks code generation for mixed arrays ([Any]).
  • Furthermore, I tried testing the old template with the given test case, and it just works...

Added my findings to #662, will need more testing to see if we actually need a PR.
Edit: I wasn't pressing the right test shortcut 🤦

@djbe
Copy link
Member

djbe commented Jun 20, 2020

Clarification for these latest changes:

  • Old template assumed that there was always going to be metadata.element.items[...], which isn't true for homogeneous arrays such as [String]
  • The initial fix always passed along metadata.element, which isn't correct for mixed arrays, where we need the right metadata for each item.
  • Correct solution is to try to use metadata for specific item, and fallback to general element metadata.

@fjtrujy
Copy link
Author

fjtrujy commented Jun 22, 2020

Thanks @djbe for progressing with the work.
I was not able to finish it.
Thanks again

# Conflicts:
#	CHANGELOG.md
@djbe djbe requested a review from AliSoftware June 23, 2020 22:06
@djbe djbe mentioned this pull request Jun 24, 2020
12 tasks
Copy link
Collaborator

@AliSoftware AliSoftware left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix for the particular problem looks good to me.

But I think we might have another issue (and likely not just with strings in arrays but with strings in general) when they contain escaped quotes…
(Feel free to decide if it's better to either fix this in this current PR or to split that in a separate one)

@djbe djbe merged commit 59fd59d into SwiftGen:develop Jun 24, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants