All Products
Search
Document Center

AI Coding Assistant Lingma:Maintaining legacy code

Last Updated:Apr 02, 2025

This topic describes the concept and classifications of legacy code, and provides strategies for different types of legacy code. In addition, this topic focuses on how Coding Assistant can support you in maintaining legacy code.

Legacy code

  • Code related to outdated technologies:

    • Code related to operating systems or software libraries that are no longer supported.

    • Code that relies on obsolete technology stacks or programming languages.

  • Code that is reserved for compatibility with legacy features:

    • Code segments that are reserved for compatibility with older versions of features in modern software.

    • Code that has to be reserved for backward compatibility.

  • Code that has no corresponding documentation and is not maintained:

    • Old code that has no corresponding documentation.

    • Code that lacks modern development practices such as unit tests and code reviews.

Solutions of legacy code

You can use one of the following strategies to address legacy code issues:

Strategy

Pros and cons

Rewrite code

Costs are high and the existing system can continue to run as expected, which results in code risks.

Refactor code

Supplement unit tests

Unit tests are used to identify issues in code and provide quality assurance for possible code changes.

The preceding table shows that supplementing unit tests is an effective method to solve legacy code issues. However, the following challenges still exist with this method:

  • A large amount of legacy code lacks unit tests, and test costs are very high due to the complex dependencies between code.

  • Specific metrics are not clear to define an adequate unit test.

  • The code that requires unit tests is not clearly identified.

Common mistakes in unit tests

  • False unit tests that lack assertions: Developers may call functions without assertions to improve code coverage, which results in many invalid unit tests.

  • Unit tests that are considered as white-box tests: Some viewpoints classify unit tests as white-box tests. However, unit tests are actually black-box tests specific to function signatures.

  • Unit tests that rely on actual environments: The main factors that hamper unit tests include laziness and environment-dependent configurations. If you do not use Stub or Mock to remove the dependence on external environments such as IP addresses or databases, unit tests cannot meet the FIRST principle (fast, independent, repeatable, self-validating, and timely).

Selectively perform unit tests

In addition to benefits, unit tests generate costs. If you analyze legacy code from a benefit and cost perspective, you can supplement unit tests for legacy code. This means that you can selectively perform unit tests. How do you distinguish costs and benefits?

Cost-benefit quadrant classification of unit tests for legacy code

Unit tests specific to legacy code can be categorized in quadrants based on their cost and benefits. The following figure shows the classification criteria and quadrants of unit tests.

组 1@1x (4)

Classification criteria

  • X-axis (Cost): Higher code dependency causes greater test cost.

  • Y-axis (Benefit): Higher code complexity causes greater quality gain.

Four quadrants

Code classification

Characteristics

Description

Benefits

Costs

Algorithms code

High cyclomatic complexity and fan-In

It contains many conditional judgment and loop statements and depends on a small number of code, but is relied on by many code.

High

Low

Trivial code

Trivial code

Low cyclomatic complexity and high fan-In

It uses simple logic and contains only one or two lines of code.

Low

Low

Coordinators code

Low cyclomatic complexity and high fan-In

It is at the upper layer of the calling relationship and reflects specific business scenarios by calling other code.

Low

High

Overcomplicated code

High cyclomatic complexity and fan-In

It uses complex logic, has multiple dependencies, contains many functions and parameters. It is typical code smell.

High

High

Understanding of cyclomatic complexity and dependencies

  • Cyclomatic complexity: the number of logical branches in the code.

  • Fan-in: the number of parent modules that directly call the module. A large fan-in indicates a high degree of module reuse.

  • Fan-out: the number of modules that a module directly calls. A large fan-out indicates that the module depends on many modules.

Strategies for different types of code

The following strategies apply to legacy code based on the preceding analysis:

  • For algorithms code, you can generate unit testing.

  • For coordinators code, you can perform API testing.

  • For overcomplicated code, you can seek the right opportunity to refactor code.

  • For trivial code, you do not need to process code.

组 1@1x (3)

Use Coding Assistant to process legacy code

1. Understand a project

When you maintain the legacy code of a project, you can use the @workspace feature to understand the purpose of the entire project and the modules involved in the project.

整屏示例@1x (16)

2. Process different types of code

Generate unit tests for algorithms code

Select the sections for which you want to generate code based on production code. During the generation, you can focus on dependency information such as the required framework and Mock. You can append relevant information after a unit test command is generated. For example, /generate unit testingCppUTest.

1722996288466-1c71b5fe-0b01-4332-bae2-9cbc87583aef

In general, the number of unit test cases generated from existing code is usually limited. If you have specific requirements for the number of test scenarios and use cases of unit tests, you can generate more unit tests by continuing test functions in a newly generated unit test file. During the continuation, Coding Assistant follows the existing use cases as much as possible and uses them as a reference for context.

1723362748120-1844d330-a97d-48bd-8315-bade66ecc5a7

Perform API testing on coordinators code

Unit testing is not an ideal solution for coordinators code, and test costs significantly increase due to an excessive number of dependencies. We recommend that you perform API or feature testing on such code. However, developers often encounter issues when writing automated test cases. Therefore, you can use Coding Assistant to quickly master and understand the test framework.

1723368390993-3776f32e-a798-490c-af55-ec645cb81547

To write a use case, you can select the tested function of the use case and ask questions directly in the conversational window of Al Coding Assistant. For example, you can ask Al Coding Assistant about the test case that is generated for the following code based on Robot Framework. This way, you can develop the corresponding keywords.

Refactor overcomplicated code at the right time

For overcomplicated code, you can use the /generate optimization command of AI Coding Assistant to obtain optimization suggestions for the selected code. Code review and optimization provides optimization suggestions from multiple dimensions such as syntax issues, exception improvements, code cleanliness, security, and risks.

1723363565800-c454ba6f-59fb-40d2-bc2f-1e82d6bdfa3b

For the optimization of complex legacy code, we recommend that developers do not blindly make comprehensive optimization and refactoring. Changes to legacy code may pose significant risks. Therefore, developers should refactor and optimize code at the right time based on specific situations and follow the Boy Scout Rule. In this process, Coding Assistant also provides strong support for you.

Summary

The preceding content provides best practices to which you can refer when processing legacy code. To process legacy code effectively, you must dive deep into the complex structure of the code and trace every possible branch node in detail. In this process, in addition to identifying and fixing potential defects, you must complete all tasks within a limited time. To minimize the time required for processing legacy code, we recommend that developers prevent code corruption, make good use of tools, and follow good programming principles in the early writing stages.