Lập Trình Công Cụ Đếm Line Code Bằng C# WinForm

Lập Trình Công Cụ Đếm Line Code Bằng C# WinForm

Winform có lẽ đã rất quen thuộc với các lập trình viên C#. Mình nhớ không nhầm thì đại học cũng có một môn dạy món này luôn. Hiện tại bạn có thể tham gia khoá học cơ bản về C# trên Codelearn.io. Ở bài viết này mình sẽ hướng dẫn các bạn làm một tool đơn giản đếm số lượng function, line of code của mỗi function từ một file và đếm tổng số line of code có trong file đó.

Nào bắt đầu thôi!

Ý tưởng

Trước đây, mình từng được giao task thống kê số lượng function và line of code của chúng. Đương nhiên là mình dùng tool có sẵn rồi, bạn có thể dùng Code Metrics trong Visual Studio để làm việc này nhé.

Vậy nên giờ mình nảy ra ý tưởng code một cái tool winform đơn giản, qua đó giúp các bạn học thêm một số kiến thức liên quan đến C#.

Yêu cầu

  • Đã nắm được những kiến thức cơ bản về C#, sẽ giúp bạn dễ tiếp cận hơn.
  • Nắm được cách design một giao diện cơ bản trên winform sử dụng các tools như: label, textbox, openfiledialog, listView.
  • Cài đặt Visual Studio

Mô tả tool

Đầu tiên bạn chọn button Select File, sau đó chọn đến file trong thư mục bạn muốn đếm, ví dụ như file Form1.cs trong project của visual studio chẳng hạn, đường link dẫn đến file sẽ hiện thị ở text box link file. Tiếp theo đó bạn click button Count Function, tool sẽ hiển thị danh sách các name function và số dòng code của chúng ở ListView. Bên cạnh đó ở Line of code sẽ hiện thị tổng số lines code trong file, và Number of function sẽ hiển thị số lượng function có trong file.

Các bước thực hiện

1. Tạo project winform app (.Net framework) trên Visual Studio 2019

Các bạn có thể xem thứ tự các hình dưới đây để tạo một new project nhé. Ở đây mình dùng bản 2019, bạn có thể dùng bản thấp hơn cũng không sao.

Chọn Create a new project

Chọn Windows Forms App (.NET Framework)

Nhập tên project, thư mục lưu project, lưu ý cái Framework bạn chọn tầm 4.5 thôi nhé.

2. Thiết kế giao diện

Sau khi đã tạo thành công project, bạn bắt đầu thiết kế giao diện winform. Các bạn chỉ việc kéo thả từ tool box ra những công cụ cần thiết như: label, textbox, openfiledialog, listView.

Các bạn hãy thiết kế một giao diện như hình hình dưới đây:


3. Code

3.1. Sự kiện click button Select File

Khi bạn click button này, sẽ mở ra một file dialog giúp bạn chọn file mà bạn muốn đếm. Trên dao diện click đúp chuột trái để vào function sự kiện này. Đoạn code dưới đây nằm trong sự kiện này.

        /// <summary>
        /// Click button Select File
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            openFileDialog1.ShowDialog();
            string fileName = openFileDialog1.FileName;
            txtLinkFile.Text = fileName.ToString();
        }

Đầu tiên dòng code này là show lên dialog để bạn có thể chọn file.

openFileDialog1.ShowDialog();

Tiếp theo get file name và show ra ở text box 1 (txtLinkFile):

string fileName = openFileDialog1.FileName;
            txtLinkFile.Text = fileName.ToString();

3.2. Sự kiện click button Count Function

Vậy làm như thế nào để nhận biết được đâu là function trong file. Nếu bạn đã học về function thì bạn có thể có những dấu hiệu nhận biệt như sau:

  • Function có thể bắt đầu với kiểu dữ liệu hoặc access modifiers (phạm vi truy cập của function)
  • Line name function kết thúc bằng ")"

Lưu ý: cách nhận biết này hoạt động đúng trên code C# có dạng function chuẩn như các function trong bài viết này. Do mình làm tool hướng dẫn nên không đưa ra quá nhiều cái phức tạp.

Dưới đây là function IsFunction check xem từng dòng có phải là dòng chứa function name hay không? 

/// <summary>
        /// Check function in file
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public bool IsFunction(string line)
        {
            if (line.Contains("//") || line.Contains("/*") || line.Contains("*/"))
                return false;

            var lines = line.Split(' ');
            var types = new List<string>
            {
                "void", "int", "long", "float", "short", "char", "double", "bool",
                "public", "private", "static", "internal", "protected", "protected internal"
            };

            if (lines.Any(l => types.Contains(l)) && line.EndsWith(")"))
            {
                if (!line.Contains(";"))
                {
                    return true;
                }
            }

            return false;
        }

Trong đoạn code trên mình có sử dụng một số thao tác như:

  • Điều kiện if
  • Xử lý chuỗi: Contains, Split, EndsWith. Tham khảo các thuộc tính xử lý chuỗi tại đây.
  • Linq: Any (Kiểm tra điều kiện trong any, nếu có data trả về true, nếu không thì trả về false)

Tiếp theo là function CountLineOfCodeFunction, nhằm kiểm tra xem số lượng dòng code của mỗi function. Như bạn thấy function trong C# sẽ bắt có cấu trúc:

public bool Test(string a)
{
// Code
}

Nó luôn tồn tại cặp "{}" để đánh dấu điểm khởi đầu và kết thúc hàm. Vậy ở đây chúng ta sẽ có ý tưởng, đếm số lượng "{" và "}" từ line function name, khi số lượng 2 cái này bằng nhau có nghĩa là đã count xong line code của function đó. Đầu vào function này sẽ là line function name, và data của file.

public int CountLineOfCodeFunction(string functionName, string[] data)
        {
            int count = 0;
            int start = 0, end = 0;

            foreach (var d in data)
            {
                if (d == functionName)
                {
                    count++;
                    continue;
                }

                if (count > 0)
                {

                    if (d.Contains("{"))
                    {
                        start++;
                        count++;
                        continue;
                    }

                    if (d.Contains("}"))
                    {
                        end++;
                        count++;
                        continue;
                    }

                    if (start == end)
                        break;

                    if (d != null)
                        count++;
                }


            }

            return count;
        }

Giải thích code:

int count = 0: đây là biến để đếm xem số lượng line code của function.

int start = 0, end = 0: 2 biến này đếm "{" và "}"

Chạy foreach trong data file (list string), nếu line nào trùng với functionName thì đó chính là điểm bắt đầu count, count = 1, continue để tiếp tục qua line tiếp theo. Lúc này count = 1, nếu count > 0 thì tiếp tục check xem line có chứa "}", nếu có thì start++ và continue, đồng thời cũng check xem line có chứa "}" hay không nếu có thì end++ và continue. Nếu như start = end thì đã count xong, thoát khỏi vòng lặp.

Trên giao diện click đúp button Count File để đến function xử lý sự kiện như ở dưới đây:

/// <summary>
        ///  Click buttton Count Function
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click_1(object sender, EventArgs e)
        {
            
            var path = txtLinkFile.Text; // Get đường dẫn file từ text box 1

            int numberOfFunction = 0; // Đếm số lượng function trong file
            int lineOfCode = 0; // Đếm số dòng code trong file

            var data = File.ReadAllLines(path); // Đọc toàn bộ dòng trong file, trả về string[]
            Dictionary<string, int> result = new Dictionary<string, int>(); // Lưu cặp giá trị: string (line function name), int (số lines code của function)

            foreach (var line in data)
            {
                if (IsFunction(line)) // == true: đây là line function name
                {
                    numberOfFunction++; // Tăng biến đếm lên 1.
                    int lineCode = CountLineOfCodeFunction(line, data); // Đếm số dòng code của function
                    result.Add(line, lineCode); // Add cặp giá trị: functionName, lineCode
                    }

                lineOfCode++; // Tăng biến đếm tổng line code lên 1
            }

            txtNumberFunction.Text = numberOfFunction.ToString(); // Hiển thị số lượng function ra text box 3
            txtLineOfCode.Text = lineOfCode.ToString(); // Hiển thị tổng số line code ra text box 2

            // In dữ liệu ra list view với 2 columns
            listView1.View = View.Details;
            listView1.Columns.Add("Function Name", 500); // Add column 1 với name và độ rộng
            listView1.Columns.Add("Line Of Code", 100); // Add column 2 với name và độ rộng

// Chèn dữ liệu vào list view
            foreach (var item in result)
            {
// Add từng mảng giá trị tương ứng
                listView1.Items.Add(new ListViewItem(new string[] { item.Key, item.Value.ToString() }));
            }

            listView1.GridLines = true;
        }

Function trên mình đã có comment giải thích các đoạn code rồi nhé. Code phần này khá dễ. Nếu không hiểu đoạn nào bạn có thể để lại comment cho mình nhé.

Sau khi bạn thực hiện như trên và đây là thành quả:

Định hướng phát triển tool

Trên đây mình chỉ viết tool rất đơn giản, các bạn có thể phát triển thêm các tính năng của tool như sau:

  • Cho phép count được trên nhiều ngôn ngữ khác.
  • Loại bỏ không đếm các comment, hay những dòng lệnh trống.
  • Xuất data ra file excel
  • Tối ưu các dòng lệnh, giúp tool chạy nhanh hơn khi với file lớn.

Lời kết

Trên đây là một tool đơn giản bằng winform, hi vọng các bạn có thể thực hiện viết tool này và qua học được một số kiến thức liên quan đến C# và WinForm. Các bạn có thể dựa vào phần code của mình để tối ưu hơn.

Nếu không hiểu vấn đề gì, hay có những góp ý hãy đến lại comment dưới đây để cùng trao đổi nhé.

Chúc các bạn thành công. Xin cảm ơn. Nhớ cho mình 5 sao nhé.