refactor analyse_types() and friends to work more like a transform by returning the node or a replacement