Nested classes

nested
class

#1

Hi all,

Here is a case that I would like to share with you
I have a base class that contains other classes that contain other subclasses as the following pseudo code

// File: Base.swift
public class Base {
    public class Class {
        public class SubClass {
        }
    }
}

With time my class Base gets bigger I decided to split the sources like this

// File: Base.swift
public class Base {
}

// File: Base.Class.swift
public extension Base {
    public class Class {
        public class SubClass {
        }
    }
}

All goes well but I want to go further. I would like each class to be on its own file but I can not.

// File: Base.swift => OK
public class Base {
}

// File: Base.Class.swift => OK
public extension Base {
    public class Class {
    }
}

// File: Base.Class.SubClass.swift => Error: Declaration is only valid at file scope
public extension Base {
    public extension Class {
        public class SubClass {
        }
    }
}

I also tried

// File: Base.Class.SubClass.swift => Error: 'Class' is not a member type of 'Base'
public extension Base.Class {
    public class SubClass {
    }
}

When I define the class Base, Class and SubClass in the same file it is not a problem. Base and Class in their own file it's good too. But it does not work for SubClass.
I do not understand this limitation (?!?!?)
Is there any trick or syntax to do what I'm trying to do?


(Kaitlin Mahar) #2

Are you sure that the final thing you tried doesn't work?

My build succeeds with

// file 1
public class Base {}

// file 2
public extension Base {
    public class Class {}
}

// file 3
public extension Base.Class {
    public class SubClass {}
}

(Anthony Latsis) #3

It's an old and well-known bug (SR-631) that was recently fixed thanks to @Slava_Pestov. I assume the changes should have already been integrated into the latest Xcode beta build.

There's a separate issue causing some problems though (see https://github.com/apple/swift/pull/18168).


#4

I just try with Xcode 10 Beta 6 and Swift 4.2 and the error still exist


(Anthony Latsis) #5

@Tof Extensions cannot be nested, try fixing that to see if it works.


#6

My test project was created with Xcode 9.4.1
At my first try with Xcode 10 I changed the swift language to swift 4.2 and the test failed
I recreate the test project from scratch with Xcode 10 beta 6 and... it is working now (?!?!?!)


Just strange... :thinking:


(Slava Pestov) #7

This change was only made on master, and not the swift-4.2-branch.


#8
// file 1
public class Base {}

// file 2
public extension Base {
    public class Class {}
}

// file 3
public extension Base.Class { // <= Error: 'Class' is not a member type of 'Base'
    public class SubClass {}
}

I tried to apply this template on real class on a project that I migrate to Xcode 10 Beta 6 and swift 4.2
The error is back:

'Class' is not a member type of 'Base'

Do I have this error because the project was originally on Xcode 9.4.1?
Is there a specific setting to specify at the project level?


(Yuga Ego) #9

See the response in the previous message in this thread: Nested classes. The change is on master branch only, not on swift 4.2 branch.


#10

Excuse me if I have trouble understanding but why put this patch in master and not the branch swift-4.2-branch?
Personally on my projects I never work directly on the master. I am doing the evolutions / fixes in branches. I only update the master once the evolutions / fixes are good.
Does this mean this fixe will not be put in the release of Swift 4.2 with Xcode 10?


(Adrian Zubarev) #11

It does mean exactly that. The subclass issue I filed (SR-5993) is only fixed in Swift 5. Here the conversation from Twitter.


(Jordan Rose) #12

To provide some more context: the primary purpose of the release branches is to have something "converge" to a stable implementation over the last part of a release. That's why we have more process about changing things there than on master. Since any change can introduce new bugs, bringing a fix to the release branch has to be considered worth the possible risk; that "high value / low risk" requirement gets stricter as the release goes on.

In this case, the bug stinks, but it's also been around for a long time and has several established workarounds. Therefore, the risk of possible new bugs outweighs the benefit of trying to backport the fix to the 4.2 branch. Sorry!