Đặt vấn đề API là viết tắt của Giao diện lập trình ứng dụng (Application Programming Interfaces), là một cách cho phép các ứng dụng và thư viện khác nhau giao tiếp và trao đổi dữ liệu với nhau. API có nhiều loại khác nhau, nhưng một loại phổ biến là API REST được sử dụng trong nền tảng Web. Tuy nhiên, trong bài toán này sẽ tập trung đến loại API dưới dạng các thư viện trong chương trình Java thuần tuý. Đối với Java, các thư viện này thường được đóng gói trong các tệp tin có đuôi.
Các lời gọi API trong bài toán của luận văn là các lời gọi phương thức trong mã nguồn Java. Giao diện lập trình ứng dụng thường được sử dụng để cải thiện năng suất trong quá trình phát triển các sản phẩm phần mềm. Các API thường sử dụng thông qua các nguồn bên thứ ba hoặc từ chính nền tảng đang phát triển. Khi khảo sát mã nguồn của 1000 dự án Java chất lượng cao và được xếp hạng cao nhất trên GitHub cho thấy rằng hơn một nửa lệnh gọi phương thức (52,3%) là từ các thư viện của bên thứ ba.
Kết quả này cho thấy tầm quan trọng của việc sử dụng API một cách cẩn thận. Tuy nhiên, phải mất rất nhiều công sức để lập trình viên có thể làm quen với tất cả các API trong các thư viện lớn và sử dụng chúng một cách chính xác trong các chương trình. Thật vậy, để hoàn thành chương trình đang phát triển với các API phù hợp, các nhà phát triển cần nghiên cứu kỹ cách sử dụng API từ các tài liệu và ví dụ minh hoạ được cung cấp trong các mã nguồn có sẵn tương ứng. Hơn nữa, với các thư viện mới và không quen thuộc, các nhà phát triển thường cần tìm hiểu xem các thư viện đó có chứa bất kỳ API nào có thể hỗ trợ các tác vụ đang phát triển hay không.
Với vấn đề này, ý tưởng của luận văn cho thấy việc đề xuất 1 gợi ý API tự động là vô cùng cần thiết khi hỗ trợ các nhà phát triển sử dụng các thư viện của bên thứ ba một cách hiệu quả. Gợi ý mã nguồn tự động, đặc biệt là đề xuất API gần đây đã trở thành một bài toán phổ biến trong các nghiên cứu học thuật và ứng dụng thực tiễn. Chẳng hạn, trong môi trường phát triển tích hợp (Integrated Development Environment - IDE), gợi ý mã nguồn là tính năng quan trọng bắt buộc phải có. Tính năng này dự kiến sẽ giảm thời gian phát triển mã nguồn bằng cách cung cấp các đề xuất các phần mã nguồn tiềm năng như tên biến, hàm,.
Tuy nhiên, các đề xuất do các IDE hiện tại tạo ra chủ yếu dựa trên khả năng phù hợp về kiểu và khả năng truy cập của các biến và lớp. Ví dụ, để gợi ý vế phải của một kiểu chuỗi (String), IDE có thể gợi ý các biến có kiểu là String và sắp xếp theo thứ tự bảng chữ cái. Do đó, những gợi ý này thường bị hạn chế và thể xử lý trong các trường hợp phức tạp. Lập trình viên đôi khi lại gặp khó khăn vì chính những gợi ý này khi phải mất công sức lựa chọn trong lượng lớn gợi ý mà IDE cung cấp.
Vì vậy, chúng ta cần một giải pháp để đưa ra các gợi ý hiệu quả bằng cách sắp xếp chúng một cách hợp lý và thu gọn lại các gợi ý không hữu ích. Các nghiên cứu gần đây về gợi ý mã nguồn [1–4] đã đạt được những kết quả đầy hứa hẹn. Những nghiên cứu này khai thác các thuộc tính của chương trình và ngữ cảnh trong các mã nguồn khác nhau để đề xuất các loại biểu thức khác nhau. Chẳng hạn, Liu và cộng sự [3] đã đề xuất một giải pháp sử dụng mô hình ngôn ngữ mạng nơ-ron để tạo đề xuất cho biến số, từ khóa, dấu câu, v.
Aroma [4] đề xuất mã bằng cách so sánh đoạn mã nguồn đang phát triển với các mã nguồn trong kho dữ liệu lớn, sau đó tận dụng các mã tương tự để tạo đề xuất. Ngoài ra, nghiên cứu AutoSC [2] kết hợp phân tích chương trình và mô hình ngôn ngữ thống kê để hoàn thành các câu lệnh chưa hoàn thiện. Bên cạnh đó, một số nghiên cứu đặc biệt tập trung vào việc đề xuất một lời gọi API/hàm ứng với ngữ cảnh đang được soạn thảo [5–9]. Chẳng hạn, Xie và cộng sự [6] đã đề xuất phương pháp gợi ý API bằng cách khai thác các mẫu sử dụng API trong một cơ sở dữ liệu lớn.
Họ xây dựng các biểu đồ phụ thuộc giữa API và ngữ cảnh của mã nguồn, sử dụng kết hợp các yếu tố tương đồng giữa chúng để khai thác các mẫu sử dụng API. Ngoài ra, Niu và cộng sự [7] cũng nghiên cứu phương pháp gợi ý API bằng cách biểu thị mã nguồn dưới dạng một mạng liên kết các cách sử dụng của từng đối tượng, là một tập hợp các lệnh gọi phương thức được gọi trên một lớp API duy nhất. Phương pháp gợi ý 2 API được Gao và cộng sự [8] tập trung vào mảng phát triển các ứng dụng Android bằng cách khai thác tài nguyên dữ liệu trong các cửa hàng ứng dụng như Google Play Store. Còn với nghiên cứu được đánh giá tốt nhất, APIRecX [5], sử dụng mô hình học máy mạnh là GPT để đề xuất các API chính xác.
Mặc dù các phương pháp hiện tại đề xuất API một cách hiệu quả cho thư viện bên thứ ba tiêu chuẩn và phổ biến trong cộng đồng lập trình viên, nhưng hiệu suất của chúng giảm đáng kể khi áp dụng với các loại API do người dùng tự xây dựng hoặc API nội bộ chưa được công bố mã nguồn trước đó [10].1: Ví dụ về gợi ý API trên IntelliJ IDEA Trên Hình.1 đưa ra một ví dụ minh hoạ việc gợi ý các API của đối tượng Java trên IntelliJ IDEA. Có thể thấy trên hình, IDE đưa ra một danh sách các gợi ý là các lời gọi API và cho người dùng chọn. Các IDE thường gợi ý ngay sau khi người dùng dừng lại trong lúc gõ hoặc sử dụng một số phím tắt như Ctrl + Space. Đây cũng là tính năng có sẵn trong các công cụ phát triển mã nguồn giúp người dùng lựa chọn một danh sách các gợi ý có sẵn.
Luận văn này đề xuất một phương pháp tiếp cận mới và hiệu quả cho đề xuất API, M F LUTE. Mục tiêu của phương pháp nghiên cứu sẽ đề xuất các API bằng cách kết hợp các kỹ thuật phân tích chương trình và mô hình ngôn ngữ thống kê. Cụ thể, MFLUTE tiến 3 hành phân tích đoạn mã nguồn còn đang viết dở (ngữ cảnh) để tạo các biểu thức ứng viên dựa trên đặc tả của ngôn ngữ lập trình. Các ứng viên là các lệnh gọi API được tạo sẽ đáp ứng các quy tắc cú pháp và ngữ nghĩa trong đặc tả Java.
Về mặt ngữ nghĩa, phương pháp này sẽ xem xét đến thông tin về kiểu dữ liệu và khả năng truy cập của các thành phần trong mã nguồn của toàn chương trình. Các quy tắc đặc tả ngôn ngữ lập trình sẽ được áp dụng cho việc đánh giá các gợi ý về mặt cú pháp. Một mô hình ngôn ngữ sẽ chịu trách nhiệm dự đoán xác suất về khả năng gọi phương thức API tương ứng với ngữ cảnh của chúng. Hiệu quả của phương pháp kết hợp các kỹ thuật này cũng đã được chứng minh trong các nghiên cứu trước đây về bài toán gợi ý mã nguồn tự động nói chung khác [2, 11].
Những nghiên cứu này đã chỉ ra rằng việc kết hợp các kỹ thuật phân tích chương trình và mô hình ngôn ngữ có thể tạo ra các mã nguồn gợi ý chính xác và đa dạng hơn so với việc chỉ sử dụng một trong hai kỹ thuật. Điều này cho thấy rằng phương pháp đề xuất trong luận văn này có thể áp dụng được cho nhiều bài toán liên quan đến gợi ý mã nguồn hiện tại. Bài toán cụ thể mà luận văn này cần giải quyết là đề xuất các lời gọi API cho một đoạn mã nguồn Java chưa hoàn thiện xong. Đầu vào của bài toán là một đoạn mã nguồn Java và vị trí con trỏ tại nơi cần gợi ý lời gọi API.
Đầu ra của bài toán là một danh sách các lời gọi API phù hợp với ngữ cảnh của đoạn mã nguồn. Để đầu ra được phù hợp, chúng ta cần thỏa mãn các điều kiện tiên quyết sau: • Các gợi ý là các lời gọi API hay lời gọi phương thức trong Java, • Các lời gọi API được gợi ý phải tuân theo cú pháp và ngữ nghĩa của ngôn ngữ lập trình Java, không phải là các lời gọi sai kiểu, sai số lượng tham số, sai tên phương thức, v.v và khiến chương trình xảy ra lỗi khi thực thi, • Danh sách đầu ra phải được sắp xếp theo thứ tự giảm dần của xác suất xuất hiện của các lời gọi API trong ngữ cảnh của đoạn mã nguồn. Các lời gọi API có xác suất cao hơn sẽ được ưu tiên hiển thị trước. Đối tượng được phân tích cụ thể trong luận văn này nhắm đến ngôn ngữ Java để phân tích các đặc thù ngôn ngữ này trong các trường hợp cụ thể và xây dựng các công cụ tương ứng.
Tuy nhiên, phương pháp này mang tính tổng quát có thể được áp dụng cho nhiều ngôn ngữ hướng đối tượng và ngôn ngữ dạng khác. 4 Kết quả nghiên cứu của luận văn này sẽ cần đáp ứng được các điều kiện đầu ra trên đây. Bên cạnh đó, phương pháp trong luận văn phải được đánh giá và so sánh với các phương pháp hiện có trên các tiêu chí như độ chính xác, thời gian thực hiện, khả năng áp dụng vào các công cụ thực tế, v. Từ đó sẽ đánh giá được các giá trị đóng góp và tính khả thi khi triển khai của luận văn.
Phần còn lại của luận văn được trình bày với cấu trúc như sau: Chương 2 sẽ liệt kê các kiến thức cơ sở liên quan được áp dụng trong quá trình xây dựng phương pháp. Chương này cũng bao gồm nội dung các công cụ phân tích mã nguồn và xây dựng mô hình ngôn ngữ. Phương pháp nghiên cứu của luận văn được mô tả chi tiết trong Chương 3. Tiếp theo, Chương 4 trình bày cách thực nghiệm để đánh giá độ hiệu quả của phương pháp.
Nội dung đánh giá bao gồm thực nghiệm so sánh với nghiên cứu được đánh giá tốt nhất và tổng quát trên một bộ dữ liệu lớn. Sau đó một số nghiên cứu liên quan tới bài toán sẽ được trình bày qua, đây là những nghiên cứu đem lại nhiều ý tưởng có thể áp dụng được một cách hiệu quả.