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

Invalid type lookup #1091

Closed
artyom-stv opened this issue Sep 5, 2022 · 7 comments · Fixed by #1179
Closed

Invalid type lookup #1091

artyom-stv opened this issue Sep 5, 2022 · 7 comments · Fixed by #1179
Assignees
Labels

Comments

@artyom-stv
Copy link

Hi!

I ran into a problem in my .swifttemplate template. It seems that the type of a Variable is resolved incorrectly if there is a nested and global type with the same name.

In the following example, the type of a Variable a is resolved to the global type A instead of the expected nested type X.A.

struct X {
  struct A {}
  struct B {}

  let a: A // variable.type?.globalName == "A"
  let b: B // variable.type?.globalName == "X.B"
}

struct A {}

Example (zip)

swift-driver version: 1.45.2 Apple Swift version 5.6.1 (swiftlang-5.6.0.323.66 clang-1316.0.20.12)
Sourcery version 1.8.2

@Nikoloutsos
Copy link

Nikoloutsos commented Sep 6, 2022

IIRC when I had this problem I used the full type and it was working well. in your example is X.A as the type of variable.

struct X {
  struct A {}
  struct B {}

  let a: X.A // variable.type?.globalName == "A"
  let b: X.B // variable.type?.globalName == "X.B"
}

@art-divin
Copy link
Collaborator

👋 Hey @artyom-stv ,

thank you very much for reporting and providing files, I was able to easily reproduce the issue.

Smallest data set to reproduce the issue is this:

struct X {
  struct A {}

  let a: A
}

struct A {}

I'm investigating and will keep you updated 👍

@art-divin art-divin added the bug label Jul 4, 2023
@art-divin art-divin self-assigned this Jul 4, 2023
@art-divin
Copy link
Collaborator

Investigation goes on, in the meanwhile:

SwiftSyntax does not embed nested type information after parsing the tree:

                  ▿ 0 : PatternBindingSyntax
                    - unexpectedBeforePattern : nil
                    ▿ pattern : IdentifierPatternSyntax
                      - unexpectedBeforeIdentifier : nil
                      ▿ identifier : identifier("a")
                        - text : "a"
                        ▿ leadingTrivia : []
                          - pieces : 0 elements
                        ▿ trailingTrivia : []
                          - pieces : 0 elements
                        ▿ tokenKind : TokenKind
                          - identifier : "a"
                      - unexpectedAfterIdentifier : nil
                    - unexpectedBetweenPatternAndTypeAnnotation : nil
                    ▿ ...
                        ▿ type : SimpleTypeIdentifierSyntax
                          - unexpectedBeforeName : nil
                          ▿ name : identifier("A")
                            - text : "A"
                            ▿ leadingTrivia : []
                              - pieces : 0 elements
                            ▿ trailingTrivia : []
                              - pieces : 0 elements
                            ▿ tokenKind : TokenKind
                              - identifier : "A"
                          - unexpectedBetweenNameAndGenericArgumentClause : nil
                          - genericArgumentClause : nil
                          - unexpectedAfterGenericArgumentClause : nil
                        - unexpectedAfterType : nil
                    - unexpectedBetweenTypeAnnotationAndInitializer : nil
                    - initializer : nil
                    - unexpectedBetweenInitializerAndAccessor : nil
                    - accessor : nil
                    - unexpectedBetweenAccessorAndTrailingComma : nil
                    - trailingComma : nil
                    - unexpectedAfterTrailingComma : nil

Then, it is parsed into Variable type as:

storedVariables = [Variable: name = a, typeName = A, isComputed = false, isAsync = false, `throws` = false, isStatic = false, readAccess = internal, writeAccess = , accessLevel = (read: SourceryRuntime.AccessLevel.internal, write: SourceryRuntime.AccessLevel.none), isMutable = false, defaultValue = nil, annotations = [:], documentation = [], attributes = [:], modifiers = [], isFinal = false, isLazy = false, definedInTypeName = Optional(X), actualDefinedInTypeName = Optional(X)]

Here, there's a possibility to check if the embedding struct has the same inner type as variable's type (or any other component type, maybe better to make this logic generic 🤷 ). Continuing ...

@krzysztofzablocki
Copy link
Owner

@art-divin the issue here is more of a resolver / combine phase issue rather than parsing, we build up tree correctly so we know there is X.A type and A, when we resolve types when combining multiple parser results we probably don't correctly match up

@art-divin
Copy link
Collaborator

Thanks @krzysztofzablocki , indeed, parsing is done correctly, the missing logic was in Variable implementation.

Creating MR, fixed 👍

@art-divin
Copy link
Collaborator

art-divin commented Jul 4, 2023

I suspect that MethodParameter and Method miss this logic also. Something to improve

@art-divin
Copy link
Collaborator

Addressed the reported issue in #1179

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

Successfully merging a pull request may close this issue.

4 participants