public void RenderInitializer(GeneratorExecutionContext context, IndentedStringBuilder stringBuilder,
                                      IteratorGenerator iteratorGenerator)
        {
            if (Cardinality.HasValue)
            {
                var propertyConstructionString = $"new IUpdateField[{Cardinality.Value}]";
                if (PropertySymbol != null)
                {
                    if (PropertySymbol.Type is IArrayTypeSymbol arrayTypeSymbol)
                    {
                        var baseType = arrayTypeSymbol.ElementType;
                        propertyConstructionString = $"new {baseType}[{Cardinality.Value}]";
                    }
                }

                stringBuilder.AppendLine();

                stringBuilder.AppendLine($"{EnumerationSymbol.Name} = {propertyConstructionString};");
                stringBuilder.AppendLine($"{EnumerationSymbol.Name}[0] = {GetElementInitializer(context)};");

                using var rentedIterator = iteratorGenerator.Rent();
                using (stringBuilder.BlockInvariant(false, $"for (var {rentedIterator} = 1; {rentedIterator} < {Cardinality.Value}; ++{rentedIterator})"))
                    stringBuilder.AppendLine($"{EnumerationSymbol.Name}[{rentedIterator}] = {GetElementInitializer(context, rentedIterator)};");

                stringBuilder.AppendLine();
            }
            else
            {
                stringBuilder.AppendLine($"{EnumerationSymbol.Name} = {GetElementInitializer(context)};");
            }
        }
        public void RenderParser(IndentedStringBuilder stringBuilder, IteratorGenerator iteratorGenerator)
        {
            if (Cardinality.HasValue)
            {
                stringBuilder.AppendLine();

                using var rentedIterator = iteratorGenerator.Rent();
                using (stringBuilder.BlockInvariant(false, $"for (var {rentedIterator} = 0; {rentedIterator} < {Cardinality.Value}; ++{rentedIterator})"))
                    stringBuilder.AppendLine($"{EnumerationSymbol.Name}[{rentedIterator}].ReadValue(packet, updateMask);");

                stringBuilder.AppendLine();
            }
            else
            {
                stringBuilder.AppendLine($"{EnumerationSymbol.Name}.ReadValue(packet, updateMask);");
            }
        }
示例#3
0
        private static void WorkWithIterators()
        {
            PositiveEnumerator positive = new PositiveEnumerator(new int[] { 0, 1, 2, 3, 4, -1 });

            while (positive.MoveNext())
            {
                Console.WriteLine(positive.Current);
            }

            MyEvenEnumerable myEvenEnumerable = new MyEvenEnumerable(new int[] { 1, 2, 3, 4, 5, 6 });

            foreach (var item in myEvenEnumerable)
            {
                Console.WriteLine(item);
            }

            IteratorGenerator var = new IteratorGenerator(10);

            while (var.MoveNext())
            {
                Console.WriteLine(var.Current);
            }
        }
        public override void Execute(GeneratorExecutionContext context)
        {
            // retrieve the populated receiver
            if (!(context.SyntaxContextReceiver is SyntaxReceiver receiver))
            {
                return;
            }

            foreach (var enumerationSymbol in receiver.Enumerations)
            {
                var generatedDescriptorData = context.Compilation.GetTypeByMetadataName(typeof(GeneratedDescriptorAttribute).FullName);

                var descriptorAttributeData = context.Compilation.GetTypeByMetadataName(typeof(DescriptorAttribute).FullName);
                var descriptorAttribute     = enumerationSymbol !.FindAttribute(descriptorAttributeData);

                var targetClientBuild = (uint)descriptorAttribute !.FindArgument(nameof(DescriptorAttribute.ClientBuild)) !.Value.Value !;
                var targetExpansion   = descriptorAttribute !.FindArgument(nameof(DescriptorAttribute.RealmType)) !.Value;

                var interfaceArgument = descriptorAttribute !.FindArgument(nameof(DescriptorAttribute.InterfaceType));
                var interfaceSymbol   = interfaceArgument !.Value.Value as ISymbol;

                var typeName = $"{interfaceSymbol!.Name}Impl";

                var handler = new EnumerationHandler(enumerationSymbol, context);

                handler.OnPropertyNotFound += (symbol, name) =>
                                              _missingPropertyDiagnostic.Report(context, symbol.Locations, name, interfaceSymbol.ToDisplayString());
                handler.OnMissingAttribute += (attrSymbol, target) =>
                                              _missingAttributeDiagnostic.Report(context, target.Locations, target.Name);
                handler.OnInvalidArity += (symbol, expected) =>
                                          (expected ? _expectedArityDiagnostic : _unexpectedArityDiagnostic).Report(context, symbol.Locations, symbol.Name, interfaceSymbol.ToDisplayString());

                handler.ResolveProperties();

                var sourceGenerator = CreateBuilder();

                sourceGenerator.AppendLine("using SniffExplorer.Parsing.Types;");
                sourceGenerator.AppendLine("using SniffExplorer.Parsing.Engine;");
                sourceGenerator.AppendLine("using SniffExplorer.Parsing.Engine.Tracking;");
                sourceGenerator.AppendLine("using SniffExplorer.Parsing.Engine.Tracking.UpdateFields;");
                sourceGenerator.AppendLine("using SniffExplorer.Parsing.Engine.Tracking.UpdateFields.Implementations;");
                sourceGenerator.AppendLine();

                using (sourceGenerator.BlockInvariant($"namespace {enumerationSymbol.ContainingNamespace.ToDisplayString()}.{(RealmExpansionType) targetExpansion.Value!}"))
                {
                    sourceGenerator.AppendLine($"[{generatedDescriptorData!.ToDisplayString()}(ClientBuild = {targetClientBuild}, RealmType = {targetExpansion.Type}.{(RealmExpansionType) targetExpansion.Value})]");
                    using (sourceGenerator.BlockInvariant($"public partial class {typeName} : {interfaceSymbol!.ToDisplayString()}"))
                    {
                        sourceGenerator.AppendLine(@"public int BitCount { get; }");
                        sourceGenerator.AppendLine();

                        foreach (var property in handler.Properties)
                        {
                            property.RenderDeclaration(sourceGenerator);
                        }

                        sourceGenerator.AppendLine();

                        using (sourceGenerator.BlockInvariant($"public {typeName}(ParsingContext context)"))
                        {
                            var iteratorGenerator = new IteratorGenerator();

                            foreach (var property in handler.Properties)
                            {
                                property.RenderInitializer(context, sourceGenerator, iteratorGenerator);
                            }

                            sourceGenerator.AppendLine();
                            sourceGenerator.AppendLineInvariant($"BitCount = {handler.Properties.Last.Value.NextOffset};");
                        }

                        sourceGenerator.AppendLine();

                        using (sourceGenerator.BlockInvariant($"public void ProcessValuesUpdate(Packet packet, UpdateMask updateMask)"))
                        {
                            sourceGenerator.AppendLineInvariant("if (!updateMask.Any()) return;");
                            sourceGenerator.AppendLine();

                            var iteratorGenerator = new IteratorGenerator();

                            foreach (var property in handler.Properties)
                            {
                                property.RenderParser(sourceGenerator, iteratorGenerator);
                            }
                        }
                    }
                }

                context.AddSource($"UpdateFields.V{targetClientBuild}.{typeName}.{(RealmExpansionType) targetExpansion.Value!}.Generated.cs", sourceGenerator.ToString());
            }
        }