public static QsCompilation Apply(QsCompilation compilation) { if (compilation == null || compilation.Namespaces.Contains(null)) { throw new ArgumentNullException(nameof(compilation)); } var globals = compilation.Namespaces.GlobalCallableResolutions(); var entryPoints = compilation.EntryPoints .Select(call => new Request { originalName = call, typeResolutions = ImmutableConcretion.Empty, concreteName = call }); var requests = new Stack <Request>(entryPoints); var responses = new List <Response>(); while (requests.Any()) { Request currentRequest = requests.Pop(); // If there is a call to an unknown callable, throw exception if (!globals.TryGetValue(currentRequest.originalName, out QsCallable originalGlobal)) { throw new ArgumentException($"Couldn't find definition for callable: {currentRequest.originalName.Namespace.Value + "." + currentRequest.originalName.Name.Value}"); } var currentResponse = new Response { originalName = currentRequest.originalName, typeResolutions = currentRequest.typeResolutions, concreteCallable = originalGlobal.WithFullName(name => currentRequest.concreteName) }; GetConcreteIdentifierFunc getConcreteIdentifier = (globalCallable, types) => GetConcreteIdentifier(currentResponse, requests, responses, globalCallable, types); // Rewrite implementation currentResponse = ReplaceTypeParamImplementationsSyntax.Apply(currentResponse); // Rewrite calls currentResponse = ReplaceTypeParamCallsSyntax.Apply(currentResponse, getConcreteIdentifier); responses.Add(currentResponse); } var filter = new ResolveGenericsSyntax(responses .GroupBy(res => res.concreteCallable.FullName.Namespace) .ToImmutableDictionary(group => group.Key, group => group.Select(res => res.concreteCallable))); return(new QsCompilation(compilation.Namespaces.Select(ns => filter.Transform(ns)).ToImmutableArray(), compilation.EntryPoints)); }
public static Response Apply(Response current) { // Nothing to change if the current callable is already concrete if (current.typeResolutions == ImmutableConcretion.Empty) { return(current); } var filter = new ReplaceTypeParamImplementationsSyntax(current.typeResolutions); // Create a new response with the transformed callable return(new Response { originalName = current.originalName, typeResolutions = current.typeResolutions, concreteCallable = filter.onCallableImplementation(current.concreteCallable) }); }