コード例 #1
0
            private IEnumerable <MethodDeclarationSyntax> ParseMethods()
            {
                var paramName            = _def.ResourceNameTyp.Name.ToLowerCamelCase();
                var name                 = Parameter(_ctx.Type <string>(), paramName);
                var allowUnparsed        = Parameter(_ctx.Type <bool>(), "allowUnparsed");
                var result               = Parameter(_ctx.Type(_def.ResourceNameTyp), "result").Out();
                var resultLocal          = Local(_ctx.Type(_def.ResourceNameTyp), "result");
                var resourceName         = Local(_ctx.Type <TemplatedResourceName>(), paramName == "resourceName" ? "resourceName2" : "resourceName");
                var unparsedResourceName = Local(_ctx.Type <UnparsedResourceName>(), "unparsedResourceName");
                MethodDeclarationSyntax parseSplitHelper;

                if (PatternDetails.SelectMany(x => x.PathSegments).Any(x => x.Segment.IsComplex))
                {
                    var s          = Parameter(_ctx.Type <string>(), "s");
                    var separators = Parameter(_ctx.ArrayType <char[]>(), "separators");
                    var i0         = Local(_ctx.Type <int>(), "i0");
                    var i1         = Local(_ctx.Type <int>(), "i1");
                    var i          = Local(_ctx.Type <int>(), "i");
                    var pshResult  = Local(_ctx.ArrayType <string[]>(), "result");
                    parseSplitHelper = Method(Private | Static, _ctx.ArrayType <string[]>(), "ParseSplitHelper")(s, separators)
                                       .WithBody(
                        pshResult.WithInitializer(NewArray(_ctx.ArrayType <string[]>(), separators.Access(nameof(Array.Length)).Plus(1))),
                        i0.WithInitializer(0),
                        For(i.WithInitializer(0), i.LessThanOrEqual(separators.Access(nameof(Array.Length))), i.PlusPlus())(
                            i1.WithInitializer(i.LessThan(separators.Access(nameof(Array.Length))).ConditionalOperator(
                                                   s.Call(nameof(string.IndexOf))(separators.ElementAccess(i), i0), s.Access(nameof(string.Length)))),
                            If(i1.LessThan(0).Or(i1.Equality(i0))).Then(Return(Null)),
                            pshResult.ElementAccess(i).Assign(s.Call(nameof(string.Substring))(i0, i1.Minus(i0))),
                            i0.Assign(i1.Plus(1))),
                        Return(pshResult));
                }
                else
                {
                    parseSplitHelper = null;
                }
                var tryParse2 = Method(Public | Static, _ctx.Type <bool>(), "TryParse")(name, allowUnparsed, result)
                                .WithBody(
                    _ctx.Type(typeof(GaxPreconditions)).Call(nameof(GaxPreconditions.CheckNotNull))(name, Nameof(name)),
                    resourceName,
                    PatternDetails.Zip(FromMethods(), (pattern, create) =>
                {
                    IEnumerable <(object code, IEnumerable <ExpressionSyntax> args)> codeAndArgs = pattern.PathSegments
                                                                                                   .Where(x => x.Segment.ParameterCount > 0)
                                                                                                   .Select((seg, segmentIndex) =>
                    {
                        if (seg.Segment.IsComplex)
                        {
                            var splitResult = Local(_ctx.ArrayType <string[]>(), $"split{segmentIndex}")
                                              .WithInitializer(This.Call(parseSplitHelper)(
                                                                   resourceName.ElementAccess(segmentIndex), NewArray(_ctx.ArrayType <char[]>())(seg.Segment.Separators.ToArray())));
                            var splitIf = If(splitResult.Equality(Null)).Then(
                                result.Assign(Null),
                                Return(false));
                            var args = Enumerable.Range(0, seg.Segment.ParameterCount).Select(i => splitResult.ElementAccess(i));
                            return((object)new object[] { splitResult, splitIf }, args);
                        }
                        else
                        {
                            return((object)null, new[] { resourceName.ElementAccess(segmentIndex) });
                        }
                    });
                    var elements = codeAndArgs.SelectMany(x => x.args);
                    return(If(pattern.PathTemplateField.Call(nameof(PathTemplate.TryParseName))(name, Out(resourceName))).Then(
                               codeAndArgs.Select(x => x.code),
                               result.Assign(This.Call(create)(elements.ToArray())),
                               Return(true)));
                }),
コード例 #2
0
        public ClassDeclarationSyntax GenerateServiceClass(SourceFileContext ctx)
        {
            var cls = Class(Modifier.Public, ServiceTyp, ctx.Type <BaseClientService>()).WithXmlDoc(XmlDoc.Summary($"The {ClassName} Service."));

            using (ctx.InClass(cls))
            {
                var discoveryVersionTyp = Typ.Manual("Google.Apis.Discovery", "DiscoveryVersion");
                var version             = Field(Modifier.Public | Modifier.Const, ctx.Type <string>(), "Version")
                                          .WithInitializer(ApiVersion)
                                          .WithXmlDoc(XmlDoc.Summary("The API version."));
                var discoveryVersion = Field(Modifier.Public | Modifier.Static, ctx.Type(discoveryVersionTyp), "DiscoveryVersionUsed")
                                       .WithInitializer(ctx.Type(discoveryVersionTyp).Access(nameof(DiscoveryVersion.Version_1_0)))
                                       .WithXmlDoc(XmlDoc.Summary("The discovery version used to generate this service."));

                var parameterlessCtor = Ctor(Modifier.Public, cls, ThisInitializer(New(ctx.Type <BaseClientService.Initializer>())()))()
                                        .WithBody()
                                        .WithXmlDoc(XmlDoc.Summary("Constructs a new service."));

                var initializerParam = Parameter(ctx.Type <BaseClientService.Initializer>(), "initializer");

                var featuresArrayInitializer = ApiFeatures.Any()
                    ? NewArray(ctx.ArrayType(Typ.Of <string[]>()))(ApiFeatures.ToArray())
                    : NewArray(ctx.ArrayType(Typ.Of <string[]>()), LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(0)));
                var features = Property(Modifier.Public | Modifier.Override, ctx.Type <IList <string> >(), "Features")
                               .WithGetBody(featuresArrayInitializer)
                               .WithXmlDoc(XmlDoc.Summary("Gets the service supported features."));

                var nameProperty = Property(Modifier.Public | Modifier.Override, ctx.Type <string>(), "Name")
                                   .WithGetBody(ApiName)
                                   .WithXmlDoc(XmlDoc.Summary("Gets the service name."));

                // Note: the following 4 properties have special handling post-generation, in terms
                // of adding the #if directives in.
                var baseUri = Property(Modifier.Public | Modifier.Override, ctx.Type <string>(), "BaseUri")
                              .WithGetBody(IdentifierName("BaseUriOverride").NullCoalesce(BaseUri))
                              .WithXmlDoc(XmlDoc.Summary("Gets the service base URI."));

                var basePath = Property(Modifier.Public | Modifier.Override, ctx.Type <string>(), "BasePath")
                               .WithGetBody(BasePath)
                               .WithXmlDoc(XmlDoc.Summary("Gets the service base path."));

                var batchUri = Property(Modifier.Public | Modifier.Override, ctx.Type <string>(), "BatchUri")
                               .WithGetBody(BatchUri)
                               .WithXmlDoc(XmlDoc.Summary("Gets the batch base URI; ", XmlDoc.C("null"), " if unspecified."));
                var batchPath = Property(Modifier.Public | Modifier.Override, ctx.Type <string>(), "BatchPath")
                                .WithGetBody(BatchPath)
                                .WithXmlDoc(XmlDoc.Summary("Gets the batch base path; ", XmlDoc.C("null"), " if unspecified."));

                var resourceProperties = Resources.Select(resource => resource.GenerateProperty(ctx)).ToArray();

                var parameterizedCtor = Ctor(Modifier.Public, cls, BaseInitializer(initializerParam))(initializerParam)
                                        .WithBlockBody(resourceProperties.Zip(Resources).Select(pair => pair.First.Assign(New(ctx.Type(pair.Second.Typ))(This))).ToArray())
                                        .WithXmlDoc(
                    XmlDoc.Summary("Constructs a new service."),
                    XmlDoc.Param(initializerParam, "The service initializer."));

                cls = cls.AddMembers(version, discoveryVersion, parameterlessCtor, parameterizedCtor, features, nameProperty, baseUri, basePath, batchUri, batchPath);

                if (AuthScopes.Any())
                {
                    var scopeClass = Class(Modifier.Public, Typ.Manual(PackageName, "Scope"))
                                     .WithXmlDoc(XmlDoc.Summary($"Available OAuth 2.0 scopes for use with the {Title}."));
                    using (ctx.InClass(scopeClass))
                    {
                        foreach (var scope in AuthScopes)
                        {
                            var field = Field(Modifier.Public | Modifier.Static, ctx.Type <string>(), scope.Name)
                                        .WithInitializer(scope.Value)
                                        .WithXmlDoc(XmlDoc.Summary(scope.Description));
                            scopeClass = scopeClass.AddMembers(field);
                        }
                    }

                    var scopeConstantsClass = Class(Modifier.Public | Modifier.Static, Typ.Manual(PackageName, "ScopeConstants"))
                                              .WithXmlDoc(XmlDoc.Summary($"Available OAuth 2.0 scope constants for use with the {Title}."));
                    using (ctx.InClass(scopeConstantsClass))
                    {
                        foreach (var scope in AuthScopes)
                        {
                            var field = Field(Modifier.Public | Modifier.Const, ctx.Type <string>(), scope.Name)
                                        .WithInitializer(scope.Value)
                                        .WithXmlDoc(XmlDoc.Summary(scope.Description));
                            scopeConstantsClass = scopeConstantsClass.AddMembers(field);
                        }
                    }

                    cls = cls.AddMembers(scopeClass, scopeConstantsClass);
                }

                // TODO: Find an example of this...
                foreach (var method in Methods)
                {
                    cls = cls.AddMembers(method.GenerateDeclarations(ctx).ToArray());
                }

                cls = cls.AddMembers(resourceProperties);
            }
            return(cls);
        }