Reconstruction method and corresponding reconstruction system, storage medium and program product
By establishing mapping standards and variable transformations in code refactoring, the refactoring process is automated, solving the problems of correctness and scalability in code refactoring, achieving efficient and accurate code refactoring, and improving the readability and maintainability of the program.
Patent Information
- Application Number
- CN202510732116.2
- Authority / Receiving Office
- CN · China
- Patent Type
- Applications(China)
- Current Assignee / Owner
- Priority Date
- 2024-06-04
- Filing Date
- 2025-06-03
- Publication Date
- 2025-12-05
AI Technical Summary
Existing technologies face challenges in correctness, expressiveness, and scalability during code refactoring, especially in large codebases where it is difficult to effectively propagate and automate multiple changes.
By establishing a mapping standard between the original program and the refactored program, and using the first and second mapping standards to perform variable transformation on the original program, automated refactoring is achieved. This includes traversing the program to identify statements involving the original variables and refactoring them into statements with the target variables. A static source code transformation method is used to reduce processing and computational overhead and improve refactoring efficiency.
It achieves reduced refactoring processing and computational overhead, improved refactoring efficiency, enhanced program readability and maintainability while maintaining program functionality, is applicable to various complex language structures and business logic, reduces human error, and is suitable for a wide range of refactoring scenarios.
Smart Images

Figure CN121070429A_ABST
Abstract
Description
[0001] Cross-reference to related applications
[0002] This application claims priority to U.S. Provisional Patent Application No. 63 / 655,832, filed June 4, 2024, the entire contents of which are incorporated herein by reference. Technical Field
[0003] This application relates to code refactoring, and in particular to a computer-implemented refactoring method, a corresponding refactoring system, a computer-readable storage medium, and a computer program product. Background Technology
[0004] Software development is an evolving process that involves adapting source code to changing user and business requirements (see [1];
[28] ; and
[63] ). For example, agile software development methodologies aim to respond quickly and flexibly to changing requirements (see [4];
[13] ; and
[59] ). However, immature user requirements specifications in the early stages can lead to frequent changes in data structures, which in turn require tedious and error-prone manual modifications in multiple locations throughout the program (see
[33] ;
[48] ; and
[49] ).
[0005] To make such changes more reliable, refactoring has become an important method for reorganizing source code while preserving program behavior (see references
[20] ;
[23] ;
[57] ;
[63] ;
[67] ; and
[71] ). Manual refactoring has been widely performed throughout the software development process (see references
[22] ;
[47] ;
[51] ; and
[70] ). To automate refactoring, many techniques have been proposed: some generalize code editing patterns from examples (see references
[12] ; [5]; [7]; and
[69] ), some recommend upgrades for deprecated API calls (see references
[19] ;
[21] ;
[38] ;
[45] ; and
[58] ), and some synthesize code using different data structures (see references
[54] ;
[55] ;
[60] ;
[76] ; and
[77] ). However, the applicability of these techniques is limited by the following challenges:
[0006] Challenge 1: Correctness. Refactoring tools typically need to modify existing code without introducing errors. It is crucial that these tools ensure the transformed program correctly maintains the same behavior as the original program.
[0007] Challenge 2: expressiveness. Given the diversity of software development tasks, developers often perform a variety of manual refactoring operations. To be effective, refactoring tools should automate a variety of commonly used refactoring operations.
[0008] Challenge 3: scalability. Refactoring tools are especially valuable when they can effectively propagate multiple changes across a large code base. These tools must be able to scale efficiently across different code sizes before they can be integrated into the development process.
[0009] Therefore, large-scale systematic refactoring remains challenging (see
[12] ;
[26] ;
[34] ; and
[53] ). SUMMARY
[0010] The present application aims to provide a solution for code refactoring to address or alleviate at least some of the above-mentioned problems in the prior art.
[0011] In a first aspect, the present application provides a computer-implemented refactoring method for refactoring an original program to obtain a refactored program that preserves the functionality of the original program, the original program being based on original variables, the refactored program being based on target variables different from the original variables, the refactoring method comprising:
[0012] receiving the original program, a first mapping specification for converting the original variables or representations based on the original variables to corresponding representations using the target variables, and a second mapping specification for converting the target variables or representations based on the target variables to corresponding representations using the original variables;
[0013] traversing the original program to perform refactoring operations on at least some original statements of the original program based on the first and second mapping specifications to obtain a refactored program, comprising:
[0014] traversing the original program to identify original statements of the original program that involve the original variables;
[0015] for each original statement involving the original variables, performing variable conversion on it using the first and second mapping specifications to refactor it to a corresponding refactored statement involving only the target variables.
[0016] In a second aspect, the present application provides a refactoring system comprising a processor configured to execute computer instructions to cause the refactoring method of the first aspect described above to be performed.
[0017] In a third aspect, the present application provides a computer device comprising a memory and a processor, wherein the memory has stored thereon computer instructions which, when executed by the processor, cause the reconstruction method of the first aspect described above to be performed.
[0018] In a fourth aspect, the present application provides a non-transitory computer readable storage medium having stored thereon computer instructions which, when executed by a processor, cause the reconstruction method of the first aspect described above to be performed.
[0019] With the scheme of the present application, it is advantageous to reduce the processing and computing overhead required for reconstruction, improve the reconstruction efficiency, reduce the requirement for computer hardware, in addition, it is advantageous to provide flexibility for expansion, and create conditions for obtaining a structured, i.e. correct, reconstructed program. BRIEF DESCRIPTION OF DRAWINGS
[0020] Non-limiting and non-exhaustive embodiments of the present application are described with reference to the following drawings, by way of example only, in which:
[0021] Figure 1A The original class is illustrated to use variables x, y to store Cartesian coordinates (original program);
[0022] Figure 1B The target class is illustrated to use variables r, v to store polar coordinates (reconstructed program);
[0023] Figure 1C The original method body is illustrated to calculate the area of a triangle with A, B, C as vertices using Cartesian coordinates;
[0024] Figure 2 The process of LOID deriving the expression to be assigned to the target variable AB.r is illustrated;
[0025] Figure 3 The reconstructed method body using polar coordinates generated by LOID is illustrated;
[0026] Figure 4A A potential implementation of rotate using Cartesian coordinates is illustrated;
[0027] Figure 4B A potential implementation of rotate using polar coordinates is illustrated;
[0028] Figure 5 The abstract syntax of the example core language is illustrated;
[0029] Figure 6 The operational semantics of the example core language is illustrated;
[0030] Figures 7A-7D The example data structure and conversion function are illustrated;
[0031] Figure 8 The rules for LOID to propagate changes to the rest of the program are illustrated;
[0032] Figure 9A and Figure 9B The original program and the refactored program generated by LOID are illustrated, respectively;
[0033] Figure 10 The correspondence between the program states of the original program in Figure 9A and the refactored program in Figure 9B are illustrated;
[0034] Figure 11 The state transitions in the equivalent programs are illustrated;
[0035] Figures 12A-12B The diagrams of the variables in Example 4.2 and Example 4.3 are illustrated;
[0036] Figures 13A-13B The forward and backward conversion functions of the classes in Example 4.3 are illustrated, respectively;
[0037] Figures 14A-14B The execution time of LOID for the benchmark test is illustrated. DETAILED DESCRIPTION
[0038] So that the above and other features and advantages of the present application can be more fully understood, a detailed description of certain embodiments of the application will now be described with reference to the accompanying drawings. The drawings are not to scale, and are provided merely to illustrate certain embodiments of the application. For purposes of clarity and simplicity, detailed explanations of known functions and constructions of devices, apparatuses and / or equipment described herein will be omitted when such explanations would obscure the subject matter of the present application. It is to be understood that the specific embodiments presented herein are illustrative only and not restrictive in nature.
[0039] The features described herein can be embodied in different forms, and should not be construed as limited to the embodiments described herein. Rather, the embodiments described herein are provided merely as examples so as to illustrate a few of the many possible ways of implementing the devices and / or systems described herein, which will be apparent to those having skill in the art upon reading the disclosure presented herein.
[0040] As used herein, the term "and / or" includes any one of the associated listed items, as well as any combination of any two or more of the associated listed items.
[0041] Although terms such as "first", "second", and "third" can be used herein to describe various components, parts, sections, or elements, these components, parts, sections, or elements are not limited by these terms. Rather, these terms are only used to distinguish one component, part, section, or element from another component, part, section, or element. Therefore, a first component, part, section, or element mentioned herein can also be called a second component, part, section, or element without departing from the teachings of the present disclosure.
[0042] The terminology used herein is for the purpose of describing various embodiments only and is not intended to be limiting of the present disclosure. Unless otherwise defined, "a", "an" and "the" are intended to include both singular and plural forms. The terms "comprises", "comprising", "including" and "having" specify the presence of stated features, operations, components, elements, and / or combinations thereof, but do not preclude the presence or addition of one or more other features, operations, components, elements, and / or combinations thereof.
[0043] In the following description, numerous specific details are set forth to provide a thorough understanding of the present application. However, it will be apparent to one of ordinary skill in the art that the present application can be practiced without the specific details. In other instances, well-known steps or procedures are not described in detail in order not to obscure the present application.
[0044] The present disclosure proposes a new scheme for code refactoring. A refactoring method according to an embodiment of the present disclosure is used to refactor an original program to obtain a refactored program that preserves the functionality of the original program, the original program being based on original variables, the refactored program being based on target variables different from the original variables. The refactoring method is suitable for implementation by a computer, and can include a receiving step and a refactoring step.
[0045] In the receiving step, an original program, a first mapping specification for converting the original variables or representations based on the original variables into corresponding representations using the target variables, and a second mapping specification for converting the target variables or representations based on the target variables into corresponding representations using the original variables are received.
[0046] The original program can be a code segment including one or more statements, and can be written in a suitable language. In one embodiment, the original program is written using a programming language that supports object-oriented features and / or structured data types, such as but not limited to JavaScript, TypeScript, Java, C++, etc. The refactored program can be written in the same language as the original program.
[0047] The original program and the restructured program can be programs or codes for various possible applications, which can be various possible industrial or industry applications, such as but not limited to industrial or industry related process implementation, process control, information collection, information processing, etc. The original variables and the target variables can be technical variables, such as technical variables associated with various possible technical data or information. The technical variables can be, for example but not limited to, technical variables related to industrial or industry applications, associated with industrial or industry related technical data or information. In one embodiment, the original program and the restructured program are programs for image processing, such as image synthesis or image noise processing, and the variables involved are variables associated with image information. In another embodiment, the original program and the restructured program are programs for industrial process implementation, such as 3D printing, and the variables involved are technical variables related to industrial processes.
[0048] The original program and the restructured program use different sets of variables, meaning that the original program and the restructured program employ different data structures. Describing the data structure changes of the restructured program relative to the original program is the basis and premise of restructuring. The present application describes such data structure changes by means of the bidirectional mapping specification constituted by the first mapping specification and the second mapping specification, which can make the description of data structure changes more accurate compared to using input-output examples or natural language documentation, etc. to describe data structure changes, which is advantageous.
[0049] On the other hand, the first mapping specification and the second mapping specification can be a natural result of the restructuring design process, without increasing the workload. For example, a software developer can restructure an existing original program according to user requirements, and for this purpose, determine the target variables to be used in the restructured program, and determine the mapping specification between the target variables and the original variables used in the original program.
[0050] In the reconstructing step, the original program is traversed, and a reconstructing operation is performed on at least part of the original statements of the original program based on the first mapping specification and the second mapping specification to obtain a reconstructed program. The at least part of the original statements can include original statements of the original program that involve the original variable. In this case, the reconstructing step can include: traversing the original program to identify original statements of the original program that involve the original variable; and for each original statement involving the original variable, performing a reconstructing operation thereon by performing a variable transformation thereon using the first mapping specification and the second mapping specification to reconstruct it into a corresponding reconstructed statement involving only the target variable. Depending on the case, the at least part of the original statements can optionally include original statements of the original program that do not involve the original variable. For original statements of the original program that do not involve the original variable, the corresponding reconstructed statement obtained by performing a reconstructing operation thereon is the same as the original statement.
[0051] By configuring the first mapping specification and the second mapping specification as the basis for reconstruction, the reconstructed program can be made to retain the functionality of the original program.
[0052] The reconstructing method of the present application is based on static source code transformation, and only performs a reconstructing operation on original statements of the original program that involve a variable, leaving other locations of the original program unchanged, which is advantageous in reducing the processing and computing overhead required for reconstruction, improving the efficiency of reconstruction, and reducing the requirements on computer hardware. In addition, performing a reconstructing operation based on variable mapping helps to comprehensively identify and reconstruct statements of the original program that involve a variable, and can realize localized analysis of the reconstructed program fragment, while leaving the rest of the program unchanged. This mechanism is advantageous in providing flexibility for extension. With the solution of the present application, in the case of performing a reconstructing operation on original statements of the original program that involve a variable, it can be conveniently applied to a situation that can contain more complex language structures and business logic. Furthermore, by using the first mapping specification and the second mapping specification, it is helpful to provide a more accurate description of the data structure changes required for reconstruction, thereby creating conditions for obtaining a correctly reconstructed program, and eliminating the need for external proof assistants, verifiers or solvers.
[0053] In one embodiment, the original statement being refactored includes an original expression involving one or more original variables, and the refactoring method includes performing a refactoring operation on the original expression such that the original expression is refactored into a corresponding refactored expression in the refactored program. Performing a refactoring operation on the original expression can include performing a variable substitution operation on the original expression according to the first mapping rule, replacing each original variable in the original expression with an expression representing the associated target variable, to obtain the refactored expression. In one embodiment, the first mapping specification includes a first conversion function and the second mapping specification includes a second conversion function, the first conversion function being used to convert an original variable to an expression representing the associated target variable, and the second conversion function being used to map a target variable to an expression representing the associated original variable; in this case, performing a variable substitution operation on the original expression according to the first mapping rule can include performing a variable substitution operation on the original expression according to the first conversion function, replacing each original variable in the original expression with an expression representing the associated target variable, to obtain the refactored expression.
[0054] In one embodiment, the original statement being refactored includes an original assignment statement for assigning one or more original expressions to one or more original variables, the refactoring method includes performing a refactoring operation on the original assignment statement such that the original assignment statement is refactored into a corresponding refactored assignment statement in the refactored program, the refactored assignment statement being for assigning one or more target expressions to one or more target variables associated with the one or more original variables. Performing the refactoring operation on the original assignment statement can include determining the one or more target variables associated with the one or more original variables as target variables being assigned in the refactored assignment statement according to the first mapping specification and the one or more original variables being assigned in the original assignment statement; and determining a target expression being assigned to each target variable being assigned in the refactored assignment statement. Determining the target expression being assigned to each target variable being assigned in the refactored assignment statement can include, for each target variable being assigned, obtaining a first intermediate expression that converts the target variable being assigned into an expression in terms of associated original variables according to the second mapping specification; replacing each original variable in the first intermediate expression with a corresponding original expression being assigned to the original variable in the original assignment statement to obtain a second intermediate expression; and performing a variable substitution operation on the second intermediate expression according to the first mapping specification to replace each original variable in the second intermediate expression with an expression in terms of associated target variables to obtain the target expression. In one embodiment, the first mapping specification includes a first conversion function for converting an original variable into an expression in terms of associated target variables, and the second mapping specification includes a second conversion function for mapping a target variable into an expression in terms of associated original variables; in which case, determining the target expression being assigned to each target variable being assigned can include, for each target variable being assigned, obtaining a first intermediate expression that converts the target variable being assigned into an expression in terms of associated original variables according to the second conversion function; replacing each original variable in the first intermediate expression with a corresponding original expression being assigned to the original variable in the original assignment statement to obtain a second intermediate expression; and performing a variable substitution operation on the second intermediate expression according to the first conversion function to replace each original variable in the second intermediate expression with an expression in terms of associated target variables to obtain the target expression.
[0055] The variable substitution operation is further described below, e.g., using and expressions of the form as described above.
[0056] The second conversion function can be an inverse function of the first conversion function. In one embodiment, the original variables form a set of original variables V, the target variables form a set of target variables V', the first conversion function is Φ V → V', which can be abbreviated as Φ, and the second conversion function is Φ V→V → V, which can be abbreviated as Φ -1 .
[0057] In one embodiment, the original statement being reconstructed comprises an original sequential statement including at least two original statements to be executed in sequence, and the reconstructing method comprises: performing a reconstructing operation on the original sequential statement so that the original sequential statement is reconstructed into a corresponding reconstructed sequential statement in the reconstructed program, the reconstructed sequential statement including at least two reconstructed statements corresponding to the at least two original statements one by one. Performing the reconstructing operation on the original sequential statement can comprise: performing the reconstructing operation on the at least two original statements one by one in the order of their execution in the original sequential statement.
[0058] In one embodiment, the original statement being reconstructed comprises an original conditional statement including at least two original branch statements to be executed in sequence, at least one of the original branch statements including an original conditional expression, and the reconstructing method comprises: performing a reconstructing operation on the original conditional statement so that the original conditional statement is reconstructed into a corresponding reconstructed conditional statement in the reconstructed program, the reconstructed conditional statement including at least two reconstructed branch statements corresponding to the at least two original branch statements one by one. Performing the reconstructing operation on the original conditional statement can comprise: performing the reconstructing operation on the at least two original branch statements one by one in the order of their execution in the original conditional statement, wherein for each original branch statement including an original conditional expression, a reconstructing operation is performed on each original conditional expression included therein before the reconstructing operation is performed on the original branch statement.
[0059] In one embodiment, the original statement being refactored includes an original loop statement including an original condition expression indicating a loop condition and an original loop body to be executed when the original condition expression is satisfied, the original loop body including at least one original execution statement, the refactoring method including: performing a refactoring operation on the original loop statement such that the original loop statement is refactored into a corresponding refactored loop statement in the refactored program, the refactored loop statement including a target condition expression indicating a loop condition and a target loop body to be executed when the target condition expression is satisfied, the target loop body including at least one target execution statement corresponding one-to-one to the at least one original execution statement. Performing a refactoring operation on the original loop statement can include: performing a refactoring operation on the original condition expression first to obtain the target condition expression, and then performing a refactoring operation on the at least one original execution statement one-by-one.
[0060] In one embodiment, the first and second mapping specifications include a conversion function for a class such that multiple instance variables of the same class share the same conversion function. In this way, a conversion function can be specified only once for each class, eliminating potential redundant conversion functions while achieving the same effect as specifying a conversion function for each variable. Redundant conversion functions can occur when the same class has multiple instance variables sharing the same or similar conversion logic.
[0061] The refactoring method of the present application can include additional steps as needed. For example, the refactoring method according to one embodiment of the present application further includes parsing a received original program into an Abstract Syntax Tree (AST) by a parsing tool. At this time, the original program is represented in AST, and traversing the original program can include traversing the AST. For another example, the refactoring method according to one embodiment of the present application further includes simplifying the refactored program by a code simplification tool to enhance readability.
[0062] Hereinafter, the present application is described further.
[0063] 1.1 Scheme of the present application
[0064] The inventors aim to remedy the deficiencies of the prior art by creating an automated scheme for refactoring data structures. The scheme of the present application systematically propagates changes in data structures to the entire program, ensuring correct usage of new data structures. The scheme of the present application builds on the following key ideas:
[0065] - Idea 1: Establish semantic connections between data structures. Rather than relying on extensive analysis of individual programs, the approach of the present invention focuses on analyzing connections between two programs. This connection is established by allowing the user to specify the refactoring operation they desire (by describing how the original data structure and the target data structure are related). This form of specification is a natural result of the software design process (see
[25] ;
[54] ;
[55] ;
[60] ; and
[77] ) and is more precise than alternative specification forms such as input-output examples or natural language documents in describing complex data structure changes.
[0066] - Idea 2: Synchronize semantics across different variable spaces. The refactoring approach of the present invention ensures consistency between the original program and the refactored program by synchronizing their read and write access to data structures. Specifically, two disjoint variable spaces are formalized for the original data structure and the target data structure, and the relationship between these two variable spaces is then exploited to construct the refactored program. When an expression in the original program is evaluated, the original expression is replaced with an equivalent projection in the target variable space. When a variable in the original program is written, the corresponding variable in the target variable space is modified accordingly to maintain the equality of the two program states.
[0067] - Idea 3: Decompose the refactoring problem for an entire program into manageable transformations within a local scope. The formalization is constructed as a set of core transformation rules, with extensions provided for high-level language structures. The core algorithm available and its soundness proof are based on a localized analysis of the program fragment being refactored, while the rest of the program remains unchanged. This conceptual separation provides great flexibility for extensions. It enables extensions to include more complex language structures and business logic without compromising the soundness results of the core algorithm. Thus, the approach of the present invention is applicable to a variety of practical benchmarks.
[0068] The inventors constructed an example refactoring system embodying the approach of an embodiment of the present invention, and named the refactoring system "LOID." The refactoring process was formalized for a core programming language, and a soundness guarantee was provided that the refactored program generated by LOID preserves the functionality of the original program as a new program.
[0069] 1.2 Main Advantages
[0070] LOID can bring many benefits, including:
[0071] - Reducing manual work in software development and migration. LOID enables developers to switch between various data representations as needed throughout the software life cycle, making it easier to adapt existing programs to different scenarios. Since LOID automatically identifies all locations that need to be modified and systematically generates refactored programs, it helps save valuable time that developers spend on repetitive labor.
[0072] - Enhancing readability and maintainability. Since LOID updates the computational code to match the latest data structure semantics, it only uses user-specified variables without generating excessive variables. This feature helps enhance the readability and maintainability of programs, making it easier for developers to maintain and develop more functionalities in the long run.
[0073] - Formal correctness guarantee. Starting from the valid specification of data structure transformations, LOID guarantees that the generated program preserves the functionality of the original program. This guarantee is expected to reduce software defects caused by human factors during the refactoring process. It also distinguishes itself from machine learning-based techniques (see [6];
[21] ; and
[45] ), which often lack soundness guarantees and are less suitable for developers who want to have full control and understanding of their code (Challenge 1).
[0074] - Applicable to a wide range of refactoring scenarios. LOID supports a much broader range of data structure refactoring operations than existing commercial Integrated Development Environments (IDEs) (see
[15] ;
[30] ;
[43] ; and
[44] ) provide (Challenge 2). Moreover, in experiments, LOID completes refactoring for thousands of abstract syntax tree nodes within a few seconds, making it suitable for integration into real-time code editing tools. This is a key advantage compared to existing techniques that rely on inductive program synthesis (see
[54] ;
[55] ; and
[77] ) (Challenge 3).
[0075] 2 Illustrative Example
[0076] An example is provided to illustrate how LOID facilitates automated refactoring. Consider an example program that serves as a library for computational geometry, which is adapted from a popular utility library (see
[68] ) by (1) simplifying its three-dimensional coordinates to two dimensions for ease of understanding, and (2) converting it to Python for brevity. See Section 5 for more details on the actual benchmarking. The original program initially uses variables x, y to store Cartesian coordinates ( Figure 1A ), and implements a method to calculate the area of a triangle ( Figure 1C). The user wants to refactor the program so that the refactored program uses polar coordinates for the variables r, v ( Figure 1B ), while still providing the same functionality as the original program. The goal is to change the underlying data structure so that it is easier to use the source code in the future, which is often a key step in software evolution to adapt to changing requirements.
[0077] The user specifies a mapping between the original data structure and the target data structure:
[0078] x = r cos v, y = r sin v, v = arctan2(y, x).
[0079] The LOID then derives how the rest of the program should be modified accordingly (Idea 1).
[0080] Automated refactoring. The focus is on explaining how the LOID automatically refactors the first statement in Figure 1C . The original statement assigns values to two variables AB.x and AB.y. According to the specification, these original variables can be expressed in terms of the target variables AB.r and AB.v. The LOID uses these two variables as the left side of the refactored assignment statement. Next, the LOID computes the right side, i.e., the expression that should be assigned to these two target variables.
[0081] Figure 2 The figure illustrates the process of how the LOID derives the expression to be assigned to the target variable AB.r. The left and right parts of the figure represent the original program and the refactored program, respectively. The top and bottom parts of the figure represent the same expression before and after the assignment statement, respectively. The double dashed lines between ① and ② and between ③ and ④ represent the equivalence between the original program and the refactored program. The solid arrow from ② to ③ represents the effect of the original assignment statement. The dashed arrow from ④ to ① represents the synthesized assignment statement in the refactored program. Refer to Figure 2 The focus is on how the LOID computes the expression to be assigned to AB.r. Conceptually, this expression is computed in two steps.
[0082] The first step is to inline the original assignment statement into the data structure specification. According to the specification of , the target variable AB.r can be expressed in terms of the original variables space as expression ② (see ①→② in Figure 2 ). Since the original statement assigns the expression (A.x - B.x) to the variable AB.x and the expression (A.y - B.y) to the variable AB.y, the LOID inlines these assignments into the specification (②→③) and obtains the new expression ③. This expression ③ represents the content of the target variable AB.r after the original assignment statement has been completed. However, this expression ③ still references the original variables x, y that represent Cartesian coordinates. Therefore, this expression ③ is not valid for the refactored program, because it must be expressed in terms of the target variablesFigure 1B The target data structure in
[0083] To make the inline expression valid for the refactored program, the second step is to migrate the expression ③ into the target variable space. Specifically, LOID replaces the Cartesian coordinates in this expression with polar coordinates by applying the data structure specification x = rcosv and y = rsinv. LOID replaces the original variables A.x, A.y, B.x, B.y by A.r*math.cos(A.V), A.r*math.sin(A.V), B.r*math.cos(B.V), and B.r*math.sin(B.V), respectively, in the expression ③→④ in Figure 2 . The resulting expression is shown in ④, which properly uses polar coordinates.
[0084] Conceptually, the steps ①→② and ③→④ compute the equivalent projections of the expression in different variable spaces. The steps ②→③ and the refactored assignment statement perform simultaneous modifications on the equivalent states from different variable spaces (Idea 2).
[0085] Recall that Figure 1C the first statement in Figure 3 requires simultaneous updates of the variables AB.r and AB.v in the refactored program. LOID computes the expression to be assigned to AB.v in a similar way as AB.r above. The resulting expression is math.atan2(A.r*math.sin(A.V)-B.r*sin(B.V), A.r*math.cos(A.V)-B.r*math.cos(B.V)). The refactored first statement performs simultaneous assignments on these two variables, as shown in the lines 1-5 of
[0086] Ready-made tools (see
[11] ;
[39] ; and
[78] ) can be directly applied to simplify the generated expressions and improve readability. For example, the right-hand side expression of AB.r in the first statement in Figure 3 lines 2-3 can be encoded as ((r1cosv1-r2cosv2) 2 +(r1sinv1-r2sinv2) 2 ) 0.5 and simplified to
[0087] LOID refactors the statements in the original program Figure 1C line by line to obtain the new program Figure 3 . The refactored program guarantees to preserve the functionality of the original program (Idea 3).
[0088] Advantages. Polar coordinates enable users to more easily implement additional functionality that benefits from the latest data representation. Figures 4A-4B One example functionality that is easier to implement after refactoring is the rotate method, which updates coordinates in a circular motion. The original program using Cartesian coordinates must perform a series of complex calculations to implement rotation Figure 4A ), but the refactored program using polar coordinates only requires an addition Figure 4B , an example functionality that is easier to implement after refactoring. This improvement is one example advantage of refactoring source code to use alternative data structures that can meet the changing needs of software. LOID aims to facilitate this process by providing automation and ensuring correctness.
[0089] 3 Core Formalization and Proofs
[0090] The refactoring process is formalized and a soundness proof of the algorithm in LOID is outlined. The algorithm generates a new program that uses the target data structure while preserving the functionality of the original program.
[0091] 3.1 Core Language
[0092] An example method according to the invention and related soundness proofs are introduced in a core imperative programming language that focuses on expressions and variable assignments. The core language aims to capture the computations and refactoring operations that occur in a variety of imperative programming languages.
[0093] Definition 3.1 (Syntax). Figure 5 The syntax of an example core language is presented.
[0094] The start symbol S represents a program in the core language. A program can be empty, a simple statement that performs n > 1 simultaneous variable assignments, or a complex statement composed of sequences, conditions, or loops. Each expression e E E can be a constant c C, a variable x X, or the result of a computational operation on sub-expressions. Can represent any side-effect-free operation with n > 0 operands, including general pure functions.
[0095] For convenience of representation, we will use and to represent x1,..., x n and e1,..., e n respectively. In this way, represents the set {x1,..., x n}, represents the assignment <x1,..., x n > <- <e1,..., e n >. Similarly, we will use denote
[0096] Definition 3.2 (variable substitution). denote the different variables occurring in an expression e∈E are replaced by the expressions
[0097] e[ ] = e
[0098]
[0099]
[0100] (y different from )
[0101]
[0102] where
[0103] Definition 3.3 (variable set). denote the set of variables occurring in an expression e∈E and a program s∈S, respectively.
[0104]
[0105] v(x) = {x}
[0106]
[0107] v(s1;s2) = v(s1)∪v(s2)
[0108] v(if e then s1 else s2 end) = v(e)∪v(s1)∪v(s2)
[0109] v(while e do s end) = v(e)∪v(s)
[0110] where c∈C, x, s, s1, s2∈S.
[0111] Proposition 3.4 (identity). For any expression e∈E and variable
[0112] Proof. The proof proceeds by induction on the derivation of e.
[0113] Case 3.4.1. e = c, where c∈C.
[0114] By Definition 3.2,
[0115]
[0116] Case 3.4.2. e = x i where i e [1, n].
[0117] Also by definition 3.2,
[0118]
[0119] Case 3.4.3. e = y, where y e X and y is different from
[0120] Again by definition 3.2,
[0121]
[0122] Case 3.4.4. where
[0123]
[0124]
[0125] Proposition 3.5 (Projection). For any expression e, and the variable
[0126]
[0127] Proof. The proof proceeds by induction on the derivation of e.
[0128] Case 3.5.1. e = c, where c e C.
[0129]
[0130] Case 3.5.2. e = x j where j e [1, n].
[0131] By definition 3.3, Thus
[0132]
[0133]
[0134] Case 3.5.3. e = y, where y e X and y is different from
[0135] In this case, there is Thus
[0136]
[0137] Case 3.5.4. where
[0138] For any v(e j ) = v(e) n v(e j ), since by definition 3.3,
[0139]
[0140] Proposition 3.6 (Distributive law for variable substitution). For any expression e, and variables if or then
[0141]
[0142] Proof. The proof proceeds by induction on the derivation of e.
[0143] Case 3.6.1. e = c, where c e C.
[0144]
[0145] Case 3.6.2. e = x i , where i e [1, n]
[0146]
[0147]
[0148] Case 3.6.3. e = z, where z is different from both and .
[0149]
[0150] Case 3.6.4. where
[0151] For any by definition 3.3, we have Thus Thus, e i also satisfies the requirements of the proposition as follows
[0152]
[0153]
[0154] Definition 3.7 (Program state). A state σ∈∑=X→C maps variables to values.
[0155] For ease of notation, ∑ is extended from X→C to E→C using the following rules so that states can also interpret the result value of expressions:
[0156] σ(c) = c,
[0157] where σ∈∑ and c∈C,
[0158] Definition 3.8 (Variable assignment). denotes the different variables that will occur in a state σ∈∑
[0159]
[0160] where y∈X(y is different from x) and i∈[1, n].
[0161] Proposition 3.9 (Associativity of variable assignment). For any state σ∈∑, the variables that are all different from each other, and the constants
[0162]
[0163] Proof. The proof proceeds by case analysis on the derivation of x′ to show that
[0164]
[0165] Since states are functions defined on X and produce the same output for every input in their domain, two states that satisfy this condition should be considered the same.
[0166] Case 3.9.1. x′ = x i where i∈[1, n].
[0167] By Definition 3.8,
[0168]
[0169] Case 3.9.2. x′ = y j where j∈[1, m].
[0170] Again by Definition 3.8,
[0171]
[0172] Case 3.9.3.x′=z, where z and and They are all different.
[0173] Again, according to definition 3.8,
[0174]
[0175] Definition 3.10 (Semantics). Figure 6 It demonstrates the operational semantics of the core language of the example.
[0176] This means that executing the program s∈S on the state σ∈∑ will generate another state a′∈∑.
[0177] Proposition 3.11 (The bridge between variable substitution and assignment). For any state σ∈Σ, the expression e, and variables ( They are different.
[0178]
[0179] Right now,
[0180]
[0181] Proof. The proof is an induction of the derivation of e.
[0182] Case 3.11.1.e=c, where c∈C.
[0183]
[0184]
[0185] Case 3.11.2. e = x i , where i∈[1,n].
[0186]
[0187] Case 3.11.3.e=y, where y∈X and y is the same as... different.
[0188]
[0189] Situation 3.11.4. in
[0190]
[0191] 3.2 Transformations used for reconstruction
[0192] Next, the transformation function and its inverse are defined. Conceptually, the transformation function specifies how variables in the original program are changed to the target variable set. LoID employs a pair of inverse transformation functions and uses them to automatically compute a new program that uses the target variable set but preserves the functionality of the original program.
[0193] Definition 3.12 (Transformation Function). Given two variable sets V, Transformation Function Φ V→V′ maps each x e V to an expression whose variables are in V', i.e.
[0194] For ease of expression, the domain of Φ V→V′ is extended from V to
[0195]
[0196] where
[0197] Definition 3.13 (Variable Space). Given a transformation function Φ V→V′ , V is the original variable space and V' is the target variable space.
[0198] Definition 3.14 (Dependency of a Variable). Given a transformation function Φ V→V′ and a variable x e V, define
[0199] D V→V′ (x) = v(Φ V→V′ (x))
[0200] as the dependency of x with respect to Φ V→V′
[0201] Example 3.15. Figure 7A illustrates classes adapted from SWT (see
[16] ); Figure 7B illustrates classes adapted from JMIST (see
[35] ); Figure 7C illustrates a forward transformation function; Figure 7D illustrates an inverse transformation function. Consider the original class in Figure 7A and the target class in Figure 7B The original variable set is V = {x, y'width, height}. The target variable set is V' = {minimumX, maximumX, minimumY, maximumY}. Figure 7C exhibits a transformation function that maps V to V'. For example, the equation Φ V→V′ (width) = maximumX - minimumX represents the mapping of the original variable width in Figure 7A to the expression (maximumX - minimumX) that contains only the target variables that occur in Figure 7B The dependency of the variable width is D V→V′ (width) = {maximumX, minimumX}.
[0202] Consider the expression e = width * height in a program built using original classes. To apply the transformation function defined in Figure 7C to e, one only needs to replace the variables in the intersection of V and v(e) according to Definition 3.12 and Theorem 3.5. According to Definition 3.3, v(e) = {width, height}, so V ∩ v(e) = {width, height}. Thus,
[0203]
[0204] Lemma 3.16. For any transformation function Φ V→V′ and a constant c e C,
[0205] Φ V→V′ (c) = c.
[0206] Proof. According to Definition 3.3,
[0207]
[0208] Lemma 3.17. For any transformation function Φ V→V′ , an operand and an expression
[0209]
[0210] Proof. According to the condition we know According to Definition 3.3, we have
[0211]
[0212] Proposition 3.18 (about substitution transformation). For any transformation function Φ V→V′ , a variable an expression and an expression e e E, such that
[0213]
[0214] Proof. By condition know Also by condition have By definition 3.3,
[0215]
[0216] Thus,
[0217]
[0218] Definition 3.19 (inverse transformation function). The inverse transformation function Φ V→V′ of a transformation function Φ V′→V is always satisfied:
[0219]
[0220] For clarity, when both Φ V→V′ and Φ V′→V are discussed as a pair, Φ V→V′ is called the forward transformation function and Φ V′→V is called the inverse transformation function.
[0221] Example 3.20. For V = {x, y}, V' = {x', y'}, and the following Φ V→V′ and Φ ′→V :
[0222] Φ V→V′ (x) = x' + y', Φ V′→V (x') = x + y,
[0223] Φ V→V′ (y) = x' - y', Φ V′ w V (y') = x - y.
[0224] The transformation function Φ V′→V is not the inverse of Φ V→V′ .
[0225] Proof. The left side of the equality in Definition 3.19 is
[0226] σ(Φ V′→V (Φ V→V′ (x)))
[0227] = σ(Φ V′→V (x' + y'))
[0228] = σ(Φ V′→V (x') + Φ V′→V (y'))
[0229] = σ((x + y) + (x - y))
[0230] = (σ(x) + σ(y)) + (σ(x) - σ(y))
[0231] = 2 x σ(x)
[0232] While the right side is σ(x). However, when σ(x) ≠ 0, 2 x σ(x) ≠ σ(x).
[0233] Example 3.21. For V = {x, y}, V' = {x', y'}, and the following Φ V→V′ and Φ V′→V :
[0234] Φ V→V′ (x) = x' + y', Φ V′→V (x') = (x + y) ÷ 2,
[0235] Φ V→V′ (y) = x' - y', Φ V′→V (y') = (x - y) ÷ 2.
[0236] The transformation function Φ V′→V is the inverse function of Φ V→V′ .
[0237] Proof. It is easy to prove that the equality in Definition 3.19 holds for all variables in V:
[0238]
[0239] Similarly, it can also be proved that Φ V→V′ is the inverse function of Φ V′→V .
[0240]
[0241] Proposition 3.22. Given a pair of forward and backward transformation functions Φ V→V′ and Φ V′→V , σ(Φ V′→V (Φ V→V′ (e))) = σ(e).
[0242] Proof. For convenience of notation, let Φ V′→V and Φ V′→V be denoted as Φ and Φ -1 , respectively.
[0243]
[0244] Intuitively, continuously applying a transformation function and its inverse function to an expression results in another expression that is equivalent to the original expression.
[0245] Inference 3.23. For any pair of forward and backward transformation functions Φ V→V′ and Φ V′→V , a program state σ ∈ ∑, an expression e ∈ E, and a distinct variable
[0246]
[0247] Proof. For convenience of notation, let Φ V→V′ and Φ V′→V be denoted by Φ and Φ -1 , respectively.
[0248]
[0249] 3.3 Automated refactoring algorithm
[0250] The core algorithm for automated refactoring in LOID is introduced next.
[0251] Definition 3.24 (procedure). Given two sets of variables V, and two transformation functions Φ V→V′ and Φ V′→V , define the following notation for specifying how to propagate the initial changes introduced in the data structure definition to the rest of the program:
[0252] Rule
[0253]
[0254] Specifying how to propagate the data structure transformation (Φ V→V′ and its inverse Φ V′→V ) to expressions. An expression e ∈ E, where is to be replaced by another expression e' ∈ E, where
[0255] Rule
[0256]
[0257] Specifying how to propagate the data structure transformation (Φ V→V′ and its inverse Φ V′→V ) to programs. A program s ∈ S, where is to be replaced by another program s' ∈ S, where
[0258] For simplicity, use Φ as a shorthand for the forward transformation Φ V→V′ and Φ -1 as a shorthand for the backward transformation Φ V′→V .
[0259] Definition 3.25 (Automatic Refactoring Algorithm). Given an original program s∈S, a forward transformation function Φ, and a backward transformation function Φ -1 LOID based on Figure 8 The rule generation program s′∈S.
[0260] The expression equations show how LOID replaces the expression using a forward transformation function according to definition 3.12. The empty equations show that empty statements remain unchanged. The assignment equations show how LOID replaces statements that assign values to variables. Specifically, the new statement s replaces the target program variable y according to definition 3.14. j Lists ∈V′ are assigned values simultaneously. j The right side of the assignment is a new expression e′ j In order to construct e′ j LOID first applies a reverse transformation function to y j Transform back to the original variable space V to produce Φ -1 (y j Next, LOID will use Φ -1 (y j All primitive variables appearing in ) Replace with To evaluate the raw assignment statement The effect, thus producing Finally, LOID recursively reconstructs the expression using expression equality. The result expression e′ j It is valid in the target variable space V′. Sequence equality indicates that LOID replaces a sequence of statements by recursively replacing one statement at a time. Conditional equality indicates that LOID replaces conditional statements by first replacing the conditional expression with an expression equality, and then recursively replacing both branches. Loop equality indicates that LOID replaces loops by first replacing the loop condition, and then recursively replacing the loop body.
[0261] Theorem 3.26 (Time Complexity). The time complexity of the algorithm is O(|s|·|V′|), where |s| represents the size of the AST of the original program s, and |V′| represents the size of the target variable space V′.
[0262] Reason. Expression equation generation. Variable substitution involves a time complexity of O(|e|), where |e| represents the size of the AST of expression e, as it involves traversing the AST to substitute the relevant variables. The time complexity of an empty equality is O(1) because an empty statement remains unchanged. Assignment equality is the main contributor to execution time. We will first discuss the time complexity of computing the lvalue. Computing has... of involves a time complexity of O(|V'| · n) as it involves iterating over all target variables y e V' and checking whether any of the n original variables depends on each y. Given that n = O(|s|), the time complexity of computing the left-hand side is within O(|s| · |V'|).
[0263] Next, for the right-hand side, the computation of has a time complexity of — given that |Φ(x)| is an amortized constant. Note that |s'| = O(|s| · |V'|) as the transformed statement is no larger than the case where a single assignment statement is transformed into a simultaneous assignment of all variables in |V'|. Thus, the complexity of computing the left-hand side and right-hand side of the assignment rule is O(|s| · |V'| + |s'|) = O(|s| · |V'|). The sequential, conditional, and loop equations only propagate the transformation to the child AST nodes, so these rules scale linearly with respect to |s|. Thus, Figure 8 the overall time complexity of
[0264] Example 3.27. Figure 9A shows a program p consisting of two statements. From the transformation function Φ Figure 7C and Figure 7D specified in V→V′ Φ V′→V beginning, the LOID infers the dependencies of the target variables using Definition 3.14:
[0265] D -1 (minimumX) = {x}, D -1 (maximumX) = {x, width},
[0266] D -1 (minimumY) = {y}, D -1 (maximumY) = {y, height}.
[0267] Then, the LOID applies the algorithm in Definition 3.25 to reconstruct the two statements one by one through sequential equations. The LOID first applies the assignment equation to the first statement <x><5>. Here, is X, is 5, where n = 1. From the target variable set in Figure 7B and the dependencies computed above, LOID infers where m = 2. Without loss of generality, let y1 = minimum X and y2 = maximum X. To compute e' j , LOID applies the expression e' = maximum X - minimum X > 5, and wraps
[0268]
[0269] Thus, the reconstructed statement is s' = (minimum X, maximum X > <-<5, 5 + maximum X - minimum X>. Similarly, LOID will reconstruct the second statement <height><7> reconstituted to <maximumy>< minimumY + 7). Finally, by the sequential equation, LOID generates the reconstructed program p' as shown in Figure 9B Figure 3.28.
[0270] Next, Theorem 3.29 is shown, which states that the reconstruction algorithm generates a new program that still satisfies the requirements of Definition 3.24.
[0271] Lemma 3.28. For any pair of expressions e, e' E and a pair of forward and backward transformation functions Φ and Φ -1 if
[0272]
[0273] then
[0274] Proof. By the expression equation, e' = Φ(e).
[0275]
[0276] Theorem 3.29 (Preservation of Variable Domains). For any pair of programs s, s' S and a pair of forward and backward transformation functions Φ and Φ -1 if
[0277]
[0278] then
[0279] Proof. The proof proceeds by induction on the derivation of s.
[0280] Case 3.29.1. S =.
[0281] By the empty equation, s' = also holds. Thus,
[0282] Case 3.29.2. where and
[0283] By the assignment equation, and Thus By Definition 3.12,
[0284]
[0285] By Definition 3.3,
[0286]
[0287] Also by Definition 3.3, for any j E [1, m],
[0288]
[0289] Therefore, for In the assignment equation, according to Theorem 3.28, we have
[0290]
[0291] Case 3.29.3. s = s1; s2, where s1, s2∈ S.
[0292] According to Definition 3.3, v(s) = v(s1)∪ v(s2), thus and According to the sequential equation, s' = s'1; s'2, where and According to the induction hypothesis, we have and Therefore, according to Definition 3.3,
[0293] Case 3.29.4. s = if e then s1 else s2 end, where e∈ E, s1, s2∈ S.
[0294] According to Definition 3.3, v(s) = v(e)∪ v(s1)∪ v(s2), thus and According to the conditional equation, s' = if e' then s'1 else s'2 end, where and According to Theorem 3.28, According to the induction hypothesis, we have and Therefore, according to Definition 3.3,
[0295] Case 3.29.5. s = while e do s1 end, where e∈ E, s1∈ S.
[0296] According to Definition 3.3, v(s) = v(e)∪ v(s1), thus and According to the loop equation, s' = while e' do s'1 end, where and According to Theorem 3.28, According to the induction hypothesis, we have Therefore, according to Definition 3.3,
[0297] 3.4 Soundness
[0298] We prove theorem 3.34, which states that the refactoring scheme according to the present application preserves the semantics of the original program. To this end, we first need to define the equivalence of two programs. However, the two programs before and after refactoring can be constructed using different sets of variables, which makes it difficult to compare them directly. Therefore, we define the equivalence of two programs indirectly in terms of the equivalence of the corresponding states generated by the two programs. Two states σ, σ'∈∑ are equivalent with respect to a pair of inverse transformation functions
[0299] Definition 3.30 (equivalent states). Given a pair of forward and backward transformation functions Φ V→V and Φ V′→V , two states σ, σ'∈∑ are equivalent if
[0300]
[0301]
[0302] denotes that the two states are equivalent with respect to and Φ V′→V .
[0303] Proposition 3.31. For any pair of equivalent states σ, σ'∈∑, where and Φ V′→V ,
[0304]
[0305] Proof. The two propositions are symmetric. By induction on the derivation of e, we obtain
[0306]
[0307] The other proposition can be proved in the same way.
[0308] Case 3.31.1. e = c, where c∈C.
[0309] σ'(Φ V→V′ (e))
[0310] = σ'(Φ V→V′ (c)) (e = c)
[0311] = σ'(c) (by theorem 3.16)
[0312] = c (by definition 3.7)
[0313] = σ(c) (by definition 3.7)
[0314] = σ(e) (e = c)
[0315] Case 3.31.2. e = x, where x ∈ V.
[0316] Since By definition 3.30, we have
[0317] σ'(Φ V→V′ (e)) = σ'(Φ V→V′ (x)) = σ(x) = σ(e).
[0318] Case 3.31.3. where
[0319] By definition 3.3, Thus,
[0320]
[0321]
[0322] Example 3.32. Continuing the discussion of the running example (Example 3.27). Figure 10 Three pairs of equivalent states are illustrated: and Here, σ0is the initial state of the original program before the first statement is executed. After the first statement is executed, the program state becomes σ1, where the value of X becomes 5. After the two statements are executed, the final state is σ2, where the value of height becomes 7. Similarly, for the refactored program, σ'0is the initial state, σ'1is the state after the first statement is executed, and σ'2is the final state. The three pairs of states are equivalent with respect to Figure 7C and Figure 7D Φ V→V′ , Φ V′→V defined in
[0323] For example, it is shown why
[0324] Proof. For x ∈ V,
[0325] σ'0(Φ V→V′ (x)) = σ'0(minimumX) = 1 = σ0(x),
[0326] σ'0(Φ V→V′ (y)) = σ'0(minimumY) = 2 = σ0(y),
[0327] σ'0(Φ V→V′ σ0 (width) = σ'0 (maximumX - minimumX) = σ'0 (maximumX) - σ'0 (minimumX)
[0328] = 4 - 1 = 3 = σ0 (width),
[0329] σ'0 (Φ V→V′ (height) = σ'0 (maximumY - minimumY) = σ'0 (maximumY) - σ'0 (minimumY)
[0330] = 6 - 2 = 4 = σ0 (height).
[0331] for y e V',
[0332] σ'0 (Φ V′→V (minimumX) = σ0 (x) = 1 = σ'0 (minimumX),
[0333] σ'0 (Φ V′→V (minimumY) = σ0 (y) = 2 = σ'0 (minimumY)
[0334] σ'0 (Φ V′→V (maximumX) = σ0 (x + width) = σ0 (x) + σ0 (width) = 1 + 3 = 4 = σ'0 (maximumX),
[0335] σ'0 (Φ V′→V (maximumY) = σ0 (y + height) = σ0 (y) + σ0 (height) = 2 + 4 = 6 = σ'0 (maximumY).
[0336] Next, the definition of equivalence states is used to define the equivalence of programs. Figure 11 This concept is illustrated. Two programs s and s' are considered equivalent if, starting from two equivalent initial states σ0 and σ'0, the execution of the two programs s and s' produces two equivalent final states σ1 and σ'1.
[0337] Definition 3.33 (Semantically Equivalent Programs). Given two programs s, s' e S, s' is semantically equivalent to s if for any two initially equivalent states and implies where σ0, σ1, σ'0, σ'1 e ∑, then s' is semantically equivalent to s.
[0338] Theorem 3.34 (Preservation of Program Semantics). For any program s e S and a pair of forward and backward transformation functions Φ and Φ -1 if and then s' is semantically equivalent to s as defined in Definition 3.33. That is, if
[0339] then with respect to Φ and Φ -1 ,
[0340] Proof. The proof proceeds by induction on the derivation of s.
[0341] Case 3.34.1. s = ε.
[0342] By the empty equation, s' = ε also holds. By Definition 3.10, and This means σ1= σ0and σ'1= σ'0. Thus,
[0343] Case 3.34.2. where and
[0344] In this case, by the assignment equation, It then follows that the condition in Definition 3.30 is satisfied, so holds.
[0345] First, we prove by another case analysis on the derivation of y.
[0346] Case 3.34.2.1.
[0347] By the assignment equation, we know
[0348]
[0349] Since In other words, By Definition 3.14, D -1 (y) = v(Φ -1 (y)), so
[0350]
[0351] Case 3.34.2.2.
[0352] By Definition 3.12, since y ∈ V',
[0353]
[0354] According to Definition 3.3,
[0355]
[0356] Thus Again according to Definition 3.3, there exists
[0357]
[0358] According to the assignment equation and the expression equation,
[0359]
[0360]
[0361] Then it is proved that
[0362]
[0363] First, it is proved that for any
[0364]
[0365] According to the assignment equation, it is known that
[0366]
[0367] Because There exists Therefore, there should be In other words, According to Definition 3.14, D -1 (y) = v(Φ -1 (y)), so
[0368]
[0369] According to the assignment equation and the expression equation,
[0370]
[0371]
[0372] Before continuing, it is necessary to prove that for any x∈V,
[0373]
[0374] According to Definition 3.12, because y∈V′,
[0375]
[0376] According to Definition 3.3,
[0377]
[0378] Thus, Again by definition 3.3, we have
[0379]
[0380] By definition 3.12, since x∈V,
[0381]
[0382] By definition 3.3,
[0383]
[0384] Then continue:
[0385]
[0386]
[0387] From the above, by definition 3.30, we have
[0388] Case 3.34.3. s = s1; s2, where s1, s2∈S.
[0389] By definition 3.3, v(s) = v(s1)∪v(s2) Thus and By the sequentiality equation, s' = s'1; s'2, where and are respectively used
[0390]
[0391] Define σ2, σ3, σ'2, σ'3.
[0392] By definition 3.10, we have and This means σ1= σ3 and σ'1= σ'3. By the induction hypothesis, we can thus conclude and Thus,
[0393] Case 3.34.4. s = if e then s1 else s2 end, where e∈E, s1, s2∈S.
[0394] By definition 3.3, v(s) = v(e)∪v(s1)∪v(s2), Thus and According to the conditional equation, s' = if e then s'1 else s'2 end, where and According to the conditional equation and the expression equation,
[0395] e' = Φ(e).
[0396] According to Theorem 3.31,
[0397] σ'0(e') = σ'0(Φ(e)) = σ0(e).
[0398] Another case analysis is made for the derivation of σ0(e).
[0399] Case 3.34.4.1. σ0(e) = True.
[0400] According to Definition 3.10, we have and According to the inductive hypothesis, it can be concluded that
[0401] Case 3.34.4.2. σ0(e) = False.
[0402] According to Definition 3.10, we have and According to the inductive hypothesis, it can be concluded that
[0403] Case 3.34.5. s = while e do s1 end, where e ∈ E and s1 ∈ S.
[0404] According to Definition 3.3, v(s) = v(e) ∪ v(s1) thus and According to the loop equation, s' = while e' do s'1 end, where and According to the conditional equation and the expression equation,
[0405] e' = Φ(e).
[0406] According to Theorem 3.31,
[0407] σ'0(e') = σ'0(Φ(e)) = σ0(e).
[0408] Another case analysis is made for the derivation of σ0(e).
[0409] Case 3.34.5.1 σ0(e) = True.
[0410] Use
[0411]
[0412] Define σ2, σ3, σ'2, σ'3.
[0413] By definition 3.10, we have and This means σ1= σ3and σ'1= σ'3.
[0414] By the inductive hypothesis, we can infer and Thus,
[0415] Case 3.3 4.5.2. σ0(e) = False.
[0416] By definition 3.10, we have and Thus,
[0417] Theorem 3.34 states that the refactored program generated by LOID will produce a final state that is identical to the state produced by the original program. This theorem holds even if the two programs use different variables and data structures constructions. This result is important because it facilitates automated software evolution. When software evolves, developers often need to refactor code to improve its quality, maintainability, and performance. However, replacing data structures can introduce errors to the rest of the program. The theorem ensures that the refactored program generated by LOID will produce the same output as the original program for identical input, which is crucial for ensuring software correctness.
[0418] 4 Extension of Compound Variables and Other Language Constructs
[0419] While the formalization and proof above focus on the core language, the approach according to the invention also applies to extended languages with more complex language constructs, such as compound data structures, functional programming, and certain operations involving arrays and pointers.
[0420] In particular, for compound data structures, the syntax of the core language in Definition 3.1 is extended by extending the variable x∈X from a simple variable to a compound data record and its attributes. Figure 5
[0421] Definition 4.1 (Syntax of Compound Variables). The following syntax rules extend the definition of a variable x∈X in Definition 3.1.
[0422] X := r.p
[0423] R := r0 | r.p
[0424] where r, r0∈R, p∈P.
[0425] As Figure 5 defined in the introduction, a primitive variable x ∈ X is an attribute p ∈ P of a composite variable r ∈ R. A composite variable r ∈ R is either a global root variable r0 or an attribute of another composite variable r' ∈ R, where r' ≠ r. The global root variable r0 is a virtual variable introduced for convenience of discussion. It is unique and always present. It corresponds to the global namespace containing all variables in the program.
[0426] Intuitively, the structure of R ∪ X can be illustrated with a tree. Each leaf node corresponds to a primitive variable x ∈ X. Each internal node corresponds to a composite variable r ∈ R. The root node is the global root variable r0. Any non-root node in the tree can be denoted as r.p, where r ∈ R is its parent and p ∈ P is the label of the edge connecting to the parent.
[0427] A running example is provided next to demonstrate the capabilities of LOID in efficiently and effectively processing composite data structures.
[0428] Example 4.2. Figure 12A A structured representation of V = {manager.name.first, manager.name.last, manager.email, client.first, client.last, clientEmail} is illustrated to show how LOID represents the set of variables V = {manager.name.first, manager.name.last, manager.email, client.first, client.last, clientEmail} as a tree, where the common prefix with the virtual variable r0. is omitted for simplicity. For example, the leaf node x5 represents the primitive variable client.last in V. It is connected to its parent r3 by an edge labeled last, which means that x5 is denoted as r3.last in syntax. The internal node r3 represents the composite variable client. It is connected to its parent r0 by an edge labeled client, which means that r3 is denoted as r0.client in syntax. The root node r0 represents the global root variable in syntax.
[0429] Each composite variable is an instance of a class. For example, Figure 12A r2 and r3 in Figure 12A r1 in
[0430] This structured representation of variables allows LOID to provide a canonical form that eliminates potentially redundant transformation functions. Redundant transformation functions can occur when multiple instance variables of the same class share similar transformations. With the structured representation in LOID, users can now specify a transformation function only once for each class, achieving the same effect as verbose specification for each variable.
[0431] Example 4.3. Let's continue with the running example (Example 4.2). Figure 12B The structured representation of V′ = {manager.name, manager.email, client.name, client.email} is illustrated, showing the target variable set V = {manager.name, manager.email, client.name, client.email} as a tree, where the common prefix of the dummy variable "r0." is omitted for simplicity. The mapping between V and V′ is established through the following reconstruction operation. First, the same Name variable ( Figure 12A In the first string, each pair of original attributes first and last is merged into a single string. Next, an "Extract Class" refactoring operation is performed (see reference
[20] ), which merges the variables client and clientEmail. Figure 12A (in Chinese) is merged into a single composite variable client containing the same content. Figure 12B middle).
[0432] To describe these refactoring operations, users can use, for example... Figure 13A and Figure 13B The specified conversion function is shown. Recall Section 3.2, the forward conversion function ( Figure 13A The function describes how to replace the original variable with an expression in the target variable space, while the inverse transformation function ( Figure 13B This describes how to replace the target variable with an expression from the original variable space. For example, in Figure 13B In the code, line 7 of the function `TransformTo_ContactNew()` specifies how to merge the properties `first` and `last` of the `Name` class in the original variable space into a single string in the target variable space. Line 18 of the function `TransformTo_Global()` specifies how to merge the original variables `client` and `clientEmail` into a single composite variable in the target variable space.
[0433] Please note that the conversion function is specified once for each class, not once for each instance variable. In other words, in Figure 13A and Figure 13B In this case, users only need to specify 5 conversion functions, instead of 10. Figure 12A and Figure 12B All 10 original variables are detailed in 10 transformation functions, which significantly reduces the workload.
[0434] As a concrete example, the function `TransformTo_Name()` specifies how to transform all instances of the `Name` class into the target variable space. This function is called in two places: in Figure 13A In the ContactOld class, it's on line 17 of the name property and line 28 of the GlobalNew class. These two usages correspond to... Figure 12A The variables `manager.name` and `client` are specified in the LOID framework. This structured specification eliminates potential redundancy caused by multiple instances of the same class. LOID also supports individual specification of each variable for finer-grained control.
[0435] LOID automatically combines these class-based conversion functions into a form equivalent to that in Definition 3.12, which is defined for each primitive variable. For example, it demonstrates how LOID transforms from... Figure 13A Calculate Φ V→V′ (r0.manager.email). The LOID begins with the transformation function `Transform_GlobalOld()` of `r0`, instantiating its parameter `global_new` with `r′0`. Through this instantiation, line 27 indicates that the transformation of `r0.manager` is constructed by calling another function `Transform_ContactOld()` and using the parameter `r′0.manager`. The LOID is then recursively computed in `Transform_ContactOld()`, instantiating its parameter `contact_new` with `r′0.manager`. Through this instantiation, line 18 indicates that the transformation of `r′0.manager.email` is obtained by replacing `contact_new` with `r′0.manager`. The result is Φ. V→V′ (r0.manager.email) = r′0.manager.email. Similarly, LOID from... Figure 13B Recursive calculation of Φ V′→V (r′0.client.name). The result is Φ. V′→V (r′0.client.name)=r0.client.first+″″+r0.client.last.
[0436] After completing the class-based specification composition, LOID continues to apply the algorithm in Section 3.3 and refactors the program accordingly.
[0437] To further extend the applicability of LOID, implementations of the present application are also applicable to programs that can use other complex language structures such as lambda functions, arrays, pointers, and exception handlers. For such programs, LOID is able to transform code snippets that are expressible in the core language. LOID preserves the semantics of the transformed code snippets, ensuring that changes are locally encapsulated within these snippets. Thus, regardless of the computations performed by the rest of the program, they are able to function as originally. These extensions highlight the flexibility of the scheme of the present application.
[0438] 5 Experimental evaluation
[0439] As mentioned above, a LOID prototype was implemented for a subset of TypeScript (see
[41] ). TypeScript was chosen as the research vehicle for the following reasons: (1) TypeScript is a superset of JavaScript, and both JavaScript and TypeScript are widely used in software development and are popular among software developers (see
[65] ; and
[66] ); (2) the type system of TypeScript enables LOID to reason about the data structure hierarchy in the original program and the refactored program; (3) package management systems such as npm (see
[52] ) enable developers to download source code of JavaScript and TypeScript packages and their dependencies, which are relatively easy to configure and run; (4) package management systems also provide tags, documentation, and usage statistics, which provide guidance in identifying commonly used libraries. Although the current implementation of LOID is for TypeScript, the algorithms and basic principles described are applicable to other programming languages that provide similar language structures as defined in Definition 3.1, such as Java and C++.
[0440] 5.1 Benchmarking
[0441] To evaluate the LOID prototype, the inventors obtained benchmark tests that represent three classes of computations: utility libraries, complex data structures, and algorithms. The utility benchmark tests implement common computations with a wide range of language structures and code structures. The data structure benchmark tests are large software projects that implement complex class hierarchies. The algorithm benchmark tests implement complex data flow and control flow. In addition, the algorithm benchmark tests are compatible with online evaluation platforms such as Codeforces (see
[46] ) and LeetCode (see
[37] ) that can thoroughly test the consistency between the original program and the program refactored by LOID.
[0442] The benchmark programs include:
[0443] jsonwebtoken / verify. jsonwebtoken (see [2]) is a Node.js implementation of the JSON Web Token standard (RFC 7519) (see
[31] ). It has more than 13 million downloads per week on npm and 17,300 stars on GitHub. The evaluation used the verify() function (a function body was chosen for evaluation as long as it met the following criteria: (1) the function body contained at least 20 lines of code so that the code structure was relatively diverse and complex, and (2) the code was self-contained, i.e., executable without the need to inline other packages; when multiple functions met these criteria, one was chosen at random), which decodes a JSON Web Token and checks its validity.
[0444] numeral / numberToFormat. numeral (see
[14] ) is a JavaScript library for formatting numbers to strings and manipulating them as strings. It has more than 1 million downloads per week on npm and 9,600 stars on GitHub. The evaluation used the numberToFormat() function, which supports formatting numbers to currency, percentage, ordinal, and other string formats.
[0445] three / cartesian-spherical. three (see
[68] ) is a JavaScript 3D library built with WebGL (see
[27] ). It has more than 1 million downloads per week on npm and 98,400 stars on GitHub. The evaluation used the Vector3 and Spherical classes in the math folder, which implement Cartesian coordinates and spherical coordinates in three-dimensional space, respectively.
[0446] core-js / ieee754.pack: core-js (see
[56] ) is a popular polyfill library that implements the latest JavaScript standards for older web browsers. It has more than 30 million downloads per week on npm and 23,800 stars on GitHub. The evaluation used the pack() function in the internals / ieee754.js file, which converts a number to IEEE 754 floating-point format (see
[24] ) and stores it in a buffer.
[0447] colord / parseHex. colord (see
[62] ) is a lightweight, high-performance, object-oriented TypeScript library for color manipulation and conversion. It has over 8 million downloads per week on npm and 1566 stars on GitHub. The evaluation used the parseHex() function in the src / colorModels / hex.ts file, which parses a color from a 6-digit hexadecimal string into an object.
[0448] lodash / random: lodash (see
[10] ) is a modern JavaScript utility library that implements common programming tasks. It has over 44 million downloads per week on npm and 58700 stars on GitHub. The evaluation used the random() function, which generates a random number within a user-specified range.
[0449] color-convert / rgb.ansi256. color-convert (see
[32] ) is a color conversion library for JavaScript. It supports converting colors between a variety of formats, such as RGB, HSL, HSV, HWB, CMYK, ANSI, and hexadecimal strings. It has over 200 million downloads per week on npm and 718 stars on GitHub. The evaluation used the rgb.ansi256() function, which converts an RGB color to an ANSI-256 color code.
[0450] fraction.js / factorize. fraction.js (see
[18] ) is a rational number arithmetic library for JavaScript. It has over 12 million downloads per week on npm and 450 stars on GitHub. The evaluation used the factorize() function, which performs prime factorization on an integer.
[0451] vjudge / Luogu-P1055 (see
[73] ). Luogu-P1055 is a programming contest problem that requires determining whether a given ISBN number is valid, and if the number is invalid, generating a correction. The evaluation used a passed JavaScript submission.
[0452] vjudge / PoJ-2406 (see
[72] ). POJ-2406 is a programming contest problem that asks to find the shortest substring that forms a special repeating pattern in a given string and the number of repetitions. Since no JavaScript submissions were available, the evaluation used a version converted from a passed C++ submission.
[0453] vjudge / UVA-100 (see
[74] ). UVA-100 is a programming contest problem that asks to find the maximum number of steps required for an integer to converge to 1 according to the Collatz conjecture (see
[36] ). Since no JavaScript submissions were available, the evaluation used a version converted from a passed C++ submission.
[0454] vjudge / Codeforces-1619A (see
[75] ). Codeforces-1619A is a programming contest problem that asks to determine whether a given string can be represented as another string written twice in succession. The evaluation used a passed JavaScript submission.
[0455] jmist.Box2. JMIST (see
[35] ) is a Java library for image synthesis. The evaluation used the Box2 class, which implements widely used rectangular geometry functions. The class was also used in a previous evaluation for class replacement (see
[60] ). The class was converted to TypeScript and its member functions bodies were condensed into a program.
[0456] Table 1 summarizes the characteristics of the benchmarks. Each row corresponds to a benchmark. The first column (Benchmark) shows the name of the benchmark. The next column (Category) shows the computation implemented by the benchmark. Of the benchmarks performed, 5 implement utility libraries, 5 implement complex data structures, and 4 implement algorithms. The next column (Structure) shows the language structures used in the source code of the benchmark. The benchmarks performed use a variety of language structures: 4 use data collections such as arrays and maps, 5 use object instances of user-defined classes, 13 use function calls, 2 use lambda functions, and 11 use control structures such as conditionals, loops, and try-catch blocks.
[0457] Table 1
[0458]
[0459]
[0460]
[0461] 5.2 Refactoring operations
[0462] The inventors collected a list of refactoring operations from a book (see reference
[20] ) and multiple surveys spanning a long time in the software engineering community (see references
[47] ;
[63] ; and
[70] ). All these sources provide a list of refactoring operations that are largely similar, with 25 focusing on data structures and variables. In addition, another data structure refactoring operation discussed in a recent paper (see reference
[55] ) is the addition of auxiliary fields.
[0463] Table 2 lists all 26 data structure refactoring operations from the literature. The first column (Refactoring operation) lists the refactoring operations outlined in the literature. Not all refactoring operations have the same level of difficulty. For example, renaming a variable can be equivalent to a simple string replacement, but changing a variable type can require more complex reasoning (shown in Section 2) to ensure the correctness of the refactored program.
[0464] Table 2
[0465]
[0466]
[0467] The inventors compared the range of refactoring operations supported by LOID and the four most popular IDEs, namely Visual Studio Code (see reference
[43] ), Microsoft Visual Studio (see reference
[44] ), JetBrains IntelliJ IDEA (see reference
[30] ), and Eclipse (see reference
[15] ), which are favored by 73.71%, 28.43%, 26.82%, and 9.90% of software developers, respectively (see reference
[66] ). In Table 2, the last five columns (LOID, VSCode, Visual Studio, IntelliJ IDEA, Eclipse) show the coverage provided by LOID, Visual Studio Code, Microsoft Visual Studio, JetBrains IntelliJ IDEA, and Eclipse. The markers "V and "X" indicate whether the tool supports or does not support the corresponding refactoring operation, respectively. The results for the four commercial IDEs were obtained by inspecting their online documentation (see references
[17] ;
[29] ;
[40] ; and
[42] ).
[0468] LOID supports 22 out of 26 refactoring operations (84.6%) in the literature. Only 4 are out of the scope of LOID: extract variable / property are out of scope because they require replacing expressions instead of variables. Split variable / property are out of scope because they require changing the lifetime of the variable. In comparison, these four commercial IDEs only support 3 out of 26 refactoring operations (11.5%), 6 out of 26 (23.1%), 10 out of 26 (38.5%), and 8 out of 26 (30.8%) respectively. Moreover, studies have shown that certain refactoring features of these IDEs are underutilized due to inaccuracy (see literature
[22] ). LOID provides automation for a wider range of refactoring operations than existing commercial tools, and does so while ensuring correctness.
[0469] 5.3 Experimental Results
[0470] The inventors implemented a prototype for LOID in Node.js 20.9.0 and TypeScript 5.3.3. It parses the source code into an abstract syntax tree using the ts-morph package (see literature
[61] ). The experiments were conducted on an Ubuntu 22.04.3 LTS server with two 16-core CPU Intel(R) Xeon(R) Gold 6444Y processors (45M cache, base clock 3.60 GHz) and 256 GiB DDR5-4800 ECC RDIMR RAM. The following pre-processing steps were performed on the benchmark programs: (1) extract function bodies, (2) rewrite function arguments, local variables, and return values as variables in the variable space V, and (3) replace syntactic sugar such as ++ and += with their LOID-compatible equivalents. For jsonwebtoken / verify, the code that sets default argument values at the beginning of the function was also excluded. The inventors expect that in many usage scenarios, it will be standard practice to automatically introduce such pre-processing steps.
[0471] For each benchmark, the inventors identified all refactoring operations that are suitable for the code structure and functionality of the benchmark in Table 2. The set of refactoring operations performed on each benchmark is listed in the last column of Table 1 (refactoring operations). One special case is the jsonwebtoken / verify benchmark, for which two suitable sets of refactoring operations were identified, separated by a horizontal line in the table. For each refactoring operation, the integer in the parentheses indicates the number of times the operation was performed on the benchmark. Overall, the experiments conducted cover 12 different types of refactoring operations. The transformation functions were then specified, and the source code was automatically refactored using LOID.
[0472] Table 3 shows the results of applying LOID to the benchmarks. Each row corresponds to a benchmark, with jsonwebtoken / verify being a special case for which two sets of refactorings were performed and whose results are shown in two rows. The first column (Benchmark) shows the name of the benchmark. The next column (Number of refactorings) shows the total number of refactorings performed on the benchmark, computed by summing the counts in Table 1.
[0473] Table 3
[0474]
[0475] Code size. The next column (Number of original AST nodes) shows the number of AST nodes in the original program. The next column (Number of original variables) shows the size of the original variable space, expressed as v1 + v2, where v1, v2 are the number of basic and composite variables in V, respectively. The next column (Number of refactored AST nodes) shows the number of AST nodes in the refactored program after applying LOID. The next column (Number of refactored variables) shows the size of the target variable space, expressed as v'1 + v'2, where v'1, v'2 are the number of basic and composite variables in V', respectively.
[0476] LOID transformed original programs with 216-2415 AST nodes and generated refactored programs with 241-2901 AST nodes. Most programs grew in size after refactoring. The main reason is that single variables were replaced by expressions that were assigned to them, which often contain multiple AST nodes. This phenomenon often occurs in refactorings that merge variables / properties, split variables / properties, replace variables / properties with variables / properties, and change the type of variables / properties. The inventors noticed that off-the-shelf simplification tools can be directly applied to remove redundant sub-expressions in the refactored code while preserving semantics. Another reason for the increase in AST size is that some simple variables were replaced by complex variables with nested properties. This phenomenon often occurs in refactorings that extract classes and move properties.
[0477] The AST size of one refactored program (jsonwebtoken / verify / inline_transform) is smaller than its original version. This reduction is caused by the inlining of classes, where the original variable has more nested properties than its refactored counterpart.
[0478] Execution time. The next two columns (Parsing time and Transformation time) show the wall-clock time (in seconds) taken to parse the source code into an AST and to apply the refactoring transformation, respectively. They are measured by averaging the execution times over 100 runs.
[0479] Starting with the AST generated by the t s-morph package, LOID spent 0.127–6.739 seconds converting the AST into a reconstructed version. Figure 14A This illustrates how the execution time of LOID scales with code size, showing that the execution time of LOID scales well with the size of the original program's AST, where the horizontal axis represents the original AST size and the vertical axis represents the time spent on each step (in seconds). Figure 14B The execution time of LOID is consistent with the asymptotic complexity results in Theorem 3.26, where the horizontal axis represents the product of the original AST size and the total number of reconstructed variables, and the vertical axis represents the time spent on each step (in seconds). Blue dots represent the time spent by t s-morph parsing the benchmark source code into an AST. Orange dots represent the time spent on LOID inference reconstruction operations and modifying the benchmark code. Dashed lines represent the linear regression results for these two series. In the experiments conducted, the parsing time remained stable across different AST sizes (0.542–0.711 seconds).
[0480] Figure 14A The results show that, in the experiments conducted, the conversion time increases approximately linearly with the size of the original AST. Theoretically, the conversion time is linearly related to the product of the original AST size and the total number of reconstructed variables (see...). Figure 14B (and Theorem 3.26). However, in practice, the number of reconstructed variables is often negligible compared to the original AST size (see Table 3). Therefore, in the experiments conducted, the transformation time scales well with the original AST size. These results highlight the efficiency of the LOID algorithm in computationally preserving reconstruction transformations.
[0481] Functional correctness. LOID successfully refactored all 14 benchmark programs, producing syntactically correct code. Recall that, as long as the conversion functions satisfy Definition 3.19, LOID guarantees to preserve program semantics. In practice, this standard can be difficult to satisfy when floating-point arithmetic is involved. To assess the effectiveness of LOID in preserving program semantics in this case, the inventors developed test inputs that check whether the refactored programs can be compiled and executed correctly. Most of the refactored programs produced final program states that were identical to the original states. The only exceptions that occurred in the experiment were caused by (1) inconsistent rounding errors in floating-point arithmetic when subexpressions were computed in different orders and (2) certain functions’ calls (e.g., Math.random() or Date.now()) that can not produce the same results when executed repeatedly. Case (1) occurred in three / vector3-spherical and jmist.Box2, which perform floating-point computations. Case (2) occurred in lodash / random, which generates random numbers. Nonetheless, the discrepancies were within reasonable bounds. The high proportion of success in preserving program behavior is attributed to the theoretical guarantees provided by LOID.
[0482] For the algorithmic benchmarks, the inventors also submitted the refactored programs to an online evaluation platform, which returned a “passed” result after extensive testing. These results indicate that the behavior of the refactored programs is consistent with the original programs, even for complex computations.
[0483] 6 Related Work
[0484] Inductive synthesis of alternative data structures. A number of studies use counterexample-guided inductive synthesis (CEGIS) (see
[64] ) to automate the data structure refactoring process. REVAMP (see
[54] ) updates class methods when data fields change. VOLT (see
[55] ) generates code to maintain relationships between existing data fields and new auxiliary fields. MASK (see
[60] ) generates wrappers for alternative classes as a direct replacement without changing the rest of the program. MIGRATOR (see
[77] ) modifies SQL queries to match the alternative database schema. CRES (see
[76] ) optimizes the selection of containers that provide similar APIs, e.g., replacing ArrayList with LinkedList and updating calls to the insert and delete APIs. All these techniques first apply CEGIS and then reject incorrect candidates by invoking a verifier. In contrast, LOID (1) does not require CEGIS but is based on static source-to-source transformations, which are typically faster and more scalable, (2) leverages user-provided formalized mappings between original and target data fields to derive refactored programs with correctness guarantees, and (3) is able to replace all outdated references to original data fields with up-to-date references, not just a few references in the same class or only API calls.
[0485] Library replacement according to documentation. Many techniques work on upgrading deprecated libraries and APIs. SOAR (see
[50] ) learns mappings between different library APIs by performing natural language processing (NLP) on documentation and error messages. SEMDIFF (see [8]; and [9]) recommends method replacements for evolving frameworks according to historical records, e.g., when method calls are removed. APPEVOLVE (see
[19] ) updates usage of deprecated Android APIs by learning from similar updates in other code bases and verifies them by testing. In contrast, LOID (1) enables users to customize formalized transformation functions, (2) uses them to automatically derive how the rest of the program should be changed accordingly to preserve the original functionality, and (3) provides correctness guarantees.
[0486] Refactoring operations focusing on code movement. Many techniques assist with routine tasks in source code refactoring, such as method extraction (see [5]; and
[69] ) and variable extraction (see
[12] ; and [7]). These techniques typically focus on syntactically reordering existing statements according to the availability of variables and expressions. In contrast, LOID (1) reasons about semantic changes in data representations and computes how to re-implement related statements, (2) supports custom transformation functions that can be more complex than routine code movement tasks, and (3) provides formalized correctness guarantees.
[0487] Other aspects of automated refactoring. Some techniques (see
[19] ;
[21] ;
[38] ;
[45] ; and
[58] ) synthesize code editing rules from examples, e.g., by finding step sequences that explain larger changes (see
[58] ) and by generalizing identifier names (see
[38] ). These techniques address orthogonal problems and can be integrated into LOID as synthesizers of transformation functions.
[0488] 7Conclusion
[0489] The invention formalizes refactoring and proposes a novel approach for deductively evolving programs for alternative data structures. It facilitates systematic refactoring, which is crucial for improving software design while ensuring correctness. The inventors implemented a prototype and evaluated it with 14 representative benchmarks. Experimental results highlight the correctness, expressiveness, and scalability of the approach embodying the invention.
[0490] In summary, the invention proposes a novel closed-form solution for deriving how to evolve programs for alternative data structures, enabling the generation of a refactored program that is correct by construction, and without the need for external proof assistants, verifiers, or solvers. The invention formalizes the refactoring problem and introduces the equality between program states in a program using potentially different variables. It is proven above that the final state of the refactored program is equal to the state produced by the original program. Experiments show that LOID can correctly and efficiently successfully process all benchmarks, with the time complexity of LOID being linear in the product of the original AST size and the number of refactored variables.
[0491] The present application can be implemented as a computer device comprising a memory and a processor, the memory having stored thereon computer instructions executable by the processor, the computer instructions when executed by the processor instructing the processor to perform the steps of the method of the present application. The executable computer instructions can be embodied in and implemented by an application program. The computer device can be broadly a server, a terminal, or any other electronic device having necessary computing and / or processing capabilities. In an embodiment, the computer device can comprise a processor, a memory, a network interface, a communication interface, and the like connected by a system bus. The processor of the computer device can be configured to provide necessary computing, processing, and / or control capabilities. The memory of the computer device can comprise a non-volatile storage medium and an internal memory. The non-volatile storage medium can have or store thereon an operating system, a computer program, and the like. The internal memory can provide an environment for running the operating system and the computer program in the non-volatile storage medium. The network interface and the communication interface of the computer device can be configured to connect and communicate with external devices through a network. The computer program, when executed by the processor, performs the steps of the method of the present application.
[0492] The present application can be implemented as a computer readable storage medium having stored thereon a computer program, the computer program when executed by a processor causing the steps of the method of the present application to be performed. In an embodiment, the computer program is distributed over a plurality of computer devices or processors coupled to a network, such that the computer program is stored, accessed and executed by one or more computer devices or processors in a distributed manner. A single method step / operation, or two or more method steps / operations, can be performed by a single computer device or processor, or by two or more computer devices or processors. One or more method steps / operations can be performed by one or more computer devices or processors, and one or more other method steps / operations can be performed by one or more other computer devices or processors. One or more computer devices or processors can perform a single method step / operation, or perform two or more method steps / operations.
[0493] It will be appreciated by those skilled in the art that all or part of the steps of the present application can be directed to relevant hardware such as computer equipment or a processor by a computer program, which can be stored in a non-transitory computer-readable storage medium, and which, when executed, causes the steps of the method of the present application to be performed. Depending on the situation, any reference to a memory, storage, database, or other medium can include non-volatile and / or volatile memory. Examples of non-volatile memory include read-only memory (ROM), programmable ROM (PROM), electrically programmable ROM (EPROM), electrically erasable programmable ROM (EEPROM), flash memory, magnetic tapes, floppy disks, magneto-optical data storage devices, optical data storage devices, hard disks, solid-state disks, etc. Examples of volatile memory include random-access memory (RAM), external cache memory, etc.
[0494] The contents of each of the above-referenced and cited documents are hereby incorporated by reference in their entirety.
[0495] Although the present application has been described in connection with the embodiments thereof, it will be appreciated that the description and drawings are merely exemplary and not limiting and that the application is not limited to the disclosed embodiments. Various modifications and variations are possible in the context of the present application without departing from the spirit thereof.
[0496] List of documents:
[0497] [1] Dalal Alrajeh, Antoine Cailliau, and Axel van Lamsweerde. 2020. Adapting requirements models to varying environments. In Proceedings of the ACM / IEEE 42nd International Conference on Software Engineering (Seoul, South Korea) (ICSE’20). Association for Computing Machinery, New York, NY, USA, 50-61. https: / / doi.org / 10.1145 / 3377811.3380927
[0498] [2] Auth0, Inc. 2023. jsonwebtoken-npm. https: / / www.npmjs.com / package / jsonwebtoken
[0499] [3] Gabriele Bavota, Andrea Lucia, Andrian Marcus, and Rocco Oliveto. 2014. Automating Extract Class Refactoring: An Improved Method and Its Evaluation. Empirical Softw. Engg. 19, 6 (dec 2014), 1617-1664. https: / / doi.org / 10.1007 / s10664-013-9256-x
[0500] [4] Walter Cazzola and Luca Favalli. 2023. Scrambled Features for Breakfast: Concepts of Agile Language Development. Commun. ACM 66, 11 (oct 2023), 50-60. https: / / doi.org / 10.1145 / 3596217
[0501] [5] Sofia Charalampidou, Apostolos Ampatzoglou, Alexander Chatzigeorgiou, Antonios Gkortzis, and Paris Avgeriou. 2017. Identifying Extract Method Refactoring Opportunities Based on Functional Relevance. IEEE Transactions on Software Engineering 43, 10 (2017), 954-974. https: / / doi.org / 10.1109 / TSE.2016.2645572
[0502] [6] Mark Chen, Jerry Tworek, Heewoo Jun, Qiming Yuan, Henrique Ponde de Oliveira Pinto, Jared Kaplan, Harri Edwards, Yuri Burda, Nicholas Joseph, Greg Brockman, Alex Ray, Raul Puri, Gretchen Krueger, Michael Petrov, Heidy Khlaaf, Girish Sastry, Pamela Mishkin, Brooke Chan, Scott Gray, Nick Ryder, Mikhail Pavlov, Alethea Power, Lukasz Kaiser, Mohammad Bavarian, Clemens Winter, Philippe Tillet, Felipe Petroski Such, Dave Cummings, Matthias Plappert, Fotios Chantzis, Elizabeth Barnes, Ariel Herbert-Voss, William Hebgen Guss, Alex Nichol, Alex Paino, Nikolas Tezak, Jie Tang, Igor Babuschkin, Suchir Balaji, Shantanu Jain, William Saunders, Christopher Hesse, Andrew N. Carr, Jan Leike, Josh Achiam, Vedant Misra, Evan Morikawa, Alec Radford, Matthew Knight, Miles Brundage, Mira Murati, Katie Mayer, Peter Welinder, Bob McGrew, Dario Amodei, Sam McCandlish, Ilya Sutskever, and Wojciech Zaremba. 2021. Evaluating Large Language Models Trained on Code. https: / / doi.org / 10.48550 / arXiv.2107.03374 arXiv:2107.03374 [cs.LG]
[0503] [7] Xiaye Chi, Hui Liu, Guangjie Li, Weixiao Wang, Yunni Xia, Yanjie Jiang, Yuxia Zhang, and Weixing Ji. 2023. An Automated Approach to Extracting Local Variables. In Proceedings of the 31st ACM joint European Software Engineering Conference and Symposium on the Foundations of Software Engineering (, San Francisco, CA, USA,)(ESEC / FSE 2023). Association for Computing Machinery, New York, NY, USA, 313-325. https: / / doi.org / 10.1145 / 3611643.3616261
[0504] [8] Barthelemy Dagenais and Martin P. Robillard. 2009. SemDiff: Analysis and Recommendation Support for API Evolution. In Proceedings of the 31st International Conference on Software Engineering (ICSE'09). IEEE Computer Society, USA, 599-602. https: / / doi.org / 10.1109 / ICSE.2009.5070565
[0505] [9] Barthélémy Dagenais and Martin P. Robillard. 2011. Recommending Adaptive Changes for Framework Evolution. ACM Trans. Softw. Eng. Methodol. 20, 4, Article 19 (sep 2011), 35 pages. https: / / doi.org / 10.1145 / 2000799.2000805
[0506]
[10] John-David Dalton, Benjamin Tan, Michal Mathias Bynens, Jean-Philippe Sirois, Zack Hall, and JS Foundation. 2021. lodash-npm. https: / / www.npmjs.com / package / lodash
[0507]
[11] Leonardo De Moura and Nikolaj 2008. Z3: An Efficient SMT Solver. In Proceedings of the Theory and Practice of Software, 14th International Conference on Tools and Algorithms for the Construction and Analysis of Systems (Budapest, Hungary) (TACAS'08 / ETAPS'08). Springer-Verlag, Berlin, Heidelberg, 337-340.
[0508]
[12] Massimiliano Di Penta, Gabriele Bavota, and Fiorella Zampetti. 2020. On the relationship between refactoring actions and bugs: a differentiated replication. In Proceedings of the 28th ACM Meeting on European Software Engineering Conference and Symposium on the Foundations of Software Engineering (Virtual Event, USA) (ESEC / FSE 2020). Association for Computing Machinery, New York, NY, USA, 556-567. https: / / doi.org / 10.1145 / 3368089.3409695
[0509]
[13] Torgeir Dingsoeyr, Davide Falessi, and Ken Power. 2019. Agile Development at Scale: The Next Frontier. IEEE Softw. 36, 2 (mar 2019), 30-38. https: / / doi.org / 10.1109 / MS.2018.2884884
[0510]
[14] Adam Draper. 2017. numeral-npm. https: / / www.npmjs.com / package / numeral
[0511]
[15] Eclipse Foundation. 2024a. Eclipse IDE | The Eclipse Foundation. https: / / eclipseide.org /
[0512]
[16] Eclipse Foundation. 2024b. Eclipse SWT. https: / / github.com / eclipse-platform / eclipse.platform.swt
[0513]
[17] Eclipse Foundation. 2024c. Help - Eclipse Platform. https: / / help.eclipse.org / latest / index.jsp?topic=%2Forg.eclipse.jdt.doc.user%2Fconcepts%2Fconcept-refactoring.htm
[0514]
[18] Robert Eisele. 2023. fraction.js - npm. https: / / www.npmjs.com / package / fraction.js
[0515]
[19] Mattia Fazzini, Qi Xin, and Alessandro Orso. 2019. Automated API-Usage Update for Android Apps. In Proceedings of the 28th ACM SIGSOFT International Symposium on Software Testing and Analysis (Beijing, China) (ISSTA 2019). Association for Computing Machinery, New York, NY, USA, 204-215. https: / / doi.org / 10.1145 / 3293882.3330571
[0516]
[20] Martin Fowler. 1999. Refactoring: Improving the Design of Existing Code. Addison- Wesley Longman Publishing Co., Inc., USA.
[0517]
[21] Xiang Gao, Shraddha Barke, Arjun Radhakrishna, Gustavo Soares, Sumit Gulwani, Alan Leung, Nachiappan Nagappan, and Ashish Tiwari. 2020. Feedback- Driven Semi-Supervised Synthesis of Program Transformations. Proc. ACM Program. Lang. 4, OOPSLA, Article 219 (nov 2020), 30 pages. https: / / doi.org / 10.1145 / 3428287
[0518]
[22] Yaroslav Golubev, Zarina Kurbatova, Eman Abdullah Al Omar, Timofey Bryksin, and Mohamed Wiem Mkaouer. 2021. One thousand and one stories: a large-scale survey of software refactoring. In Proceedings of the 29th ACM Meeting on European Software Engineering Conference and Symposium on the Foundations of Software Engineering (Athens, Greece) (ESEC / FSE 2021). Association for Computing Machinery, New York, NY, USA, 1303-1313. https: / / doi.org / 10.1145 / 3468264.3473924
[0519]
[23] Alex Gyori, Lyle Franklin, Danny Dig, and Jan Lahoda. 2013. Crossing the gap from imperative to functional programming through refactoring. In Proceedings of the 2013 9th Meeting on Foundations of Software Engineering (Saint Petersburg, Russia) (ESEC / FSE 2013). Association for Computing Machinery, New York, NY, USA, 543-553. https: / / doi.org / 10.1145 / 2491411.2491461
[0520]
[24] IEEE Computer Society. 2019. IEEE Standard for Floating-Point Arithmetic. IEEE Std 754-2019 (Revision of IEEE 754-2008), (July 2019), 1-84. https: / / doi.org / 10.1109 / IEEESTD.2019.8766229
[0521]
[25] Shachar Itzhaky, Hila Peleg, Nadia Polikarpova, Reuben N. S. Rowe, and Ilya Sergey. 2021. Cyclic program synthesis. In Proceedings of the 42nd ACM SIGPLAN International Conference on Programming Language Design and Implementation (Virtual, Canada) (PLDI 2021). Association for Computing Machinery, New York, NY, USA, 944-959. https: / / doi.org / 10.1145 / 3453483.3454087
[0522]
[26] James Ivers, Robert L. Nord, Ipek Ozkaya, Chris Seifried, Christopher S. Timperley, and Marouane Kessentini. 2022. Industry experiences with large-scale refactoring. In Proceedings of the 30th ACM European Software Engineering Conference and Symposium on the Foundations of Software Engineering, Singapore, Singapore, (ESEC / FSE 2022). Association for Computing Machinery, New York, NY, USA, 1544-1554. https: / / doi.org / 10.1145 / 3540250.3558954
[0523]
[27] Dean Jackson. 2014. WebGL Specification. https: / / registry.khronos.org / webgl / specs / 1.0.3 /
[0524]
[28] Shalinka Jayatilleke and Richard Lai. 2018. A systematic review of requirements change management. Inf. Softw. Technol. 93, C (jan 2018), 163-185. https: / / doi.org / 10.1016 / j.infsof.2017.09.004
[0525]
[29] JetBrains s.r.o. 2024a. Code refactoring | IntelliJ IDEA Documentation. https: / / www.jetbrains.com / help / idea / refactoring-source-code.html
[0526]
[30] JetBrains s.r.o. 2024b. IntelliJ IDEA - the Leading Java and Kotlin IDE. https: / / www.jetbrains.com / idea /
[0527]
[31] Michael B. Jones, John Bradley, and Nat Sakimura. 2015. JSON Web Token (JWT). RFC 7519. https: / / doi.org / 10.17487 / RFC7519
[0528]
[32] Josh Junon and Heather Arthur. 2019. color-convert-npm. https: / / www.npmjs.com / package / color-convert
[0529]
[33] Miryung Kim, Vibha Sazawal, David Notkin, and Gail Murphy. 2005. An Empirical Study of Code Clone Genealogies. In Proceedings of the 10th European Software Engineering Conference Held with 13th ACM SIGSOFT International Symposium on Foundations of Software Engineering (Lisbon, Portugal) (ESEC / FSE-13). Association for Computing Machinery, New York, NY, USA, 187-196. https: / / doi.org / 10.1145 / 1081706.1081737
[0530]
[34] Miryung Kim, Thomas Zimmermann, and Nachiappan Nagappan. 2012. A field study of refactoring challenges and benefits. In Proceedings of the ACM SIGSOFT 20th International Symposium on the Foundations of Software Engineering (Cary, North Carolina) (FSE'12). Association for Computing Machinery, New York, NY, USA, Article 50, 11 pages. https: / / doi.org / 10.1145 / 2393596.2393655
[0531]
[35] Bradley W. Kimmel. 2022. Java Modular Image Synthesis Toolkit (JMIST). https: / / github.com / bwkimmel / jmist
[0532]
[36] Jeffrey C. Lagarias. 1985. The 3x+1 Problem and its Generalizations. The American Mathematical Monthly 92, 1 (1985), 3-23. https: / / doi.org / 10.1080 / 00029890.1985.11971528
[0533]
[37] LeetCode. 2024. LeetCode - The World's Leading Online Programming Learning Platform. https: / / leetcode.com /
[0534]
[38] Na Meng, Miryung Kim, and Kathryn S. McKinley. 2013. LASE: Locating and Applying Systematic Edits by Learning from Examples. In Proceedings of the 2013 International Conference on Software Engineering (San Francisco, CA, USA) (ICSE'13). IEEE Press, USA, 502-511.
[0535]
[39] Aaron Meurer, Christopher P. Smith, Mateusz Paprocki, Jeremy Szalay, Trishita Fazli, Steven Perona, Lane Burkett, Brian E. Granger, Kyle Singer, and Natalie Pistunovich. 2016. SymPy: Python library for symbolic mathematics. arXiv preprint arXiv: 1210.5892 Sergey B. Kirpichev, Matthew Rocklin, AMit Kumar, Sergiu Ivanov, Jason K. Moore, Sartaj Singh, Thilina Rathnayake, Sean Vig, Brian E. Granger, Richard P. Muller, Francesco Bonazzi, Harsh Gupta, Shivam Vats, Fredrik Johansson, Fabian Pedregosa, Matthew J. Curry, Andy R. Terrel, Ashutosh Saboo, Isuru Fernando, Sumith Kulal, Robert Cimrman, and Anthony Scopatz. 2017. SymPy: symbolic computing in Python. Computer Science 3 (Jan. 2017), e103. https: / / doi.org / 10.7717 / peerj-cs.103
[0536]
[40] Microsoft. 2024a. Refactoring for different programming languages - Visual Studio (Windows) | Microsoft Learn. https: / / learn.microsoft.com / en-us / visualstudio / ide / refactoring-in-visual-studio
[0537]
[41] Microsoft. 2024b. TypeScript: JavaScript with syntax for types. https: / / www.typescriptlang.org /
[0538]
[42] Microsoft. 2024c. TypeScript refactoring with Visual Studio Code. https: / / code.visualstudio.com / docs / typescript / typescript-refactoring
[0539]
[43] Microsoft. 2024d. Visual Studio Code - Code Editing. Redefined. https: / / code. visualstudio.com /
[0540]
[44] Microsoft. 2024e. Visual Studio: IDE and Code Editor for Software Developers and Teams. https: / / visualstudio.microsoft.com /
[0541]
[45] Anders Miltner, Sumit Gulwani, Vu Le, Alan Leung, Arjun Radhakrishna, Gustavo Soares, Ashish Tiwari, and Abhishek Udupa. 2019. On the Fly Synthesis of Edit Suggestions. Proc. ACM Prograrn. Lang. 3, OOPSLA, Article 143 (oct 2019), 29 pages. https: / / doi.org / 10.1145 / 3360569
[0542]
[46] Mike Mirzayanov. 2024. Codeforces. https: / / codeforces.com /
[0543]
[47] Emerson Murphy-Hill, Chris Parnin, and Andrew P. Black. 2009. How were factor, and how we know it. In Proceedings of the 31st International Conference on Software Engineering (ICSE '09). IEEE Computer Society, USA, 287-297. https: / / doi.org / 10.1109 / ICSE.2009.5070529
[0544]
[48] Hoan Anh Nguyen, Anh Tuan Nguyen, Tung Thanh Nguyen, Tien N. Nguyen, and Hridesh Rajan. 2013. A Study of Repetitiveness of Code Changes in Software Evolution. In Proceedings of the 28th IEEE / ACM International Conference on Automated Software Engineering (Silicon Valley, CA, USA) (ASE'13). IEEE Press, USA, 180-190. https: / / doi.org / 10.1109 / ASE.2013.6693078
[0545]
[49] Ansong Ni, Daniel Ramos, Aidan Z. H. Yang, Lynce, Vasco Manquinho, Ruben Martins, and Claire Le Goues. 2021a. SOAR: A Synthesis Approach for Data Science API Refactoring. In Proceedings of the 43rd International Conference on Software Engineering (Madrid, Spain) (ICSE'21). IEEE Press, USA, 112-124. https: / / doi.org / 10.1109 / ICSE43902.2021.00023
[0546]
[50] Wode Ni, Joshua Sunshine, Vu Le, Sumit Gulwani, and Titus Barik. 2021b. ReCode: A Lightweight Find-and-Replace Interaction in the IDE for Transforming Code by Example. In The 34th Annual ACM Symposium on User Interface Software and Technology (Virtual Event, USA) (UIST'21). Association for Computing Machinery, New York, NY, USA, 258-269. https: / / doi.org / 10.1145 / 3472749.3474748
[0547]
[51] Shayan Noei, Heng Li, Stefanos Georgiou, and Ying Zou. 2023. An Empirical Study of Refactoring Rhythms and Tactics in the Software Development Process. IEEE Transactions on Software Engineering 49, 12 (2023), 5103-5119. https: / / doi.org / 10.1109 / TSE.2023.3326775
[0548]
[52] npm, Inc. 2024. npm - A JavaScript package manager. https: / / www.npmjs.com /
[0549]
[53] André Oliveira, Neves, Alexandre Plastino, Ana Carla Bibiano, Alessandro Garcia, and Leonardo Murta. 2023. Do Code Refactorings Influence the Merge Effort?. In Proceedings of the 45th International Conference on Software Engineering (Melbourne, Victoria, Australia) (ICSE'23). IEEE Press, USA, 134-146. https: / / doi.org / 10.1109 / ICSE48619.2023.00023
[0550]
[54] Shankara Pailoor, Yuepeng Wang, and Dillig. 2024. Semantic Code Refactoring for Abstract Data Types. Proc. ACM Program. Lang. 8, POPL, Article 28 (jan 2024), 32 pages. https: / / doi.org / 10.1145 / 3632870
[0551]
[55] Shankara Pailoor, Yuepeng Wang, Xinyu Wang, and Isil Dillig. 2021. Synthesizing Data Structure Refinements from Integrity Constraints. In Proceedings of the 42nd ACM SIGPLAN International Conference on Programming Language Design and Implementation (Virtual, Canada) (PLDI 2021). Association for Computing Machinery, New York, NY, USA, 574-587. https: / / doi.org / 10.1145 / 3453483.3454063
[0552]
[56] Denis Pushkarev. 2024. core-js-npm. https: / / www.npmjs.com / package / core-js
[0553]
[57] Kia Rahmani, Kartik Nagar, Benjamin Delaware, and Suresh Jagannathan. 2021. Repairing serializability bugs in distributed database programs via automated schema refactoring. In Proceedings of the 42nd ACM SIGPLAN International Conference on Programming Language Design and Implementation (Virtual, Canada) (PLDI 2021). Association for Computing Machinery, New York, NY, USA, 32-47. https: / / doi.org / 10.1145 / 3453483.3454028
[0554]
[58] Veselin Raychev, Max Manu Sridharan, and Martin Vechev. 2013. Refactoring with Synthesis. In Proceedings of the 2013 ACM SIGPLAN International Conference on Object Oriented Programming Systems Languages & Applications (Indianapolis, Indiana, USA) (OOPSLA'13). Association for Computing Machinery, New York, NY, USA, 339-354. https: / / doi.org / 10.1145 / 2509136.2509544
[0555]
[59] W. W. Royce. 1987. Managing the Development of Large Software Systems: Concepts and Techniques. In Proceedings of the 9th International Conference on Software Engineering (Monterey, California, USA) (ICSE'87). IEEE Computer Society Press, Washington, DC, USA, 328-338.
[0556]
[60] Malavika Samak, Deokhwan Kim, and Martin C. Rinard. 2019. Synthesizing Replacement Classes. Proc. ACM Program. Lang. 4, POPL, Article 52 (Dec 2019), 33 pages. https: / / doi.org / 10.1145 / 3371120
[0557]
[61] David Sherret. 2024. ts-morph-npm. https: / / www.npmjs.com / package / ts-morph
[0558]
[62] Vlad Shilov. 2022. colord-npm. https: / / www.npmjs.com / package / colord
[0559]
[63] Danilo Silva, Nikolaos Tsantalis, and Marco Tulio Valente. 2016. Why we refactor? confessions of GitHub contributors. In Proceedings of the 201624th ACM SIGSOFT International Symposium on Foundations of Software Engineering (Seattle, WA, USA) (FSE 2016). Association for Computing Machinery, New York, NY, USA, 858-870. https: / / doi.org / 10.1145 / 2950290.2950305
[0560]
[64] Armando Solar-Lezama. 2008. Program Synthesis By Sketching. Ph.D. Dissertation. EECS Department, University of California, Berkeley. http: / / www2.eecs.berkeley.edu / Pubs / TechRpts / 2008 / EECS-2008-177.html
[0561]
[65] Stack Overflow. 2020. Stack Overflow Developer Survey 2020. https: / / survey.stackoverflow.co / 2020#technology-most-loved-dreaded-and-wanted-languages-loved
[0562]
[66] Stack Overflow. 2023. Stack Overflow Developer Survey 2023. https: / / survey.stackoverflow.co / 2023 / #section-most-popular-technologies-programming-scrip ting-and-markup-languages
[0563]
[67] Mirko Streckenbach and Gregor Snelting. 2004. Refactoring class hierarchies with KABA. In Proceedings of the 19th Annual ACM SIGPLAN Conference on Object-Oriented Programming, Systems, Languages, and Applications (Vancouver, BC, Canada) (OOPSLA '04). Association for Computing Machinery, New York, NY, USA, 315-330. https: / / doi.org / 10.1145 / 1028976.1029003
[0564]
[68] three.js authors. 2024. three-npm. https: / / www.npmjs.com / package / three
[0565]
[69] Sewen Thy, Andreea Costea, Kiran Gopinathan, and Ilya Sergey. 2023. Adventure of a Lifetime: Extract Method Refactoring for Rust. Proc. ACM Program. Lang. 7, OOPSLA2, Article 245 (oct 2023), 28 pages. https: / / doi.org / 10.1145 / 3622821
[0566]
[70] Nikolaos Tsantalis, Ameya Ketkar, and Danny Dig. 2022. RefactoringMiner 2.0. IEEE Transactions on Software Engineering 48, 3 (March 2022), 930-950. https: / / doi.org / 10.1109 / TSE.2020.3007722
[0567]
[71] Jyothi Vedurada and V. Krishna Nandivada. 2018. Identifying refactoring opportunities for replacing type code with subclass and state. Proc. ACM Program. Lang. 2, OOPSLA, Article 138 (oct 2018), 28 pages. https: / / doi.org / 10.1145 / 3276508
[0568]
[72] Virtual Judge. 2023. #47579892 | casheep's solution for [POJ-2406]. https: / / vjudge.net / solution / 47579892
[0569]
[73] Virtual Judge. 2024a. #49296861 | tianci000's solution for [Luogu-P1055]. https: / / vjudge.net / solution / 49296861
[0570]
[74] Virtual Judge. 2024b. #50187490 | A1115522's solution for [UVA-100]. https: / / vjudge.net / solution / 50187490
[0571]
[75] Virtual Judge. 2024c. #50243575 | zakir_ewu's solution for [CodeForces-1619A]. https: / / vjudge.net / solution / 50243575
[0572]
[76] Chengpeng Wang, Peisen Yao, Wensheng Tang, Qingkai Shi, and Charles Zhang. 2022. Complexity-Guided Container Replacement Synthesis. Proc. ACM Program. Lang. 6, OOPSLA 1, Article 68 (apr 2022), 31 pages. https: / / doi.org / 10.1145 / 3527312
[0573]
[77] Yuepeng Wang, James Dong, Rushi Shah, and Isil Dillig. 2019. Synthesizing Database Programs for Schema Refactoring. In Proceedings of the 40th ACM SIGPLAN Conference on Programming Language Design and Implementation (Phoenix, AZ, USA) (PLDI 2019). Association for Computing Machinery, New York, NY, USA, 286-300. https: / / doi.org / 10.1145 / 3314221.3314588
[0574]
[78] Wolfram Research, Inc. 2024. Wolfram|Alpha: Computational Intelligence. https: / / www.wolframalpha.com / Champaign, IL.< / maximumy> < / height> < / x>
Claims
1. A computer-implemented refactoring method for refactoring an original program to obtain a refactored program that preserves functionality of the original program, the original program being based on original variables, the refactored program being based on target variables that are different from the original variables, the refactoring method comprising: receiving the original program, a first mapping specification for converting the original variables or representations based on the original variables to corresponding representations using the target variables, and a second mapping specification for converting the target variables or representations based on the target variables to corresponding representations using the original variables; traversing the original program to perform refactoring operations on at least some original statements of the original program based on the first and second mapping specifications to obtain the refactored program, including: traversing the original program to identify original statements of the original program that involve the original variables; for each original statement that involves the original variables, performing variable conversion on it using the first and second mapping specifications to refactor it to a corresponding refactored statement that involves only the target variables.
2. The reconstitution method of claim 1, wherein, a refactored original statement includes an original expression involving one or more original variables, the refactoring method comprising performing a refactoring operation on the original expression such that the original expression is refactored to a corresponding refactored expression in the refactored program, wherein performing the refactoring operation on the original expression includes performing a variable substitution operation on the original expression according to the first mapping rule to substitute each original variable in the original expression with an expression representing the relevant target variable to obtain the refactored expression.
3. The reconstitution method of claim 2, wherein, the first mapping specification includes a first conversion function for converting an original variable to an expression representing the relevant target variable, and the second mapping specification includes a second conversion function for mapping a target variable to an expression representing the relevant original variable, wherein performing the variable substitution operation on the original expression according to the first mapping rule includes performing the variable substitution operation on the original expression according to the first conversion function to substitute each original variable in the original expression with an expression representing the relevant target variable to obtain the refactored expression.
4. The reconstitution method of claim 1, wherein, a refactored original statement includes an original assignment statement for assigning one or more original expressions to one or more original variables, the refactoring method comprising performing a refactoring operation on the original assignment statement such that the original assignment statement is refactored to a corresponding refactored assignment statement in the refactored program, the refactored assignment statement being for assigning one or more target expressions to one or more target variables associated with the one or more original variables, wherein performing the refactoring operation on the original assignment statement includes: determining, according to the first mapping specification and the one or more original variables assigned in the original assignment statement, the one or more target variables associated with the one or more original variables as target variables assigned in the reconstructed assignment statement; for each target variable assigned, determining a target expression assigned to the target variable in the reconstructed assignment statement, including: obtaining, according to the second mapping specification, a first intermediate expression that converts the target variable assigned to an expression in terms of associated original variables; replacing each original variable in the first intermediate expression with a corresponding original expression assigned to the original variable in the original assignment statement, thereby obtaining a second intermediate expression; performing a variable substitution operation on the second intermediate expression according to the first mapping specification, replacing each original variable in the second intermediate expression with an expression in terms of associated target variables, to obtain the target expression.
5. The reconstitution method of claim 4, wherein, the first mapping specification includes a first conversion function and the second mapping specification includes a second conversion function, the first conversion function being used to convert an original variable to an expression in terms of associated target variables, and the second conversion function being used to map a target variable to an expression in terms of associated original variables, and for each target variable assigned, determining a target expression assigned to the target variable in the reconstructed assignment statement, including: obtaining, according to the second conversion function, a first intermediate expression that converts the target variable assigned to an expression in terms of associated original variables; replacing each original variable in the first intermediate expression with a corresponding original expression assigned to the original variable in the original assignment statement, thereby obtaining a second intermediate expression; performing a variable substitution operation on the second intermediate expression according to the first conversion function, replacing each original variable in the second intermediate expression with an expression in terms of associated target variables, to obtain the target expression.
6. The reconstitution method of claim 3 or 5, wherein, the second conversion function is an inverse function of the first conversion function.
7. The reconstitution method of any one of claims 1-5, wherein, the original statement to be reconstructed includes an original sequential statement including at least two original statements to be executed in sequence, and the reconstructing method includes performing a reconstructing operation on the original sequential statement such that the original sequential statement is reconstructed into a corresponding reconstructed sequential statement in the reconstructed program, the reconstructed sequential statement including at least two reconstructed statements corresponding one-to-one to the at least two original statements, and performing the reconstructing operation on the original sequential statement includes: performing the reconstructing operation on the at least two original statements one by one in the order in which they are to be executed in the original sequential statement.
8. The reconstitution method of any one of claims 1-5, wherein, The reconstructed original statement comprises an original conditional statement comprising at least two original branch statements to be executed in sequence, at least one of the original branch statements comprising an original condition expression, the reconstructing method comprising: performing reconstructing operation on the original conditional statement so that the original conditional statement is reconstructed into a corresponding reconstructed conditional statement in the reconstructed program, the reconstructed conditional statement comprising at least two reconstructed branch statements corresponding to the at least two original branch statements one-to-one, wherein performing reconstructing operation on the original conditional statement comprises:
9. The reconstitution method of any one of claims 1-5, wherein, performing reconstructing operation on the original conditional statement so that the original conditional statement is reconstructed into a corresponding reconstructed conditional statement in the reconstructed program, the reconstructed conditional statement comprising at least two reconstructed branch statements corresponding to the at least two original branch statements one-to-one, wherein performing reconstructing operation on the original conditional statement comprises: performing reconstructing operation on the original conditional statement so that the original conditional statement is reconstructed into a corresponding reconstructed conditional statement in the reconstructed program, the reconstructed conditional statement comprising at least two reconstructed branch statements corresponding to the at least two original branch statements one-to-one, wherein performing reconstructing operation on the original conditional statement comprises:
10. The reconstitution method of any one of claims 1-5, wherein, performing reconstructing operation on the original conditional statement so that the original conditional statement is reconstructed into a corresponding reconstructed conditional statement in the reconstructed program, the reconstructed conditional statement comprising at least two reconstructed branch statements corresponding to the at least two original branch statements one-to-one, wherein performing reconstructing operation on the original conditional statement comprises:
11. The reconstitution method of any one of claims 1-5, further comprising: performing reconstructing operation on the original conditional statement so that the original conditional statement is reconstructed into a corresponding reconstructed conditional statement in the reconstructed program, the reconstructed conditional statement comprising at least two reconstructed branch statements corresponding to the at least two original branch statements one-to-one, wherein performing reconstructing operation on the original conditional statement comprises:
12. The reconstitution method of any one of claims 1-5, further comprising: performing reconstructing operation on the original conditional statement so that the original conditional statement is reconstructed into a corresponding reconstructed conditional statement in the reconstructed program, the reconstructed conditional statement comprising at least two reconstructed branch statements corresponding to the at least two original branch statements one-to-one, wherein performing reconstructing operation on the original conditional statement comprises:
13. The reconstitution method of any one of claims 1-5, wherein, performing reconstructing operation on the original conditional statement so that the original conditional statement is reconstructed into a corresponding reconstructed conditional statement in the reconstructed program, the reconstructed conditional statement comprising at least two reconstructed branch statements corresponding to the at least two original branch statements one-to-one, wherein performing reconstructing operation on the original conditional statement comprises: The first and second mapping specifications comprise conversion functions for classes, so that multiple instance variables of the same class share the same conversion function. The received original program is parsed into an abstract syntax tree by a parsing tool, wherein traversing the original program comprises traversing the abstract syntax tree. The reconstructed program is simplified by a code simplification tool. The original program is written using a programming language that supports object-oriented features and / or structured data types.
14. A reconstructing system comprising a processor configured to execute computer instructions to cause the reconstructing method according to any one of claims 1-13 to be performed.
15. A computer device comprising a memory and a processor, the memory having computer instructions stored thereon, the computer instructions, when executed by the processor, causing the reconstructing method according to any one of claims 1-13 to be performed.
16. A non-transitory computer-readable storage medium having computer instructions stored thereon, the computer instructions, when executed by a processor, causing the reconstructing method according to any one of claims 1-13 to be performed.
Citation Information
Patent Citations
Channeling-machine.
US1030536A
Cited By
Expression evaluation method supporting automatic conversion of measurement units
CN121880373A
