Unfortunately there doesn't seem any documentation about how precedence is generally handled or how to hide the implicitly imported xtend extensions.
If the library method and your custom method have unambiguous signatures, it should work right if you use static extension imports. I've successfully tested this:
package test1
class CustomListExtensions {
static def <T, R> map(T original, (T)=>R transformation) {
return transformation.apply(original);
}
}
usage example:
package test2
import static extension test1.CustomListExtensions.*
class Test1 {
def static void main(String[] args) {
// uses org.eclipse.xtext.xbase.lib.ListExtensions.map
val mappedList = #["hello", "world"].map['''«it» has length «length»''']
// uses test1.CustomListExtensions.map
val mappedObject = "hello CustomListExtensions".map['''«it» has length «length»''']
mappedList.forEach[println(it)]
println(mappedObject)
}
}
Output:
hello has length 5
world has length 5
hello CustomListExtensions has length 26
If you use extension providers (with non-static methods) instead of static extensions imports, then it seems the extension provider has precedence over the library method:
package test1
class CustomListExtensions2 {
def <T, R> map(T original, (T)=>R transformation) {
return transformation.apply(original);
}
}
Usage:
package test2
import test1.CustomListExtensions2
class Test2 {
val extension CustomListExtensions2 = new CustomListExtensions2
def void main() {
// uses test1.CustomListExtensions.map (<List<String>, String>)
val mappedObject1 = #["hello", "world"].map['''«it» has length «length»''']
// uses test1.CustomListExtensions.map (<String, String>)
val mappedObject2 = "hello CustomListExtensions".map['''«it» has length «length»''']
println(mappedObject1)
println(mappedObject2)
}
}
Output:
[hello, world] has length 2
hello CustomListExtensions has length 26