Пример #1
0
        public override object VisitClass_declaration([NotNull] CSharpParser.Class_declarationContext context)
        {
            _currentClass.Push(context.identifier().GetText());

            var classBaseType = context?.class_base()?.class_type()?.GetText();

            _isControllerClass.Push(classBaseType == "Controller");

            VisitChildren(context);

            _ = _isControllerClass.Pop();
            _ = _currentClass.Pop();
            return(null);
        }
Пример #2
0
        public override object VisitClass_declaration([NotNull] CSharpParser.Class_declarationContext context)
        {
            bool matchNames        = context.identifier().GetText() == ServiceClassName;
            bool isTypeParamsMatch = true;
            var  typeParams        = context?.type_parameter_list()?.type_parameter();

            if (!(typeParams is null && (TypeParameters is null || TypeParameters.Count == 0)))
            {
                if ((typeParams?.Length ?? 0) != (TypeParameters?.Count ?? 0))
                {
                    isTypeParamsMatch = false;
                }
                else
                {
                    for (int i = 0; i < typeParams.Length; ++i)
                    {
                        if (typeParams[i].identifier().GetText() != TypeParameters[i].TypeParam)
                        {
                            isTypeParamsMatch = false;
                            break;
                        }
                    }
                }
            }

            if (matchNames && isTypeParamsMatch)
            {
                HasServiceClass          = true;
                Results.ServiceNamespace = string.Join(".", _currentNamespace.ToArray().Reverse());
                var classDeclaration = new ClassInterfaceDeclaration()
                {
                    IsInterface = false,
                    Attributes  = _cSharpParserService.GetTextWithWhitespace(Tokens, context?.attributes()),
                    Identifier  = ServiceClassName
                };

                //Results.ClassInterfaceDeclarations.Add(className, classDeclaration);
                Results.ServiceDeclaration = classDeclaration;

                if (context?.PARTIAL()?.GetText() != null)
                {
                    classDeclaration.Modifiers.Add(context.PARTIAL().GetText());
                }

                if (context?.class_modifier() != null)
                {
                    foreach (var modifier in context.class_modifier())
                    {
                        classDeclaration.Modifiers.Add(modifier.GetText());
                    }
                }

                var typeParameters     = context?.type_parameter_list()?.type_parameter();
                var constraintsClauses =
                    context?.type_parameter_constraints_clauses()?.type_parameter_constraints_clause();

                classDeclaration.TypeParameters =
                    _cSharpParserService.ParseTypeParameterList(Tokens, typeParameters, constraintsClauses);

                var baseClassType = _cSharpParserService.GetTextWithWhitespaceMinifiedLite(
                    Tokens, context?.class_base()?.class_type());
                var interfaceTypes = context?.class_base()?.interface_type_list()?.interface_type();
                if (interfaceTypes != null || baseClassType != null)
                {
                    classDeclaration.Base = new ClassInterfaceBase();
                    if (baseClassType != null)
                    {
                        classDeclaration.Base.ClassType = baseClassType;
                    }

                    if (interfaceTypes != null)
                    {
                        foreach (var interfaceType in interfaceTypes)
                        {
                            classDeclaration.Base.InterfaceTypeList.Add(
                                _cSharpParserService.GetTextWithWhitespaceMinifiedLite(Tokens, interfaceType));
                        }
                    }
                }

                var memberDeclarations = context?.class_body()?.class_member_declarations()?.class_member_declaration();
                if (memberDeclarations != null)
                {
                    foreach (var memberDeclaration in memberDeclarations)
                    {
                        bool isPublic = false;

                        var classMethodDeclaration   = memberDeclaration?.method_declaration();
                        var classPropertyDeclaration = memberDeclaration?.property_declaration();
                        if (classMethodDeclaration != null)
                        {
                            var methodDeclaration = new MethodDeclaration()
                            {
                                Attributes = _cSharpParserService.GetTextWithWhitespace(
                                    Tokens, classMethodDeclaration?.method_header()?.attributes()),
                                ReturnType = _cSharpParserService.GetTextWithWhitespaceMinifiedLite(
                                    Tokens, classMethodDeclaration.method_header().return_type()),
                                Identifier = classMethodDeclaration.method_header().member_name().GetText(),
                                Body       = _cSharpParserService.GetTextWithWhitespaceUntab(
                                    Tokens, classMethodDeclaration.method_body())
                            };

                            var methodModifiers = classMethodDeclaration?.method_header()?.method_modifier();
                            if (methodModifiers != null)
                            {
                                foreach (var methodMod in methodModifiers)
                                {
                                    if (methodMod.GetText() == Keywords.Public)
                                    {
                                        isPublic = true;
                                    }
                                    methodDeclaration.Modifiers.Add(methodMod.GetText());
                                }
                            }

                            if (!isPublic)
                            {
                                continue;
                            }

                            var formalParameterList = classMethodDeclaration?.method_header()?.formal_parameter_list();
                            methodDeclaration.FormalParameterList =
                                _cSharpParserService.ParseFormalParameterList(Tokens, formalParameterList);

                            var methodTypeParameters =
                                classMethodDeclaration?.method_header()?.type_parameter_list()?.type_parameter();
                            var methodConstraintsClauses = classMethodDeclaration
                                                           ?.method_header()
                                                           ?.type_parameter_constraints_clauses()
                                                           ?.type_parameter_constraints_clause();

                            methodDeclaration.TypeParameters = _cSharpParserService
                                                               .ParseTypeParameterList(Tokens, methodTypeParameters, methodConstraintsClauses);

                            classDeclaration.Body.MethodDeclarations.Add(methodDeclaration);
                        }
                        else if (classPropertyDeclaration != null)
                        {
                            var propertyDeclaration = new PropertyDeclaration()
                            {
                                Attributes = _cSharpParserService.GetTextWithWhitespace(
                                    Tokens, classPropertyDeclaration?.attributes()),
                                Type = _cSharpParserService.GetTextWithWhitespaceMinifiedLite(
                                    Tokens, classPropertyDeclaration.type_()),
                                Identifier = classPropertyDeclaration.member_name().GetText(),
                                Body       = new PropertyBody()
                                {
                                    Text = _cSharpParserService.GetTextWithWhitespaceUntab(
                                        Tokens, classPropertyDeclaration.property_body()),
                                    HasGetAccessor = classPropertyDeclaration.property_body().expression() != null
                                                     | classPropertyDeclaration.property_body()
                                                     ?.accessor_declarations()
                                                     ?.get_accessor_declaration() != null,
                                    HasSetAccessor = classPropertyDeclaration.property_body()
                                                     ?.accessor_declarations()
                                                     ?.set_accessor_declaration() != null
                                }
                            };

                            var propertyModifiers = classPropertyDeclaration?.property_modifier();
                            if (propertyModifiers != null)
                            {
                                foreach (var propModifier in propertyModifiers)
                                {
                                    if (propModifier.GetText() == Keywords.Public)
                                    {
                                        isPublic = true;
                                    }
                                    propertyDeclaration.Modifiers.Add(propModifier.GetText());
                                }
                            }

                            if (!isPublic)
                            {
                                continue;
                            }

                            classDeclaration.Body.PropertyDeclarations.Add(propertyDeclaration);
                        }
                    }
                }
            }
            VisitChildren(context);
            return(null);
        }
        public override object VisitClass_declaration([NotNull] CSharpParser.Class_declarationContext context)
        {
            _currentClass.Push(context.identifier().GetText());

            var classBaseType = context?.class_base()?.class_type()?.GetText();

            _isControllerClass.Push(classBaseType == "Controller");
            _isClassModified.Push(false);

            VisitChildren(context);

            if (_isClassModified.Peek() && _isControllerClass.Peek())
            {
                var currentClass                = GetCurrentClass();
                var serviceInterfaceName        = GetServiceInterfaceName();
                var controllerServiceIdentifier = "breadcrumbService";

                var fieldDeclaration = new FieldDeclaration()
                {
                    Modifiers = new List <string>()
                    {
                        Keywords.Private, Keywords.Readonly
                    },
                    Type = serviceInterfaceName,
                    VariableDeclarator = new VariableDeclarator()
                    {
                        Identifier = $"_{controllerServiceIdentifier}"
                    }
                };

                var constructorParameter = new FixedParameter()
                {
                    Type       = serviceInterfaceName,
                    Identifier = controllerServiceIdentifier
                };

                var constructorAssignment = new SimpleAssignment()
                {
                    LeftHandSide  = $"_{controllerServiceIdentifier}",
                    RightHandSide = controllerServiceIdentifier
                };

                var constructorDeclaration = new ConstructorDeclaration()
                {
                    Modifiers = new List <string>()
                    {
                        Keywords.Public
                    },
                    Identifier          = currentClass,
                    FormalParameterList = new FormalParameterList()
                    {
                        FixedParameters = new List <FixedParameter>()
                        {
                            constructorParameter
                        }
                    },
                    Body = new ConstructorBody()
                    {
                        Statements = new List <Statement>()
                        {
                            new Statement()
                            {
                                SimpleAssignment = constructorAssignment
                            }
                        }
                    }
                };

                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() == serviceInterfaceName)
                            {
                                foreach (var varDec in fieldDec.variable_declarators().variable_declarator())
                                {
                                    if (varDec.identifier().GetText() ==
                                        $"_{controllerServiceIdentifier}")
                                    {
                                        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() == serviceInterfaceName &&
                                    fixedParam.identifier().GetText() == controllerServiceIdentifier)
                                {
                                    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"))
                                    {
                                        IsModified = 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"))
                                {
                                    IsModified = true;
                                    Rewriter.InsertBefore(
                                        formalParamList.parameter_array().Start.TokenIndex,
                                        "\r\n" +
                                        _stringUtilService.TabString(string.Empty, ctorBodyTabLevels, _tabString));
                                }
                            }
                        }

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

                    string ctorAssignString = _cSharpCommonStgService.RenderSimpleAssignment(constructorAssignment);

                    var constructorBody = constructorContext?.constructor_body();
                    if (constructorBody.SEMICOLON() != null)
                    {
                        IsModified = 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;{{]_{controllerServiceIdentifier}\s*=\s*{controllerServiceIdentifier}\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)
                            {
                                IsModified = true;
                                Rewriter.InsertAfter(assignmentStopIndex, assignmentString);
                            }
                        }
                    }
                }

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

                if (constructorStringBuilder != null &&
                    constructorStopIndex != fieldStopIndex)
                {
                    var constructorString = constructorStringBuilder.ToString();
                    if (constructorString.Length > 0)
                    {
                        IsModified = true;
                        Rewriter.InsertAfter(Tokens.Get(constructorStopIndex ?? -1), constructorString);
                    }
                }
            }

            _ = _isClassModified.Pop();
            _ = _isControllerClass.Pop();
            _ = _currentClass.Pop();
            return(null);
        }