Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check variable implements a protocol #40

Closed
bolismauro opened this issue Dec 17, 2016 · 9 comments
Closed

Check variable implements a protocol #40

bolismauro opened this issue Dec 17, 2016 · 9 comments

Comments

@bolismauro
Copy link

Hi!
First of all great work!
I had the same idea from months but I've never found the time to implement it. Very great work :)

I'm trying to understand how to check if a variable (of a struct) implements a protocol but I can't find a way.
Is it possible? it could be that I'm missing something though (I just started to try the project)

@ilyapuchka
Copy link
Collaborator

ilyapuchka commented Dec 17, 2016

Hi @bolismauro . Yes it is possible. When you have variable in the template just do {% if variable.type.inheritedTypes.Protocol %}. Probably in future we will add variable.type.implements just for protocols, but currently inheritedTypes contain all the types that given type inherits form or implements directly (meaning we currently do not flatten types hierarchy).

@bolismauro
Copy link
Author

bolismauro commented Dec 17, 2016

What I'm trying to achieve is this

{% for type in types.implementing.AutoEquatable %}
extension {{ type.name }}: Equatable {
  func == (lhs: {{ type.name }}, rhs: {{ type.name }}) -> Bool {
      {% for variable in type.storedVariables %}
        {% if variable.type.inheritedTypes.Equatable %}
        if lhs.{{ variable.name }} != rhs.{{ variable.name }} { return false }
        {% endif %
      {% endfor %}
      return true
  }
}
{% endfor %}

with this struct

struct Book: AutoEquatable {
  let name: String
  let author: String
  let numPages: Int
}

I get an empty file (completely empty). I guess there is some kind of problem in the template, because at least some part of the code should be generated.

Is it because I'm trying to work with types (Int, String, ...) that are not declared in the project but in the Apple framework?

@ilyapuchka
Copy link
Collaborator

ilyapuchka commented Dec 17, 2016

You should have AutoEquatable defined in your sources somewhere, do you? If you don't that might be the reason why you get an empty file. types.implementing and types.inheriting only contain known types, meaning that they are defined in processed sources so that we know either they are protocols or classes. If type is defined somewhere else it will be present in types.based only (this collection contains all the types, known and unknown).

For variables type property will be only set if the type is known. In case of String type we don't know what is this type and what protocols it implements, that's why inheritedTypes.Equatable will not work. You should add extension String: AutoEquatable {}, then you will be able to check it with variable.type.inheritedTypes.AutoEquatable.

@bolismauro
Copy link
Author

I tried it before writing but I didn't restart sourcery (it was in watch mode) and that's why I didn't see changes.

The problem is that I have to let sourcery find the Int: AutoEquatable but then it will also generate the equatable definition for the Int type, which is of course something wrong.
I guess I have to add another protocol like Skip to prevent this behaviour. Is there a better way?

In general I think it would be extremely useful to access to built-in types, but I guess it would take a lot of time to analyse all that code, right?

Thanks for the help :)

@krzysztofzablocki
Copy link
Owner

We could in theory run Sourcery against iOS frameworks and cache meta-data informations in the tool, but we'd need to make sure it's updated properly etc so not sure if that's something we should tackle yet.

@bolismauro you can use source annotations to skip, take a look at docs

@krzysztofzablocki
Copy link
Owner

I'll add ability to check conformance as in #42

@bolismauro
Copy link
Author

Makes sense @krzysztofzablocki
Thanks to both of you for the help. I think I've managed to do what I was trying to achieve :)

I think we can close this if it is ok for you

@krzysztofzablocki
Copy link
Owner

Glad to hear, we are very actively working on features so more and more should be possible with less burden soon :)

@bolismauro
Copy link
Author

For future reference
variable.type.inheritedTypes.PROTOCOL doesn't work
See also #42 and #43

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants