Beispiel #1
0
 public void SetOperands(TransducerCompilation inner, TransducerCompilation outer)
 {
     _inner = inner;
     _outer = outer;
 }
Beispiel #2
0
        private static IEnumerable <TransducerCompilation> GetCompilations(Z3Provider ctx, Compilation compilation, IEnumerable <SyntaxTree> trees)
        {
            var transducers = new Dictionary <INamedTypeSymbol, TransducerCompilation>();
            var genericTransducerBaseType  = compilation.GetTypeByMetadataName(typeof(Transducer <,>).FullName);
            var composedTransducerBaseType = compilation.GetTypeByMetadataName(typeof(Composition <,>).FullName);
            var specialTransducerBaseType  = compilation.GetTypeByMetadataName(typeof(SpecialTransducer).FullName);
            var charType = compilation.GetTypeByMetadataName(typeof(Int32).FullName);

            foreach (var tree in trees)
            {
                var model = compilation.GetSemanticModel(tree);
                var root  = tree.GetRoot();
                // Find all transducer declarations
                foreach (var declaration in root.DescendantNodes().OfType <ClassDeclarationSyntax>())
                {
                    var declarationType = model.GetDeclaredSymbol(declaration) as INamedTypeSymbol;
                    Debug.Assert(declarationType != null, "A class declaration's symbol is not an INamedTypeSymbol?!");
                    var attributes = declaration.AttributeLists.SelectMany(x => x.Attributes);

                    TransducerCompilation transducer = null;

                    // User defined transducers
                    var transducerType = GetConstructedBase(declarationType, genericTransducerBaseType);
                    if (transducerType != null && !declarationType.IsAbstract && !transducers.ContainsKey(declarationType))
                    {
                        transducer = new TransducerSource(ctx, model, declarationType, transducerType);
                    }
                    // Compositions
                    transducerType = GetConstructedBase(declarationType, composedTransducerBaseType);
                    if (transducerType != null && !declarationType.IsAbstract && !transducers.ContainsKey(declarationType))
                    {
                        transducer = new TransducerComposition(declarationType);
                    }
                    // Special transducers
                    transducerType = GetConstructedBase(declarationType, specialTransducerBaseType);
                    if (transducerType != null && !declarationType.IsAbstract)
                    {
                        if (transducers.ContainsKey(declarationType))
                        {
                            throw new TransducerCompilationException("SpecialTransducers must have only one declaration (even though they must be partial).");
                        }
                        transducer = GetSpecialCompilation(ctx, compilation, model, declarationType, attributes);
                    }
                    // Handle the [ShowGraph()] and [SuppressCodeGeneration()] attributes
                    if (transducer != null)
                    {
                        transducer.ShowGraphStages        = GetShowGraphStages(compilation, model, attributes);
                        transducer.SuppressCodeGeneration = GetSuppressCodeGeneration(compilation, model, attributes);
                        transducers.Add(declarationType, transducer);
                    }
                }
            }

            // Resolve the arguments for compositions
            foreach (var composition in transducers.Values.OfType <TransducerComposition>())
            {
                var compositionType = GetConstructedBase(composition.DeclarationType, composedTransducerBaseType);
                var innerDecl = compositionType.TypeArguments[0] as INamedTypeSymbol;
                var outerDecl = compositionType.TypeArguments[1] as INamedTypeSymbol;
                TransducerCompilation inner, outer;
                if (!transducers.TryGetValue(innerDecl, out inner) || !transducers.TryGetValue(outerDecl, out outer))
                {
                    throw new TransducerCompilationException("The " + composition.DeclarationType.Name + " composition's type parameters must be other transducers");
                }
                composition.SetOperands(inner, outer);
            }

            return(transducers.Values);
        }