krzysztofzablocki / Sourcery

Meta-programming for Swift, stop writing boilerplate code.
http://merowing.info
MIT License
7.65k stars 617 forks source link

Support annotation array detection #302

Closed samskiter closed 6 years ago

samskiter commented 7 years ago

Im trying to loop over repeated annotations, except sometimes they might not be repeated.

How can I treat the annotation as an array even if it's only a single value?

ilyapuchka commented 7 years ago

Annotations are stored as a dictionary so you can access them by their name. In Stencil you can iterate over dictionary now, using swift templates it's just normal iteration over dictionary.

samskiter commented 7 years ago

Thanks for the fast reply @ilyapuchka - unfortunately don't seem to be able to get that working:

{% for type in types.protocols|annotated:"TypeErase" %}

{% for key, value in type.annotations %}{{ key }}{% endfor %}

{% endfor %}

This crashes with Note:'for' statements should use the following 'for x in y' 'for key, value in type.annotations'.

Running 0.6.0:

./Pods/Sourcery/bin/sourcery --version
0.6.0
ilyapuchka commented 7 years ago

And what is the crash?

samskiter commented 7 years ago

Whoops you beat me to it, was just updating my comment ^^

ilyapuchka commented 7 years ago

We didn't release a new version with Stencil 0.9.0 yet, so you need to use latest master version - CHANGELOG

samskiter commented 7 years ago

aha ok, thanks, i will try pointing my pod repo to you 👍

samskiter commented 7 years ago

@ilyapuchka Looks like your podspec doesn't work out of the box either. i'll see if I can work out how to fix it

ilyapuchka commented 7 years ago

CocoaPods will download latest release, so you should build from source code.

samskiter commented 7 years ago

@ilyapuchka you can use cocoapods to point to a git repo+sha right? I'm using pod 'Sourcery', :git => 'https://github.com/krzysztofzablocki/Sourcery.git', :commit => 'a6118efb5b9756eb59570e5e92b625c9b591fd24'

samskiter commented 7 years ago

Ahh i see, you pull from releases

samskiter commented 7 years ago

@ilyapuchka Have tried building from master, used the rake scripts to generate a new zip, then pointed to that locally using cocoapods. Getting a slightly different error message now:

error: /Users/samduke/Waking-iOS/scripts/Sourcery/Templates/TypeErase.stencil: 'for' statements should use the following 'for x in y where condition' `for key, value in type.annotations`.

It's now outputting as an error and there is some information about where conditions, so I'm certain I have a different build from your last release

samskiter commented 7 years ago

@ilyapuchka I got it working by iterating like so:

{% for type in types.protocols|annotated:"TypeErase" %}

{% for key,value in type.annotations %}{{ key }}{% endfor %}

{% endfor %}

But I still get an array for the dictionary values where "TypeErase" is a key

So I'm back to square one.

So for a file like this:

// sourcery: TypeErase = a
protocol bar {
associatedtype a
}

and a file like this:

// sourcery: TypeErase = a
// sourcery: TypeErase = b
protocol foo {
associatedtype a
associatedtype b
}

I'd like to be able to generate something like this

struct barStruct<a> {
}
struct fooStruct<a, b> {
}
samskiter commented 7 years ago

Hey again @ilyapuchka - I also brought this up on SwiftStencilKit here: https://github.com/SwiftGen/StencilSwiftKit/issues/44 and they suggested it might be best to always return an array for each annotation name...

ilyapuchka commented 7 years ago

Can you use macro node or swift templates as advised in #307?

bolismauro commented 7 years ago

@ilyapuchka @samskiter I decided to keep the ugly stencil I need to have rather than using swift. This is because the generation time is considerably higher than stencil

Antondomashnev commented 7 years ago

hey suggested it might be best to always return an array for each annotation name

@ilyapuchka @bolismauro I, actually, agree with that. I think it's confusing when the same code returns different type of object under different circumstances.

samskiter commented 7 years ago

I think that would be great. the only other useful thing to do would be either to define dictionaries through annotations or in some way allow splitting by a string (e.g. ',')

Antondomashnev commented 7 years ago

@samskiter you can take a look on #313, they're some proposals that could improve annotations 😄

haimwaking commented 7 years ago

I've run into this issue today, is there a resolution for this?

Antondomashnev commented 6 years ago

Hey @haimwaking @samskiter check out the https://github.com/krzysztofzablocki/Sourcery/pull/425

In the next Sourcery release you'll be able to use toArray filter to convert any value into array.

haimwaking commented 6 years ago

Cheers for that, looking forward!