Cuckoo icon indicating copy to clipboard operation
Cuckoo copied to clipboard

Error: Expected member name or constructor call after type name

Open pauluhn opened this issue 1 year ago • 27 comments

Xcode 15

GeneratedMocks.swift is showing errors for:

return DefaultValueRegistry.defaultValue(for: (Observable<T>).self)

\\ Expected member name or constructor call after type name
\\ Use '.self' to reference the type object <Fix>

If I edit it to:

return DefaultValueRegistry.defaultValue(for: Observable.self)

the error goes away.

If I fix the errors in the generated file and skip the Cuckoo script phase, I am able to compile and run unit tests in both Xcode 15 and Xcode 14.3.1

pauluhn avatar Sep 21 '23 17:09 pauluhn

I also have noticed the same issue when upgrading my project today

fraune avatar Sep 22 '23 20:09 fraune

Hey, thanks for reporting this. I don't have Xcode 15 installed yet, but I'll update and try fixing this.

MatyasKriz avatar Sep 23 '23 13:09 MatyasKriz

I tried just removing the parentheses and that will unfortunately not work, they are required for closure types. Does (Observable).self work or not?

MatyasKriz avatar Sep 28 '23 19:09 MatyasKriz

Here is an excerpt of a file Cuckoo generated for me today. Xcode 15.0/RxSwift 6.5.

In my case (Observable).self does not work. Screenshot 2023-09-28 at 4 58 38 PM

fraune avatar Sep 28 '23 22:09 fraune

I see, thanks for the info. I wonder why they broke that functionality.

This is then unfortunately also blocked by the current flawed type implementation. I'll see what I can do.

MatyasKriz avatar Sep 29 '23 05:09 MatyasKriz

I don't know if it will help because I didn't yet try updating all my failing types with it, but the compiler seems happy when I change the line in my example to either:

return DefaultValueRegistry.defaultValue(for: (Observable<BluetoothState>.self))
return DefaultValueRegistry.defaultValue(for: (Observable<BluetoothState>.self).self)

fraune avatar Sep 29 '23 15:09 fraune

I tried the above solution but cannot edit GeneratedMocks.swift.

when it's rebuilt, the changes go off. unable to execute unit tests because of this issue

bnandhinidevi avatar Oct 02 '23 15:10 bnandhinidevi

I did not intent to suggest that manually editing GeneratedMocks would be a suitable workaround.

fraune avatar Oct 02 '23 15:10 fraune

Good news is that over the weekend I managed to find the time to implement a new type system using the SwiftSyntax structure, so it should also be more rigid.

I haven't gotten around to creating a project with new Swift version to find out what exact changes I need to do.

MatyasKriz avatar Oct 02 '23 18:10 MatyasKriz

Awesome. If it helps, I created a new repo for reproducing the issue, with Cuckoo and RxSwift 6.6. This gives passing tests in Xcode 14, and the type error in Xcode 15. [email protected]:fraune/CuckooSwiftTest.git

(Using this method to run both Xcodes next to each other. https://stackoverflow.com/a/74500488/13944515)

fraune avatar Oct 02 '23 21:10 fraune

That's great, thank you! 🙂 I should be able to look at fixing this today.

MatyasKriz avatar Oct 03 '23 09:10 MatyasKriz

Awesome. If it helps, I created a new repo for reproducing the issue, with Cuckoo and RxSwift 6.6. This gives passing tests in Xcode 14, and the type error in Xcode 15. [email protected]:fraune/CuckooSwiftTest.git

I'd very much like to know why this only occurs with Observable from RxSwift, at least that we have here. I've been trying (and failing) to reproduce this error with any other generic type, including protocols with primary associated type.

Another issue I've found is that simply removing parentheses works for just Observable<T>, but for closure () -> Observable<T> I wasn't able to get it working (and it requires parentheses as a closure).

However, I've found a workaround that seems to fix the main issue along with this edge-case while keeping the default value registry working as intended. It will require generating a private typealias above each property with the type it uses, then TypealiasName.self works every time for all types that I've tried.

I'll implement the full workaround into Cuckoo 2.0; but since this seems like a blocker, I'll release a new 1.x version with a simple workaround by using the type without parentheses if it's not a closure, probably tomorrow.

MatyasKriz avatar Oct 03 '23 18:10 MatyasKriz

@fraune I've actually used the idea with the typealias for the 1.x version as well as it's easier to do. There's a branch fix/swift-5.9-type that contains the changes, could you please test it out with RxSwift? As I've mentioned, I haven't seen it have problems with any other generic type.

MatyasKriz avatar Oct 04 '23 18:10 MatyasKriz

I love that idea. Do I need to do anything special to download the cuckoo_generator file for a branch that isn't tagged?

function download_generator seems to want to download either the latest release or a specified tag.

fraune avatar Oct 04 '23 19:10 fraune

Oh, right. The generator needs to be built in this case. Downloading is done through GitHub releases only. It should be available for download in this comment.

cuckoo_generator.zip

EDIT: I've tried to run this generator with the sample project and it compiles! 😁

MatyasKriz avatar Oct 04 '23 20:10 MatyasKriz

Thanks for providing that. It looks like a huge reduction in the errors that are showing up in my team's project.

I still have a handful of errors remaining — I'm working to reproduce them in the test project, since I am unable to share team code. I'll hopefully have a better test project for you tomorrow.

fraune avatar Oct 04 '23 21:10 fraune

I've oddly had a difficult time reproducing my remaining errors in the test project, but I'll give an update on where I've gotten with it.

It appears the only remaining errors in my team project are specifically with the RxSwift Observable type. Interestingly, RxSwift's Single and Completable, types work just fine.

Screenshot 2023-10-06 at 12 28 19 AM Screenshot 2023-10-06 at 12 28 37 AM

I don't know enough about Swift types, or how Cuckoo picks them up, but it looks like something is going on with elements that get type-erased, like Observable. https://github.com/ReactiveX/RxSwift/blob/473b7a7180df6ff58925a5bd1ed039bccdc35250/RxSwift/Observable.swift

I'll see if any fresh ideas come overnight, or perhaps the weekend.

fraune avatar Oct 06 '23 06:10 fraune

I'm stumped as well, Observable seems to be an ordinary type, but its behavior is anything but.

@TadeasKriz have you ever encountered this? If you have a suggestion, that'd be great!

MatyasKriz avatar Oct 06 '23 09:10 MatyasKriz

Is this Xcode 15? I think Observable is now a macro for SwiftUI, so maybe try RxSwift.Observable<IBluetoothPeripheral>, that might work.

TadeasKriz avatar Oct 06 '23 13:10 TadeasKriz

@TadeasKriz That was it! Tricky, because when I use Xcode to click into the Observable it would take me to RxSwift's type.

After updating my protocols to use RxSwift.Observable over Observable, my remaining project errors have been resolved.

fraune avatar Oct 06 '23 15:10 fraune

Hi – not trying to sound pushy, but is there an approximate timeline for this work to be released? Thanks!

fraune avatar Oct 09 '23 20:10 fraune

Hey, changing the types to RxSwift.Observable didn't make all the errors related to it go away? The change that's in the pipeline is just the typealias we discussed, I can't add RxSwift. in the generator automatically as the parser has no clue nor does it care where the Observable comes from.

MatyasKriz avatar Oct 09 '23 21:10 MatyasKriz

Good question. I meant to double check that.

fraune avatar Oct 09 '23 21:10 fraune

It looks like you're correct. Although your update on that branch fixed many of the errors in my project, I was able to get it all working with the current Cuckoo version by explicitly renaming the remaining Observable uses.

fraune avatar Oct 09 '23 22:10 fraune

Haven't had a chance to revisit this until now. 😅

Based on all the comments, I added RxSwift. to all the Observables in GeneratedMocks.swift and it does make all the previous errors go away.

So I'm not sure how to resolve this on the generator side, but I've resolved it for my project by adding a Run Script Phase with the following:

sed -i '' -e 's/Observable/RxSwift.Observable/g' <path to GeneratedMocks.swift>

Will leave Foundation.Observable vs RxSwift.Observable debate for another time.

pauluhn avatar Oct 10 '23 21:10 pauluhn

Issue Description:

  • I am encountering an issue with the Cuckoo library when attempting to run test cases. Despite switching to the 'fix/swift-5.9-type' branch, my test cases continue to fail. This problem has been a significant blocker for my project over the last couple of weeks.

Environment Details:

  1. Xcode Version: 15.0
  2. Pod Configuration:
target 'CoreTests' do
   inherit! :search_paths
   pod 'Cuckoo', :git => 'https://github.com/Brightify/Cuckoo.git', :branch => 'fix/swift-5.9-type'
   pod 'RxBlocking', '~> 6.0'
   pod 'RxTest', '~> 6.0'
   pod 'Quick', '6.0.1'
   pod 'Nimble', '13.0.0'
 end
end

post_install do |pi|
   pi.pods_project.targets.each do |t|
       t.build_configurations.each do |config|
           config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
       end
   end
end
  1. macOS Version: Sonoma
  2. macOS Version Number: 14.0 (23A344)
  3. Machine: Apple M1

CC: @MatyasKriz @TadeasKriz @fraune @pauluhn

Build Phase Reference

Screenshot 2023-10-22 at 3 58 03 PM Screenshot 2023-10-22 at 3 58 39 PM

Xcode test case failed reference

Screenshot 2023-10-22 at 3 59 43 PM Screenshot 2023-10-22 at 4 00 06 PM

chirag05k avatar Oct 22 '23 10:10 chirag05k

@chirag05k If your case is like mine, you don't need to use a special branch of Cuckoo. Try renaming Observable to RxSwift.Observable in the class you're mocking out (e.g. rename your startSession method's return type).

Swift 5.9 added a new Observable type that now shadows RxSwift's Observable.

fraune avatar Oct 22 '23 14:10 fraune

Nothing we can do about this unfortunately AFAIK, closing.

MatyasKriz avatar Apr 23 '24 15:04 MatyasKriz