A code completion tool built on n-grams could be very effective. Many special cases for types arise naturally from this. `foo.` is probably a void method, whereas `await foo.` is an async method. `return foo.` and `x = foo.` probably have different properties too.