module d.semantic.closure;

import d.semantic.semantic;

import d.ir.symbol;
import d.ir.type;

struct ContextFinder {
	private SemanticPass pass;
	alias pass this;

	this(SemanticPass pass) {
		this.pass = pass;
	}

	Function visit(Symbol s) in {
		assert(
			s.hasContext,
			"You can't finsource.context of symbol that do not have context");
	} do {
		return this.dispatch(s);
	}

	Function visit(Function f) {
		scheduler.require(f, Step.Signed);

		// If we have a this pointer, then the context is next.
		auto t = f.type.parameters[0].getType();
		assert(t.kind == TypeKind.Context,
		       t.toString(context) ~ ": invalid type for a context.");

		return t.context;
	}

	Function visit(SymbolAlias a) {
		return visit(a.symbol);
	}
}