예제 #1
0
        public MethodDeclaration TryFind(int lineIndex, RawCode code)
        {
            var currLine = code.Lines[lineIndex].Trim();

            if (string.IsNullOrEmpty(currLine))
            {
                return(null);
            }

            // Ensure method begins with access modifier
            var parts = currLine.Split(" ");

            if (!AccessModifiers.Contains(parts[0]) && !Primitives.Contains(parts[0]))
            {
                return(null);
            }

            // Check inline format `int x(int y) => y * 2;`
            if (currLine.Contains("=>") && currLine.Contains(";") && !currLine.Contains("{") && !currLine.Contains("}"))
            {
                return(new MethodDeclaration
                {
                    Signature = new CodeSegment
                    {
                        LineStartIndex = lineIndex,
                        LineEndIndex = lineIndex,
                        Content = currLine.Split("=>")[0].Trim()
                    },
                    Variant = MethodVariant.InlineMethod
                });
            }

            // Ensure we aren't looking at a class
            if (parts.Any(p => ClassTypes.Contains(p)) || parts.Length < 2)
            {
                return(null);
            }

            // We are looking at [accessModifier] [name]
            var numOpenParenthesis = currLine.Count(c => c == '(');
            var endIndex           = -1;

            if (numOpenParenthesis > 0)
            {
                for (var i = lineIndex; i < code.Lines.Count; i++)
                {
                    var numCloseParenthesis = code.Lines[i].Count(ch => ch == ')');
                    if (numCloseParenthesis > 0)
                    {
                        numOpenParenthesis -= numCloseParenthesis;
                    }

                    if (numOpenParenthesis == 0)
                    {
                        endIndex = i;
                        break;
                    }
                }
            }

            if (endIndex == -1 || !code.Lines[endIndex + 1].EndsWith("{"))
            {
                return(null);
            }

            var content = code.Join(lineIndex, endIndex);

            return(new MethodDeclaration
            {
                Variant = MethodVariant.FullMethod,
                Signature = new CodeSegment
                {
                    Content = content,
                    LineStartIndex = lineIndex,
                    LineEndIndex = endIndex
                }
            });
        }
예제 #2
0
        public IEnumerable <MethodDefinition> ExtractMethods(RawCode code)
        {
            var numOpenBrackets            = 0;
            MethodDefinition currMethodDef = null;

            for (var i = 0; i < code.Lines.Count; i++)
            {
                var currLine = code.Lines[i].Trim();

                if (currMethodDef == null)
                {
                    var declaration = MethodDeclarationIdentifier.TryFind(i, code);
                    if (declaration == null)
                    {
                        continue;
                    }

                    // Found new method definition
                    var signatureLineEndIndex = declaration.Signature.LineEndIndex;
                    var methodBody            = declaration.Variant == MethodVariant.FullMethod
                        ? new CodeSegment
                    {
                        LineStartIndex = signatureLineEndIndex + 2,
                        LineEndIndex   = signatureLineEndIndex + 1
                    }
                        : new CodeSegment {
                        LineStartIndex = signatureLineEndIndex, LineEndIndex = signatureLineEndIndex
                    };

                    currMethodDef = new MethodDefinition
                    {
                        Signature  = currLine,
                        FullMethod = new CodeSegment
                        {
                            LineStartIndex = i,
                            LineEndIndex   = i
                        },
                        MethodBody  = methodBody,
                        Declaration = declaration
                    };

                    if (declaration.Variant == MethodVariant.InlineMethod)
                    {
                        currMethodDef.MethodBody.LineStartIndex = currMethodDef.MethodBody.LineEndIndex;

                        currMethodDef.FullMethod.Content = currLine;
                        currMethodDef.MethodBody.Content = currLine.Split("=>")[1].Trim();

                        yield return(currMethodDef);

                        currMethodDef = null;
                    }
                }
                else
                {
                    // Check if } was reached, potentially end of method
                    if (currLine.Contains("}"))
                    {
                        numOpenBrackets--;
                    }
                    if (currLine.Contains("{"))
                    {
                        numOpenBrackets++;
                    }

                    currMethodDef.FullMethod.LineEndIndex++;

                    if (numOpenBrackets > 0)
                    {
                        // Expand method body length if an orphan { still exists
                        currMethodDef.MethodBody.LineEndIndex++;
                    }
                    else
                    {
                        // Set full method content from line start to line end
                        currMethodDef.FullMethod.Content = code.Join(currMethodDef.FullMethod);

                        // Set method body content
                        if (currMethodDef.MethodBody.NumLines == 0)
                        {
                            currMethodDef.MethodBody.Content = string.Empty;
                        }
                        else
                        {
                            currMethodDef.MethodBody.Content = code.Join(currMethodDef.MethodBody);

                            if (currMethodDef.MethodBody.Content.Trim().Equals("}"))
                            {
                                currMethodDef.MethodBody.Content = string.Empty;
                            }
                        }

                        yield return(currMethodDef);

                        i = currMethodDef.FullMethod.LineEndIndex;

                        // Reset method definition
                        currMethodDef = null;
                    }
                }
            }
        }