Skip to content

Conversation

Kyle-Ye
Copy link
Contributor

@Kyle-Ye Kyle-Ye commented Dec 11, 2021

The Symbol.swift currently has 1400 lines.

This PR is intended to split the Symbol.swift file into a file system hierarchy.

So that the Symbol.swift only have SymbolGraph.Symbol definition and also makes it easier for writing test case.

Discussion

  • Which style do you prefer?
- Symbol
	- Availability
		- Availability.swift
		- Domain.swift
	- Symbol.swift  	

Or

- Symbol
	- Availability
		- Domain.swift
	- Availability.swift
- Symbol.swift  	
  • What should we do if there are 2 struct/enum both named as "Kind"

Currently there are SymbolGraph.Symbol.DeclarationFragments.Fragment.Kind and SymbolGraph.Symbol.Kind.

Although they are not in the same folder, they are in the same module. Which is not allowed by Swift

error: filename "Kind.swift" used twice: 'Symbol/DeclarationFragments/Fragment/Kind.swift' and 'SymbolKit/SymbolGraph/Symbol/Kind.swift'
note: filenames are used to distinguish private declarations with the same name

https://belkadan.com/blog/2021/11/Swift-Mangling-Regret-Private-Discriminators/

Status

  • WIP
    After the above 2 discussion is solved, I'll complete the full PR.

@franklinsch
Copy link
Contributor

Thanks for taking this initiative, @Kyle-Ye! I agree, the Symbol.swift file is quite long and becoming hard to navigate. I personally prefer the first approach you propose. I also don't think that the type hierarchy necessarily needs to be reflected in the directory structure. I think the organization you're proposing makes sense though.

Regarding the collision of Kind, one convention I've seen is adding a + in the file name for extensions, for example Fragment+Kind.swift and Symbol+Kind.swift. To follow this convention pedantically, we'd have SymbolGraph+Symbol+Kind.swift, SymbolGraph+Symbol+Identifier.swift etc., but I think the directory structure you're proposing is better suited.

@Kyle-Ye
Copy link
Contributor Author

Kyle-Ye commented Dec 13, 2021

Thanks for taking this initiative, @Kyle-Ye! I agree, the Symbol.swift file is quite long and becoming hard to navigate. I personally prefer the first approach you propose. I also don't think that the type hierarchy necessarily needs to be reflected in the directory structure. I think the organization you're proposing makes sense though.

Regarding the collision of Kind, one convention I've seen is adding a + in the file name for extensions, for example Fragment+Kind.swift and Symbol+Kind.swift. To follow this convention pedantically, we'd have SymbolGraph+Symbol+Kind.swift, SymbolGraph+Symbol+Identifier.swift etc., but I think the directory structure you're proposing is better suited.

Got it. Maybe we could combine them to be the following:

For node struct: parent/node/node.swift
For leaf struct: parent/parent+leaf.swift

Node struct means it has other struct defined in its namespace

Thus, we got:

├── Availability
│   ├── Availability+AvailabilityItem.swift
│   ├── Availability+Domain.swift
│   └── Availability.swift
├── DeclarationFragments
│   ├── DeclarationFragments.swift
│   └── Fragment
│       ├── Fragment+Kind.swift
│       └── Fragment.swift
├── FunctionSignature
│   ├── FunctionSignature+FunctionParameter.swift
│   └── FunctionSignature.swift
├── Symbol+AccessControl.swift
├── Symbol+Identifier.swift
├── Symbol+Kind.swift
├── Symbol+SPI.swift
└── Symbol.swift

What's your opinion about it? @franklinsch

@franklinsch
Copy link
Contributor

Makes sense to me! I'll defer to @QuietMisdreavus to do a review as well.

@QuietMisdreavus
Copy link
Contributor

Thanks so much for this! I like the organization you and Franklin have agreed upon; i think it makes working with the Symbol-related types much cleaner. Consider this my thumbs-up to keep going.

@Kyle-Ye Kyle-Ye changed the title [DNM & WIP] Split Symbol.swift to reduce complexity of the file Split Symbol.swift to reduce complexity of the file Dec 14, 2021
@Kyle-Ye
Copy link
Contributor Author

Kyle-Ye commented Dec 14, 2021

@swift-ci Please test

@Kyle-Ye
Copy link
Contributor Author

Kyle-Ye commented Dec 14, 2021

Complete the full PR.

It is a little big PR to review. But actually only involves moving files around.

Could you please help review it in your spare time? @franklinsch @QuietMisdreavus ❤️

@Kyle-Ye
Copy link
Contributor Author

Kyle-Ye commented Dec 14, 2021

I tried many ways, but I can't mark Relationship.swift as "rename" instead of "delete" and "add". Whether I use "git mv", first modify then mv nor first mv then modify can not achieve it.

Maybe the only way is to do 2 separate commits😂. (After doing 2 separate commits to achieve this, if I do squash commits, it will change to delete and add again😵‍💫)

@Kyle-Ye Kyle-Ye force-pushed the split branch 2 times, most recently from 584b5cb to c0836b6 Compare December 14, 2021 05:58
@Kyle-Ye
Copy link
Contributor Author

Kyle-Ye commented Dec 14, 2021

./Sources
└── SymbolKit
    ├── Mixin.swift
    ├── SymbolGraph
    │   ├── LineList
    │   │   ├── LineList.swift
    │   │   └── SourceRange
    │   │       ├── SourceRange+Position.swift
    │   │       └── SourceRange.swift
    │   ├── Relationship
    │   │   ├── Relationship+Kind.swift
    │   │   ├── Relationship+SourceOrigin.swift
    │   │   ├── Relationship.swift
    │   │   └── Swift
    │   │       ├── Swift+GenericConstraints.swift
    │   │       └── Swift.swift
    │   ├── Symbol
    │   │   ├── Availability
    │   │   │   ├── Availability+AvailabilityItem.swift
    │   │   │   ├── Availability+Domain.swift
    │   │   │   └── Availability.swift
    │   │   ├── DeclarationFragments
    │   │   │   ├── DeclarationFragments.swift
    │   │   │   └── Fragment
    │   │   │       ├── Fragment+Kind.swift
    │   │   │       └── Fragment.swift
    │   │   ├── FunctionSignature
    │   │   │   ├── FunctionSignature+FunctionParameter.swift
    │   │   │   └── FunctionSignature.swift
    │   │   ├── Swift
    │   │   │   ├── Namespace.swift
    │   │   │   ├── Swift+Extension.swift
    │   │   │   ├── Swift+GenericConstraint.swift
    │   │   │   ├── Swift+GenericParameter.swift
    │   │   │   └── Swift+Generics.swift
    │   │   ├── Symbol+AccessControl.swift
    │   │   ├── Symbol+Identifier.swift
    │   │   ├── Symbol+Kind.swift
    │   │   ├── Symbol+KindIdentifier.swift
    │   │   ├── Symbol+Location.swift
    │   │   ├── Symbol+Mutability.swift
    │   │   ├── Symbol+Names.swift
    │   │   ├── Symbol+SPI.swift
    │   │   └── Symbol.swift
    │   ├── SymbolGraph+Metadata.swift
    │   ├── SymbolGraph+Module.swift
    │   ├── SymbolGraph+OperatingSystem.swift
    │   ├── SymbolGraph+Platform.swift
    │   ├── SymbolGraph+SemanticVersion.swift
    │   └── SymbolGraph.swift
    ├── SymbolKit.docc
    │   ├── Resources
    │   │   ├── conforms.png
    │   │   ├── member.png
    │   │   └── twonodes.png
    │   └── SymbolKit.md
    └── UnifiedSymbolGraph
        ├── GraphCollector.swift
        ├── UnifiedSymbol.swift
        └── UnifiedSymbolGraph.swift

@QuietMisdreavus
Copy link
Contributor

The changes look good. Are you using an automatic formatter/linter? I noticed that the public keywords on the types got moved in favor of the extension blocks. Since the rest of the swift-docc repos tend to have their keywords the other way i wanted to make sure.

@Kyle-Ye
Copy link
Contributor Author

Kyle-Ye commented Dec 15, 2021

The changes look good. Are you using an automatic formatter/linter? I noticed that the public keywords on the types got moved in favor of the extension blocks. Since the rest of the swift-docc repos tend to have their keywords the other way i wanted to make sure.

Yes, I use an automatic formatter to use the public extension style which is my favor.

Since it was not the way swift-docc related repos' style, maybe I should change them back into the original style

extension XX {
	public struct YY {
	}
}

@QuietMisdreavus
Copy link
Contributor

The changes look good. Are you using an automatic formatter/linter? I noticed that the public keywords on the types got moved in favor of the extension blocks. Since the rest of the swift-docc repos tend to have their keywords the other way i wanted to make sure.

Yes, I use an automatic formatter to use the public extension style which is my favor.

Since it was not the way swift-docc related repos' style, maybe I should change them back into the original style

extension XX {
	public struct YY {
	}
}

That makes sense. I think we should stick to the existing style, to remove some churn. (As much as we can with a change like this! 😅)

@Kyle-Ye
Copy link
Contributor Author

Kyle-Ye commented Dec 15, 2021

The changes look good. Are you using an automatic formatter/linter? I noticed that the public keywords on the types got moved in favor of the extension blocks. Since the rest of the swift-docc repos tend to have their keywords the other way i wanted to make sure.

Yes, I use an automatic formatter to use the public extension style which is my favor.
Since it was not the way swift-docc related repos' style, maybe I should change them back into the original style

extension XX {
	public struct YY {
	}
}

That makes sense. I think we should stick to the existing style, to remove some churn. (As much as we can with a change like this! 😅)

Done👌

Copy link
Contributor

@QuietMisdreavus QuietMisdreavus left a comment

Choose a reason for hiding this comment

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

This looks good, thanks so much! Can you rebase and run tests before merging?

Separate into 2 commits because git can't mark it as rename since the change is too big
@Kyle-Ye
Copy link
Contributor Author

Kyle-Ye commented Dec 16, 2021

@swift-ci Please test

@Kyle-Ye
Copy link
Contributor Author

Kyle-Ye commented Dec 16, 2021

This looks good, thanks so much! Can you rebase and run tests before merging?

Done. I think we should defer to @franklinsch 's approval before merging.

@QuietMisdreavus
Copy link
Contributor

This looks good, thanks so much! Can you rebase and run tests before merging?

Done. I think we should defer to @franklinsch 's approval before merging.

Franklin's on vacation until January; are you comfortable keeping this open until then, or would you like me to pull in some other reviewers so we can land it sooner? I don't want to make you rebase this over and over if anything else lands before then, since it's a larger change that i feel is worthwhile to land.

@Kyle-Ye
Copy link
Contributor Author

Kyle-Ye commented Dec 16, 2021

This looks good, thanks so much! Can you rebase and run tests before merging?

Done. I think we should defer to @franklinsch 's approval before merging.

Franklin's on vacation until January; are you comfortable keeping this open until then, or would you like me to pull in some other reviewers so we can land it sooner? I don't want to make you rebase this over and over if anything else lands before then, since it's a larger change that i feel is worthwhile to land.

Maybe we could invite some other reviewers? +1 for this

@Kyle-Ye
Copy link
Contributor Author

Kyle-Ye commented Dec 16, 2021

Hello @ethan-kusters , would you please help review this MR? Thanks

Copy link
Contributor

@ethan-kusters ethan-kusters left a comment

Choose a reason for hiding this comment

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

This looks great to me! Thank you @Kyle-Ye. I think it makes the codebase much more approachable.

I also generated a DocC archive before and after this change and then diffed them to confirm there's no change in public API here. Looks all good. 👍🏻

@ethan-kusters
Copy link
Contributor

I think we should consider cherry-picking this change onto the release/5.6 branch after landing it here since this is low-risk and it will be difficult to manage merge conflicts otherwise.

@Kyle-Ye Kyle-Ye merged commit c4c029c into swiftlang:main Dec 18, 2021
@Kyle-Ye Kyle-Ye deleted the split branch December 18, 2021 02:54
@Kyle-Ye Kyle-Ye restored the split branch December 18, 2021 02:55
@Kyle-Ye Kyle-Ye deleted the split branch December 21, 2021 04:41
@WowbaggersLiquidLunch
Copy link
Contributor

Sorry for reviving the discussion long after the PR is merged.

I find the prevalent use of "ParentType+" prefixes in file names makes the repository a little difficult to navigate. For example, in this screenshot of part of the repository structure in Xcode's sidebar:

image

Because of the shared prefixes, it becomes difficult to tell apart the files when their names are long (and the prefixes contribute to the file name lengths). This is can become much worse with types introduced in #12, which can lead to file names like SymbolGraph+SemanticVersion+Prerelease+Identifier.

I'd like to open a PR that amends the naming convention to the following, but would like to discuss it here first:

  1. Keep the "+" convention for protocol conformances only, like in swift-collections.

  2. Group files that define types under the same immediate parent types into the same directory with the file that defines the parent type, and do not repeat the parent type's name. <- It's a mouthful, but this is what I mean:

    For a type structure like this:

    struct S {
        struct A {
            struct X {}
            struct Y {}
        }
        struct B {
            struct W {
                struct T {}
            }
            struct X {}
            struct Z {}
        }
    }
    
    extension Y: Equatable {}

    If we separate each type into its own file, then the directory structure should be like this:

    S
    ├─ S.swift
    ├─ A
    │  ├─ A.swift
    │  ├─ X.swift
    │  └─ Y
    │     ├─ Y.swift
    │     └─ Y+Equatable.swift
    └─ B
       ├─ B.swift
       ├─ W
       │  ├─ W.swift
       │  └─ T.swift
       ├─ X.swift
       └─ Z.swift
    

    instead of this:

    S
    ├─ S.swift
    ├─ A
    │  ├─ A.swift
    │  ├─ A+X.swift
    │  └─ Y
    │     ├─ Y.swift
    │     └─ Y+Equatable.swift
    └─ B
       ├─ B.swift
       ├─ W
       │  ├─ W.swift
       │  └─ W+T.swift
       ├─ B+X.swift
       └─ B+Z.swift
    

@Kyle-Ye
Copy link
Contributor Author

Kyle-Ye commented Jan 11, 2022

Sorry for reviving the discussion long after the PR is merged.

I find the prevalent use of "ParentType+" prefixes in file names makes the repository a little difficult to navigate. For example, in this screenshot of part of the repository structure in Xcode's sidebar:

image

Because of the shared prefixes, it becomes difficult to tell apart the files when their names are long (and the prefixes contribute to the file name lengths). This is can become much worse with types introduced in #12, which can lead to file names like SymbolGraph+SemanticVersion+Prerelease+Identifier.

I'd like to open a PR that amends the naming convention to the following, but would like to discuss it here first:

  1. Keep the "+" convention for protocol conformances only, like in swift-collections.

  2. Group files that define types under the same immediate parent types into the same directory with the file that defines the parent type, and do not repeat the parent type's name. <- It's a mouthful, but this is what I mean:
    For a type structure like this:

    struct S {
        struct A {
            struct X {}
            struct Y {}
        }
        struct B {
            struct W {
                struct T {}
            }
            struct X {}
            struct Z {}
        }
    }
    
    extension Y: Equatable {}

    If we separate each type into its own file, then the directory structure should be like this:

    S
    ├─ S.swift
    ├─ A
    │  ├─ A.swift
    │  ├─ X.swift
    │  └─ Y
    │     ├─ Y.swift
    │     └─ Y+Equatable.swift
    └─ B
       ├─ B.swift
       ├─ W
       │  ├─ W.swift
       │  └─ T.swift
       ├─ X.swift
       └─ Z.swift
    

    instead of this:

    S
    ├─ S.swift
    ├─ A
    │  ├─ A.swift
    │  ├─ A+X.swift
    │  └─ Y
    │     ├─ Y.swift
    │     └─ Y+Equatable.swift
    └─ B
       ├─ B.swift
       ├─ W
       │  ├─ W.swift
       │  └─ W+T.swift
       ├─ B+X.swift
       └─ B+Z.swift
    

Yes, both I and @franklinsch prefer the first approach I propose in the first post.

But this way we'll get more collision like Fragment+Kind.swift and Symbol+Kind.swift

Currently there are SymbolGraph.Symbol.DeclarationFragments.Fragment.Kind and SymbolGraph.Symbol.Kind.

Although they are not in the same folder, they are in the same module. Which is not allowed by Swift

error: filename "Kind.swift" used twice: 'Symbol/DeclarationFragments/Fragment/Kind.swift' > and 'SymbolKit/SymbolGraph/Symbol/Kind.swift'
note: filenames are used to distinguish private declarations with the same name

belkadan.com/blog/2021/11/Swift-Mangling-Regret-Private-Discriminators

If we use the second approach (which is merged now), the "collision" only occurs once
and can use some strategy to work around.

@Kyle-Ye
Copy link
Contributor Author

Kyle-Ye commented Jan 11, 2022

Because of the shared prefixes, it becomes difficult to tell apart the files when their names are long (and the prefixes contribute to the file name lengths). This is can become much worse with types introduced in #12, which can lead to file names like SymbolGraph+SemanticVersion+Prerelease+Identifier.

The file name will not be that long, it should at most be Prerelease+Identifier.swift according to the current rule.

@WowbaggersLiquidLunch
Copy link
Contributor

The file name will not be that long, it should at most be Prerelease+Identifier.swift according to the current rule.

Yes, you're correct. I misinterpreted it. Although, I think my main point stands, that shared prefixes make it more difficult to discern files.

@Kyle-Ye
Copy link
Contributor Author

Kyle-Ye commented Jan 11, 2022

I agree. So maybe we should only add the prefix when needed?
(Such as when a potential name collision may occur)

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

Successfully merging this pull request may close these issues.

5 participants