Example #1
0
 public MethodMakerVisitor(ModuleBuilder moduleBuilder, WhoDefinedMemberByMethodlike extensionLookup, RealizedMethodLookup realizedMethodLookup, AssemblerTypeTracker typeCache)
 {
     this.moduleBuilder        = moduleBuilder ?? throw new ArgumentNullException(nameof(moduleBuilder));
     this.extensionLookup      = extensionLookup ?? throw new ArgumentNullException(nameof(extensionLookup));
     this.realizedMethodLookup = realizedMethodLookup ?? throw new ArgumentNullException(nameof(realizedMethodLookup));
     this.typeTracker          = typeCache ?? throw new ArgumentNullException(nameof(typeCache));
 }
Example #2
0
        private static TacCompilation <Tin, TOut> Build <Tin, TOut>(IProject <Assembly, object> project)
        {
            var rootScope = project.RootScope;
            // I think we are actually not making an assembly,
            // just a type

            var extensionLookup = new WhoDefinedMemberByMethodlike();
            var closureVisitor  = new ClosureVisitor(extensionLookup, project.DependencyScope.Members.Values.Select(x => x.Value).ToHashSet());

            rootScope.Convert(closureVisitor);

            var(memberKindVisitor, memberKindLookup) = MemberKindVisitor.Make(extensionLookup, project);
            rootScope.Convert(memberKindVisitor);
            memberKindVisitor.HandleDependencies(project.DependencyScope);

            var gens = new List <DebuggableILGenerator>();

            var typeTracker = new TypePassTypeTracker(module.Value, gens);
            var typeVisitor = new TypeVisitor(typeTracker);

            rootScope.Convert(typeVisitor);
            typeVisitor.HandleDependencies(project);

            var typeTracker2 = typeTracker.CreateTypesAndProperties();

            var dependenciesTypeBuider = module.Value.DefineType(AssemblerVisitor.GenerateName(), TypeAttributes.Public);

            foreach (var member in project.References)
            {
                dependenciesTypeBuider.DefineField(TypeTracker.ConvertName(member.Key.Name), typeTracker2.ResolvePossiblyPrimitive(member.Scope), FieldAttributes.Public);
            }
            var dependenciesType = dependenciesTypeBuider.CreateType() ?? throw new NullReferenceException("dependenciesTypeBuider.CreateType should not return null");
            //var dependenciesType = typeTracker2.GetDependencyType();

            var realizedMethodLookup = new RealizedMethodLookup();
            var methodMakerVisitor   = new MethodMakerVisitor(module.Value, extensionLookup, realizedMethodLookup, typeTracker2);

            rootScope.Convert(methodMakerVisitor);


            var conversionTypes = new ConcurrentIndexed <(System.Type, System.Type), TypeBuilder>();

            var(assemblerVisitor, after) = AssemblerVisitor.Create(
                memberKindLookup,
                extensionLookup,
                typeTracker2,
                conversionTypes,
                module.Value,
                realizedMethodLookup,
                typeTracker2.ResolvePossiblyPrimitive(rootScope.EntryPoint.InputType),
                typeTracker2.ResolvePossiblyPrimitive(rootScope.EntryPoint.OutputType),
                gens,
                dependenciesType);
            rootScope.Convert(assemblerVisitor);

            //finish up
            // this is a bit sloppy, maybe disposable?
            after();

            // we have to actually create the types
            realizedMethodLookup.CreateTypes();
            assemblerVisitor.rootType.CreateType();

            var yo = String.Join(Environment.NewLine, gens.Select(x => x.GetDeubbingSting()));

            // now I need to reflexively find my type and call main
            var complitation = (TacCompilation)(Assembly.Value.CreateInstance(assemblerVisitor.rootType.Name) ?? throw new NullReferenceException());

            //var runtimeTypeCache = new ConcurrentIndexed<System.Type,IVerifiableType>();

            //foreach (var type in typeTracker.GetTypes())
            //{
            //    runtimeTypeCache.AddOrThrow(type.Value, type.Key);
            //}

            //foreach (var pair in conversionTypes)
            //{
            //    // the runtimeTypeCache shouldn't cause any trouble
            //    // pair.Key.Item2 should all be root
            //    runtimeTypeCache.AddOrThrow(pair.Value, runtimeTypeCache[pair.Key.Item2]);
            //}

            //complitation.addType = (type, tacType) => { typeTracker.typeCache.AddOrThrow(type, tacType); };
            //complitation.

            //var wrapsAndImplementsCache = new ConcurrentIndexed<(System.Type, System.Type), System.Type>();

            //foreach (var conversion in conversionTypes)
            //{
            //    wrapsAndImplementsCache[conversion.Key] = conversion.Value;
            //}

            complitation.runTimeTypeTracker = typeTracker2.RunTimeTypeTracker();

            var compType = complitation.GetType();

            var dependenciesField = compType.GetField(nameof(TacCompilation <int, int, object> .dependencies)) ?? throw new NullReferenceException();

            var dependencies = Activator.CreateInstance(dependenciesField.FieldType);

            dependenciesField.SetValue(complitation, dependencies);

            // A502902A-8EC8-4F5F-A55F-32E36F146762 this is a bit weird
            // it would be great if these didn't have to be wraped
            // the MSIL type could flow into the front end
            // and be picked up again on the backend
            foreach (var reference in project.References)
            {
                var field = dependenciesType.GetField(TypeTracker.ConvertName(reference.Key.Name)) ?? throw new NullReferenceException();
                var setTo = AssemblyWalkerHelp.TryAssignOperationHelper_Cast(reference.Backing, typeTracker2.ResolvePossiblyPrimitive(reference.Scope), complitation.runTimeTypeTracker);
                field.SetValue(dependencies, setTo);
            }

            //complitation.indexerArray = assemblerVisitor.indexerList.indexers.ToArray();
            //complitation.verifyableTypesArray = assemblerVisitor.verifyableTypesList.types.ToArray();
            complitation.Init();
            return((TacCompilation <Tin, TOut>)complitation);
        }