function transform_component(analysis, source, options) {
	if (options.generate === false) {
		return {
			js: /** @type {any} */ (null),
			css: null,
			warnings: state.warnings, // set afterwards
			metadata: {
				runes: analysis.runes
			},
			ast: /** @type {any} */ (null) // set afterwards
		};
	}

	const program =
		options.generate === 'server'
			? server_component(analysis, options)
			: client_component(analysis, options);

	const js_source_name = get_source_name(options.filename, options.outputFilename, 'input.svelte');

	const js = print(program, {
		// include source content; makes it easier/more robust looking up the source map code
		// (else esrap does return null for source and sourceMapContent which may trip up tooling)
		sourceMapContent: source,
		sourceMapSource: js_source_name
	});

	merge_with_preprocessor_map(js, options, js_source_name);

	const css =
		analysis.css.ast && !analysis.inject_styles
			? render_stylesheet(source, analysis, options)
			: null;

	return {
		js,
		css,
		warnings: state.warnings, // set afterwards. TODO apply preprocessor sourcemap
		metadata: {
			runes: analysis.runes
		},
		ast: /** @type {any} */ (null) // set afterwards
	};
}
@param {ComponentAnalysis} analysis
@param {string} source
@param {ValidatedCompileOptions} options
@returns {CompileResult}