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

Treatment of enum based feature flags #660

Closed
aleksandr-zakshevskii-n26 opened this issue May 1, 2024 · 2 comments
Closed

Treatment of enum based feature flags #660

aleksandr-zakshevskii-n26 opened this issue May 1, 2024 · 2 comments

Comments

@aleksandr-zakshevskii-n26
Copy link

aleksandr-zakshevskii-n26 commented May 1, 2024

Hello, I wanted to get your advice on how to treat the following case,
we have a feature flag which is called FEATURE-A-ENABLED

the code which is using the feature flag:

enum class FeatureFlags(val featureName: String) {
    FEATURE_A("FEATURE-A-ENABLED"),
    FEATURE_B("FEATURE-B-ENABLED")
    ;
}

fun isFeatureEnabled() =
    featureService.isEnabled(FeatureFlags.FEATURE_A)

fun main() {
    if (isFeatureEnabled()) {
        println("Hello world!")
    } else {
        println("Hi world!")
    }
}

Ideally i would like to remove usages of FEATURE_A enum entry and isFeatureEnabled() invocations

enum class FeatureFlags(val featureName: String) {
    FEATURE_B("FEATURE_B")
    ;
}

fun main() {
   println("Hi world!")
}

Initially I tried adding the following rules:

rule #1
delete_enum_declaration - deletes the enum entry using the string "FEATURE-A-ENABLED" , since it's a seed rule I can use the @flag_enum_name in the subsequent non-seed rules

[[rules]]
name = "delete_enum_declaration"
query = """
(
(enum_entry
    (simple_identifier) @flag_enum_name
    (value_arguments
    	(value_argument [
        	(string_literal) @flag_name
     ]))
) @enum_entry
(#eq? @flag_name "\\\"@stale_flag_name\\\"")
)
"""
replace_node = "enum_entry"
replace= ""
groups = ["delete_property_declaration"]
holes = ["stale_flag_name"]

rule #2
replace_flag_method_declaration - deletes one-line functions which are using the FEATURE_A enum entry, in order to use @flag_enum_name from the previous rule this rule must be declared as is_seed_rule = false

[[rules]]
name = "replace_flag_method_declaration"
query = """
(
(function_declaration
    (simple_identifier) @func_name
    (function_body
    	(call_expression
            (navigation_expression (_))
            (call_suffix
            	(value_arguments
                	(value_argument
                    	(navigation_expression
                        	(navigation_suffix
                            	(simple_identifier) @enum_item
                            )))))))) @function_declaration
(#eq? @enum_item "@flag_enum_name")
)
"""
replace_node = "func_name"
replace= ""
groups = ["delete_method_declaration"]
holes = ["flag_enum_name"]
is_seed_rule = false

After running those 2 rules - I get the following result:

enum class FeatureFlags(val featureName: String) {
    FEATURE_B("FEATURE_B")
    ;
}

fun main() {
    if (isFeatureEnabled()) {
        println("Hello world!")
    } else {
        println("Hi world!")
    }
}

As you can see the enum entry and the function declaration isFeatureEnabled are deleted. I want also to replace invocation of isFeatureEnabled() with boolean literal

But from the rules perspective I don't understand how can I accomplish that, since the second rule which matches function declarations - is not a seed rule - so I can't add @function_name to the hole of the 3rd rule. Also I cannot make the 2nd rule as seed, since I need the @ flag_enum_name to identify such functions.

I hope I explained it clearly. I would be appreciated for your help.
Thanks!

@dvmarcilio
Copy link
Collaborator

dvmarcilio commented May 1, 2024

Hi @aleksandr-zakshevskii-n26. Have you tried adding an edge from the 2nd rule to the 3rd rule? In general, if you have rules a and b, and an edge a -> b, you can use matches from a as holes in b.

@aleksandr-zakshevskii-n26
Copy link
Author

Hello @dvmarcilio . Thanks a lot, that helped!

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

No branches or pull requests

2 participants