Skip to content

Conversation

@EotT123
Copy link
Contributor

@EotT123 EotT123 commented Jan 18, 2025

This PR depends on #656.


Using Utility Class Methods as Extensions

Methods in utility classes are often good candidates to be used as extension methods. However, since these methods are not annotated, they cannot be used directly as extension methods.

Rather than manually converting all those methods into extensions, which can be time-consuming and error-prone, you can leverage Manifold's built-in functionality to automate this process. By specifying the utility class as a parameter to the @ExtensionSource annotation, you can easily incorporate its methods as extension methods for the target type.

Basic Usage

Suppose you want to use methods from the org.apache.commons.lang3.StringUtils class as extension methods for java.lang.String. You can do this with the following code:

package extensions.java.lang.String;

import java.org.apache.commons.lang3.StringUtils;
import manifold.ext.rt.api.Extension;
import manifold.ext.rt.api.ExtensionSource;

@Extension
@ExtensionSource( source = StringUtils.class )
public class MyStringExt {
    // Additional extension methods can be added here
}

With this approach, all public, static methods from the StringUtils class that take a String as their first parameter will be automatically available as extension methods for String objects.
Any methods that conflict with existing methods in the String class (i.e., methods with the same signature) will be excluded by default.

Overriding Existing Methods

If you want to override existing methods (i.e., make the methods from the utility class replace the methods already present on the target object), you can set the overrideExistingMethods attribute to true:

@ExtensionSource( source = Files.class, overrideExistingMethods = true )

Granular Control Over Included and Excluded Methods

You can further control which methods are included or excluded by specifying the method signatures you want to include or exclude. This is achieved using the type and methods attributes in the @ExtensionSource annotation.

For example, to include (or exclude) only specific methods from StringUtils, you can specify the INCLUDE or EXCLUDE types and provide method signatures:

@ExtensionSource( 
    source = StringUtils.class,
    overrideExistingMethods = true,
    type = ExtensionMethodType.INCLUDE, // <-- change to EXCLUDE to exclude specified methods
    methods = {
        @MethodSignature( name = "substring", paramTypes = { String.class, int.class } )
        // others
    } )

The name value can be specified as a regular expression.

There are several ways to configure how parameter types are matched:

  • Omitting paramTypes: Intercepts all methods with the specified name, regardless of their parameter types.
  • Empty paramTypes: Intercepts only methods with the same name and no parameters.
  • Non-empty paramTypes: Intercepts methods with the specified name and matching parameter types. You can use any.class for a parameter type that matches any class type.
    • For example, @MethodSignature(name = "foo", paramTypes = { String.class, any.class }) matches methods like foo(String, int) as well as foo(String, String) (and other variations for the second parameter).

@EotT123 EotT123 changed the title Add support for intercepting methods WIP: Use Utility Class Methods as Extensions Jan 18, 2025
@EotT123 EotT123 changed the title WIP: Use Utility Class Methods as Extensions Use Utility Class Methods as Extensions Jan 18, 2025
@EotT123 EotT123 changed the title Use Utility Class Methods as Extensions WIP: Use Utility Class Methods as Extensions Feb 2, 2025
@EotT123
Copy link
Contributor Author

EotT123 commented Feb 2, 2025

This PR depends on #656

@EotT123 EotT123 changed the title WIP: Use Utility Class Methods as Extensions BLOCKED: Use Utility Class Methods as Extensions Feb 2, 2025
@EotT123 EotT123 changed the title BLOCKED: Use Utility Class Methods as Extensions Use Utility Class Methods as Extensions Feb 12, 2025
@EotT123
Copy link
Contributor Author

EotT123 commented Feb 12, 2025

@rsmckinney Since #656 is merged, this PR is also ready.

@EotT123
Copy link
Contributor Author

EotT123 commented Apr 2, 2025

@rsmckinney What are your thoughts on this PR?

@rsmckinney
Copy link
Member

What are your thoughts on this PR?

It's a nice way to bridge utility classes. But I hesitate to add it because it's also a nice way to overcrowd a type with context-specific methods. I'm going to merge it though because manifold is for adults.

@rsmckinney rsmckinney merged commit 1ce2f10 into manifold-systems:master Apr 16, 2025
@EotT123 EotT123 deleted the #597_utility_class_as_extension_new branch April 16, 2025 07:51
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.

2 participants