示例#1
0
 public List <ImportStatement> Extract(RawCode code)
 {
     return(code.Lines
            .Select(line => line.Trim())
            .SkipWhile(line => !line.StartsWith("using"))
            .TakeWhile((line, index) => line.StartsWith("using") && line.EndsWith(";"))
            .Select(line => new ImportStatement
     {
         Import = line,
         LineIndex = code.Lines.IndexOf(line)
     })
            .ToList());
 }
示例#2
0
        public void Process(string projectRootPath)
        {
            foreach (var entry in Directory.GetFiles(projectRootPath, "*.cs", SearchOption.AllDirectories))
            {
                Console.WriteLine($"Processing {entry}");

                var code = new RawCode
                {
                    FilePath = entry,
                    Lines    = File.ReadAllLines(entry).ToList()
                };

                // Replace content
                Replacer.Replace(code);

                // Overwrite existing content
                File.WriteAllLines(code.FilePath, code.Lines);
            }
        }
示例#3
0
        public void Replace(RawCode code)
        {
            var notImplementedEmitStrategy = new NotImplementedEmitStrategy();

            var processed = new HashSet <string>();

            MethodDefinition FindUnprocessed()
            {
                // We need to continuously extract methods if a modification changes indexing
                var definitions = MethodExtractor.ExtractMethods(code);

                return(definitions.FirstOrDefault(definition => !processed.Contains(definition.Signature)));
            }

            MethodDefinition next;

            while ((next = FindUnprocessed()) != default)
            {
                var bodyLineStart = next.MethodBody.LineStartIndex;
                var bodyLineEnd   = next.MethodBody.LineEndIndex;

                switch (next.Declaration.Variant)
                {
                case MethodVariant.FullMethod:
                    if (next.MethodBody.NumLines == 0)
                    {
                        continue;
                    }

                    var lines = new List <string>(next.MethodBody.NumLines);
                    for (var i = 0; i < next.MethodBody.NumLines; i++)
                    {
                        lines.Add(EmitStrategy.Emit);
                    }

                    lines[^ 1] = notImplementedEmitStrategy.Emit;
示例#4
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
                }
            });
        }
示例#5
0
 public IEnumerable <string> ExtractDependencies(RawCode code)
 {
     return(code.Lines.TakeWhile(line => line.StartsWith("using")));
 }
示例#6
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;
                    }
                }
            }
        }