0

I am trying to flag protocols that are created with one or more function or property. To start I created some regex that matches more than one function in a protocol in regex testers. However, when I build the app with the rule, it doesn't match protocols with more than one function.

custom_rules:
  protocol_more_than_one_function:
    name: "Protocol with more than one function"
    regex: 'protocol.*{\n.*func.*\n.*func'
    message: "If you would like to create a protocol with more than one function, then cretae separate protocols with one function each, then combine them with a typealias. For example, typealias BothProtocols = firstProtocol & secondProtocol"
    severity: warning

The code I am testing it on is this:

protocol GroupedProtocol {
    func stuff()
    func stuff2()
}

I assume this is because swift lint regex isn't accepting the multiline regex arguments. What regex would accomplish this at buildtime?

ScottyBlades
  • 12,189
  • 5
  • 77
  • 85
  • I have no idea why one would want such a limitation but I think this will be a very complicated regex to write. You need to consider empty lines between two function declarations or a property between them and to not include anything in a protocol extension or any other code in the same file. Unless you know that you always write your protocol content in a certain way/order and never have any other code in the same file of course, then it might be a bit less complicated – Joakim Danielson Dec 31 '22 at 09:12
  • The provided regex matches examples in regex playgrounds but doesn't match the same examples in code with swiftlint executing. – ScottyBlades Dec 31 '22 at 10:41
  • you can use the `(?s)` inline flag to enable the `dotall` mode, which allows the `.` character to match any character, including newlines. this should work `(?s)protocol.*{\n.*func.*\n.*func ` – DanTe Dec 31 '22 at 10:49
  • I just tested your rule on two protocols (with one function and two functions respectively) and it works fine for me. Maybe your editor is adding some other type of line break? Maybe you could add the protocol you use for testing this. – Joakim Danielson Dec 31 '22 at 11:05
  • @JoakimDanielson did you test the regex within a swiftlint yml rule or in a regex browser simulator/editor? – ScottyBlades Dec 31 '22 at 23:36
  • I used swiftlint from the command line – Joakim Danielson Dec 31 '22 at 23:39
  • Oh weird. Well my swift lint from the command line is failing for separate reasons. However when I run it from yml it Doesnt match. I'm inclined to think it didn't save or load the latest yml, but I tested that and it wasn't the case. – ScottyBlades Jan 01 '23 at 01:43
  • @DanTe, By default, SwiftLint applies the 'dotAll' and 'multiline' flags to all 'CustomRule' regexes. – Blazej SLEBODA Apr 17 '23 at 05:54

1 Answers1

0

I went character by character. The regex broke on the {.
I had to escape it like so: \{.

smh

ScottyBlades
  • 12,189
  • 5
  • 77
  • 85
  • Yes of course I did this to when I tested your regex, sorry that I forgot to mention it above in my comments. – Joakim Danielson Jan 01 '23 at 11:21
  • No worries! I appreciate the collaboration and help! The smh was for the swiftlintregex engine. – ScottyBlades Jan 01 '23 at 20:39
  • There are three special characters in regular expressions that must be escaped in order to match them as literal characters in NSRegularExpression patterns, otherwise an error will be thrown. These characters are: "[" (left square bracket), escaped version "\\[" "{" (left curly brace), escaped version "\\{" "\" (backslash), escaped version "\\\\" – Blazej SLEBODA Apr 17 '23 at 06:15