public override object VisitNamespace_body([NotNull] CSharpParser.Namespace_bodyContext context)
        {
            var isServiceNamespace = GetCurrentNamespace() == _serviceFile.ServiceNamespace;

            if (isServiceNamespace)
            {
                _hasServiceNamespace = true;
            }

            VisitChildren(context);

            if (!_hasServiceInterface && isServiceNamespace)
            {
                var classInterfaceStopIndex = _cSharpParserService.GetClassInterfaceStopIndex(context);

                var preclassWhitespace = Tokens.GetHiddenTokensToLeft(context.Start.TokenIndex, Lexer.Hidden);
                int tabLevels          = 1 + ((preclassWhitespace?.Count ?? 0) > 0 ?
                                              _stringUtilService.CalculateTabLevels(preclassWhitespace[0]?.Text ?? string.Empty, _tabString) : 0);

                var interfaceDeclaration = _cSharpParserService.GenerateClassInterfaceDeclaration(
                    _serviceFile.ServiceDeclaration,
                    tabLevels,
                    _tabString);

                IsModified = true;
                Rewriter.InsertAfter(classInterfaceStopIndex, interfaceDeclaration);
            }

            return(null);
        }
Exemplo n.º 2
0
        public override object VisitNamespace_declaration([NotNull] CSharpParser.Namespace_declarationContext context)
        {
            _currentNamespace.Push(context.qualified_identifier().GetText());

            var isBreadcrumbNamespace = false;

            if (GetCurrentNamespace() == _breadcrumbNamespace)
            {
                _usingSet.Remove(GetCurrentNamespace());
                _hasBreadcrumbNamespace = true;
                isBreadcrumbNamespace   = true;
            }

            VisitChildren(context);

            if (isBreadcrumbNamespace)
            {
                if (!_hasBreadcrumbClass)
                {
                    var classStopIndex = _cSharpParserService.GetClassInterfaceStopIndex(context.namespace_body());

                    var prenamespaceWhitespace = Tokens.GetHiddenTokensToLeft(context.Start.TokenIndex, Lexer.Hidden);

                    int tabLevels = 1 + ((prenamespaceWhitespace?.Count ?? 0) > 0 ?
                                         _stringUtilService.CalculateTabLevels(prenamespaceWhitespace[0]?.Text ?? string.Empty, _tabString) : 0);

                    var breadcrumbClassString = _breadcrumbCommandParserService.GenerateBreadcrumbClassInterfaceDeclaration(
                        _breadcrumbDeclaration,
                        tabLevels,
                        _tabString);

                    IsModified = true;
                    Rewriter.InsertAfter(classStopIndex, breadcrumbClassString);
                }
            }

            _ = _currentNamespace.Pop();
            return(null);
        }
        public override object VisitClass_declaration([NotNull] CSharpParser.Class_declarationContext context)
        {
            var currentNamespace = string.Join(".", _currentNamespace.ToArray().Reverse());

            if (context.identifier().GetText() == _constructorClassName &&
                currentNamespace == _constructorClassNamespace)
            {
                _isConstructorClassFound = true;

                var preclassWhitespace = Tokens.GetHiddenTokensToLeft(context.Start.TokenIndex, Lexer.Hidden);

                int classBodyTabLevels = 1 + ((preclassWhitespace?.Count ?? 0) > 0 ?
                                              _stringUtilService.CalculateTabLevels(preclassWhitespace[0]?.Text ?? string.Empty, _tabString) : 0);

                int ctorBodyTabLevels = classBodyTabLevels + 1;

                int?finalConstantOrField = null;
                int?finalField           = null;
                int?finalProperty        = null;

                CSharpParser.Constructor_declarationContext constructorContext = null;
                bool hasServiceField   = false;
                bool hasCtorParam      = false;
                bool hasCtorAssignment = false;

                var members = context?.class_body()?.class_member_declarations()?.class_member_declaration();
                if (members != null)
                {
                    foreach (var member in members)
                    {
                        if (member.constant_declaration() != null)
                        {
                            finalConstantOrField = member.constant_declaration().Stop.TokenIndex;
                        }
                        else if (member.field_declaration() != null)
                        {
                            var fieldDec = member.field_declaration();
                            finalField           = fieldDec.Stop.TokenIndex;
                            finalConstantOrField = fieldDec.Stop.TokenIndex;
                            if (fieldDec.type_().GetText() == _serviceInterfaceType)
                            {
                                foreach (var varDec in fieldDec.variable_declarators().variable_declarator())
                                {
                                    if (varDec.identifier().GetText() ==
                                        $"_{_serviceIdentifier}")
                                    {
                                        hasServiceField = true;
                                        break;
                                    }
                                }
                            }
                        }
                        else if (member.property_declaration() != null)
                        {
                            finalProperty = member.property_declaration().Stop.TokenIndex;
                        }
                        else if (member.constructor_declaration() != null)
                        {
                            constructorContext ??= member.constructor_declaration();
                        }
                    }
                }

                int fieldStopIndex = finalField
                                     ?? finalConstantOrField
                                     ?? context.class_body().OPEN_BRACE().Symbol.TokenIndex;

                int?constructorStopIndex = null;

                var           fieldStringBuilder       = new StringBuilder();
                StringBuilder constructorStringBuilder = null;

                if (!hasServiceField)
                {
                    fieldStringBuilder.Append(_cSharpParserService.GenerateFieldDeclaration(
                                                  _fieldDeclaration,
                                                  classBodyTabLevels,
                                                  _tabString));
                }

                if (constructorContext is null)
                {
                    constructorStopIndex = finalProperty
                                           ?? finalConstantOrField
                                           ?? fieldStopIndex;

                    constructorStringBuilder = constructorStopIndex == fieldStopIndex
                        ? fieldStringBuilder : new StringBuilder();

                    constructorStringBuilder.Append(
                        _cSharpParserService.GenerateConstructorDeclaration(
                            _constructorDeclaration,
                            classBodyTabLevels,
                            _tabString));
                }
                else
                {
                    CSharpParser.Fixed_parameterContext finalFixedParam = null;

                    var formalParamList = constructorContext?.constructor_declarator()?.formal_parameter_list();
                    if (formalParamList != null)
                    {
                        var fixedParams = formalParamList.fixed_parameters();
                        if (fixedParams != null)
                        {
                            foreach (var fixedParam in fixedParams.fixed_parameter())
                            {
                                if (fixedParam.type_().GetText() == _serviceInterfaceType &&
                                    fixedParam.identifier().GetText() == _serviceIdentifier)
                                {
                                    hasCtorParam = true;
                                    break;
                                }
                            }
                            finalFixedParam = fixedParams.fixed_parameter().Last();
                        }
                    }
                    if (!hasCtorParam)
                    {
                        var ctorParam = _cSharpCommonStgService.RenderFixedParameter(_constructorParameter);

                        int fixedParamStopIndex = finalFixedParam?.Stop?.TokenIndex
                                                  ?? constructorContext.constructor_declarator().OPEN_PARENS().Symbol.TokenIndex;

                        var paramStringBuilder = new StringBuilder();
                        if (finalFixedParam != null)
                        {
                            var preFinalParamWhitespace = Tokens.GetHiddenTokensToLeft(
                                finalFixedParam?.Start?.TokenIndex ?? -1, Lexer.Hidden);

                            int finalParamtabs = (preFinalParamWhitespace?.Count ?? 0) > 0 ?
                                                 _stringUtilService.CalculateTabLevels(
                                preFinalParamWhitespace?[0]?.Text ?? string.Empty, _tabString) : 0;

                            if (finalParamtabs > 0)
                            {
                                paramStringBuilder.Append(",\r\n");
                                paramStringBuilder.Append(_stringUtilService.TabString(
                                                              ctorParam,
                                                              finalParamtabs,
                                                              _tabString));
                                if (formalParamList?.parameter_array() != null)
                                {
                                    var preParamArrayWhitespaceArray = Tokens.GetHiddenTokensToLeft(
                                        formalParamList.parameter_array().Start.TokenIndex, Lexer.Hidden);

                                    string preParamArrayWhitespace =
                                        preParamArrayWhitespaceArray.Count > 0 ?
                                        preParamArrayWhitespaceArray[0].Text : string.Empty;

                                    if (!Regex.IsMatch(preParamArrayWhitespace, @"\r?\n"))
                                    {
                                        _isRewritten = true;
                                        Rewriter.InsertBefore(
                                            formalParamList.parameter_array().Start.TokenIndex,
                                            "\r\n" +
                                            _stringUtilService.TabString(string.Empty, finalParamtabs, _tabString));
                                    }
                                }
                            }
                            else
                            {
                                paramStringBuilder.Append(", ");
                                paramStringBuilder.Append(ctorParam);
                            }
                        }
                        else
                        {
                            paramStringBuilder.Append("\r\n");
                            paramStringBuilder.Append(
                                _stringUtilService.TabString(ctorParam, ctorBodyTabLevels, _tabString));
                            if (formalParamList?.parameter_array() != null)
                            {
                                var preParamArrayWhitespaceArray = Tokens.GetHiddenTokensToLeft(
                                    formalParamList.parameter_array().Start.TokenIndex, Lexer.Hidden);

                                string preParamArrayWhitespace =
                                    preParamArrayWhitespaceArray.Count > 0 ?
                                    preParamArrayWhitespaceArray[0].Text : string.Empty;

                                if (!Regex.IsMatch(preParamArrayWhitespace, $"\r?\n"))
                                {
                                    _isRewritten = true;
                                    Rewriter.InsertBefore(
                                        formalParamList.parameter_array().Start.TokenIndex,
                                        "\r\n" +
                                        _stringUtilService.TabString(string.Empty, ctorBodyTabLevels, _tabString));
                                }
                            }
                        }

                        var paramString = paramStringBuilder.ToString();
                        if (paramString.Length > 0)
                        {
                            _isRewritten = true;
                            Rewriter.InsertAfter(fixedParamStopIndex, paramString);
                        }
                    }

                    string ctorAssignString = _cSharpCommonStgService.RenderSimpleAssignment(_constructorAssignment);

                    var constructorBody = constructorContext?.constructor_body();
                    if (constructorBody.SEMICOLON() != null)
                    {
                        _isRewritten = true;
                        Rewriter.Replace(constructorBody.SEMICOLON().Symbol.TokenIndex, _stringUtilService.TabString(
                                             $@"\r\n{{\r\n{_tabString}{ctorAssignString}\r\n}}",
                                             classBodyTabLevels,
                                             _tabString));
                    }
                    else
                    {
                        var block         = constructorBody.block();
                        var statementList = block?.statement_list()?.GetText();
                        if (statementList != null)
                        {
                            var assignmentMatchString =
                                $@"[\s;{{]_{_serviceIdentifier}\s*=\s*{_serviceIdentifier}\s*;";

                            hasCtorAssignment = Regex.Match(statementList, assignmentMatchString).Success;
                        }

                        if (!hasCtorAssignment)
                        {
                            int?finalAssignment     = block.statement_list().statement().Last().Stop.TokenIndex;
                            int assignmentStopIndex = finalAssignment
                                                      ?? block.OPEN_BRACE().Symbol.TokenIndex;

                            var assignmentStringBuilder = new StringBuilder();

                            assignmentStringBuilder.Append("\r\n");
                            assignmentStringBuilder.Append(_stringUtilService.TabString(
                                                               ctorAssignString, ctorBodyTabLevels, _tabString));

                            var postAssignmentStopWhitespaceArray = Tokens.GetHiddenTokensToRight(
                                assignmentStopIndex, Lexer.Hidden);

                            string postAssignmentStopWhitespace =
                                postAssignmentStopWhitespaceArray.Count > 0 ?
                                postAssignmentStopWhitespaceArray[0].Text : string.Empty;

                            if (!Regex.IsMatch(postAssignmentStopWhitespace, @"\r?\n"))
                            {
                                assignmentStringBuilder.Append("\r\n");
                            }

                            var assignmentString = assignmentStringBuilder.ToString();
                            if (assignmentString.Length > 0)
                            {
                                _isRewritten = true;
                                Rewriter.InsertAfter(assignmentStopIndex, assignmentString);
                            }
                        }
                    }
                }

                var fieldString = fieldStringBuilder.ToString();
                if (fieldString.Length > 0)
                {
                    _isRewritten = true;
                    Rewriter.InsertAfter(fieldStopIndex, fieldString);
                }

                if (constructorStringBuilder != null &&
                    constructorStopIndex != fieldStopIndex)
                {
                    var constructorString = constructorStringBuilder.ToString();
                    if (constructorString.Length > 0)
                    {
                        _isRewritten = true;
                        Rewriter.InsertAfter(Tokens.Get(constructorStopIndex ?? -1), constructorString);
                    }
                }
            }
            VisitChildren(context);
            return(null);
        }
Exemplo n.º 4
0
        public override object VisitClass_member_declaration([NotNull] CSharpParser.Class_member_declarationContext context)
        {
            var method = context?.method_declaration();

            // Find method "public void ConfigureServices(IServiceCollection services)"
            if (method != null &&
                method.method_header().member_name().identifier().GetText() == "ConfigureServices" &&
                string.Join(".", _currentClass.ToArray().Reverse()) == "Startup" &&
                string.Join(".", _currentNamespace.ToArray().Reverse()) == _rootNamespace
                )
            {
                _isFoundConfigureServices = true;

                var paramList = method?.method_header()?.formal_parameter_list()?.fixed_parameters()?.fixed_parameter();
                if (paramList is null)
                {
                    // throw
                }

                // Get name of IServiceCollection parameter (services)
                string serviceCollectionName = null;
                foreach (var param in paramList)
                {
                    if (param.type_().GetText() == nameof(IServiceCollection))
                    {
                        serviceCollectionName = param.identifier().GetText();
                        break;
                    }
                }

                if (serviceCollectionName is null)
                {
                    // throw
                }

                //  Check each services.Add[Lifespan] method in the form
                //          If TypeParameters:  services.AddScoped(typeof(IMyService<>), typeof(MyService<>));
                //          Else:               services.AddScoped<IMyService, MyService>();
                //      If found and Lifespan in services.Add[Lifespan] == Service.Lifespan:
                //          No action taken
                //      Else if found and Lifespan in services.Add[Lifespan] != Service.Lifespan:
                //          Replace Add[Lifespan] with Add[Service.Lifespan] in token stream
                //      Else:
                //          Create StringTemplate for services.Add[Lifespan] statement
                //              If TypeParameters:  services.AddScoped(typeof(IMyService<>), typeof(MyService<>));
                //              Else:               services.AddScoped<IMyService, MyService>();
                //          Use rewriter to insert services.Add[Lifespan] into token stream
                //          Write parse tree as string to Startup.cs
                var missingRegInfo = new List <StartupRegistrationInfo>();

                var body = _cSharpParserService.GetTextWithWhitespace(Tokens, method.method_body());

                foreach (var regInfo in _startupRegInfoList)
                {
                    if (!Regex.Match(body, ServiceRegistrationMatchString(regInfo)).Success)
                    {
                        missingRegInfo.Add(regInfo);
                    }
                }

                if (missingRegInfo.Count > 0)
                {
                    if (method?.method_body()?.block() is null)
                    {
                        // throw
                    }
                    else
                    {
                        var closeBranceIndex = method.method_body().block().CLOSE_BRACE().Symbol.TokenIndex;

                        var preclassWhitespace = Tokens.GetHiddenTokensToLeft(closeBranceIndex, Lexer.Hidden);

                        int tabLevels = (preclassWhitespace?.Count ?? 0) > 0 ?
                                        _stringUtilService.CalculateTabLevels(preclassWhitespace[0]?.Text ?? string.Empty, _tabString) : 0;

                        var regCallStrings = new List <string>();

                        foreach (var regInfo in missingRegInfo)
                        {
                            var regCallString = _serviceCommandStgService.RenderServiceStartupRegistrationCall(
                                serviceClassType: regInfo.ServiceClassType,
                                serviceBaseType: regInfo.ServiceBaseType,
                                hasTypeParameters: regInfo.HasTypeParameters,
                                serviceLifespan: regInfo.ServiceLifespan.ToString());

                            regCallStrings.Add(serviceCollectionName + regCallString + ";");
                        }
                        var registrationStatement =
                            "\r\n" +
                            _stringUtilService.TabString(
                                string.Join("\r\n", regCallStrings), tabLevels + 1, _tabString) +
                            "\r\n" +
                            _stringUtilService.TabString(string.Empty, tabLevels, _tabString);

                        IsModified = true;
                        Rewriter.InsertBefore(closeBranceIndex, registrationStatement);
                        return(null);
                    }
                }
            }

            VisitChildren(context);
            return(null);
        }