Code bad smell detection method fusing graph structure information

By constructing a heterogeneous graph model and integrating multiple graph structure features, the problem that code bad smell detection methods in the existing technology are difficult to fully reflect the complexity of the program, achieving higher detection accuracy and robustness, and improving code quality.

CN120123209APending Publication Date: 2025-06-10HOHAI UNIV +1
View PDF 0 Cites 0 Cited by

Patent Information

Application Number
CN202510191153.7
Authority / Receiving Office
CN · China
Patent Type
Applications(China)
Current Assignee / Owner
Filing Date
2025-02-20
Publication Date
2025-06-10

AI Technical Summary

Technical Problem

Existing code bad smell detection methods are difficult to fully reflect the complex structure and behavioral characteristics of the program, resulting in false positives and missed reactions, and cannot meet the needs of high-quality software development.

Method used

By constructing a heterogeneous graph model, integrating information from control flow graphs, function call graphs and class call graphs, combining multiple graph structure features, and using integrated algorithms for code bad smell detection.

Benefits of technology

It significantly improves the accuracy and robustness of code bad smell detection, reduces false positives and missed reports, enhances the generalization ability of the model, and improves the maintainability and readability of the code.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN120123209A_ABST
    Figure CN120123209A_ABST
Patent Text Reader

Abstract

The invention discloses a code bad smell detection method fusing graph structure information, which comprises the following steps of: firstly, analyzing a source code, constructing an abstract syntax tree, further generating heterogeneous graph models such as a control flow graph, a function call graph and a class call graph on the basis of the abstract syntax tree, and comprehensively describing execution logic, a call relationship and data dependence of a program; secondly, extracting important features, such as basic block structures, function call depth, inheritance complexity and the like, in the graph structures, and performing model training and feature fusion by utilizing a machine learning algorithm; through an integrated learning method, in combination with prediction results of a plurality of classifiers, a final decision is made by adopting a voting mechanism, so that the accuracy and robustness of bad smell detection are improved. Compared with the prior art, the method has the advantages that multi-dimensional information in a potential graph structure in the source code can be fully utilized, the bad smell in the source code can be effectively detected, the code quality analysis precision and efficiency are improved, high expandability is achieved, and the method is suitable for code bad smell detection of various programming languages.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] The present invention belongs to the field of software engineering and relates to a code smell detection method integrating graph structure information. Background Art

[0002] As the complexity of software development continues to increase, code quality has become one of the most important issues in software engineering. Code smells refer to potential problems or bad design patterns in a program that may affect code quality, maintainability, and scalability. Although these smells themselves may not necessarily lead to program errors, they usually mean that there are potential defects in the design or implementation of the program, which may lead to difficulties in later maintenance, performance degradation, or the introduction of difficult-to-find defects. Therefore, timely detection and repair of code smells is of great significance to improving software quality.

[0003] Traditional code smell detection methods mostly rely on rule-based static analysis or simple measurement methods, mainly identifying code smells by analyzing some common problem patterns in the source code (such as overly large classes, overly long methods, duplicated code, etc.). However, these methods are often limited to single-dimensional feature analysis and are difficult to fully reflect the complex structure and behavioral characteristics of the program. Therefore, traditional methods often have certain false positives and false negatives when detecting code smells, which cannot meet the needs of high-quality software development.

[0004] In recent years, with the development of machine learning technology, researchers have begun to try to use graph structures to model different hierarchical structures in programs, such as control flow graphs, data flow graphs, call graphs, etc. These graph structures can more comprehensively describe the logical relationships, data dependencies, and interactions between functions or classes of a program, helping to more accurately capture potential problems in the code. Graph-based analysis methods can better discover the complexity and potential bad smells in the code by converting the various modules, functions, and control flows of the code into graph nodes and their interrelationships.

[0005] Although graph-based code analysis methods have achieved good results in some applications, there are still some shortcomings in current research. For example, existing methods usually only focus on a single graph structure or feature, while ignoring the comprehensive role of multiple graph structures in the program; in addition, how to effectively integrate information from different types of graph structures to improve the accuracy and robustness of code smell detection is still an urgent problem to be solved. Therefore, how to use the multi-level and multi-dimensional information of the graph structure and combine it with advanced machine learning technology to propose a more accurate code smell detection method has become a research hotspot in the current field of code quality detection.

[0006] This patent proposes a code smell detection method that integrates graph structure information. By constructing a heterogeneous graph model and combining multiple graph structure features, it can more comprehensively and accurately identify code smells in the program, thereby providing more scientific and effective technical support for software quality analysis and maintenance. Summary of the invention

[0007] The purpose of the present invention is to make up for the deficiencies and defects of the prior art, and to provide a code smell detection method that integrates graph structure information. By constructing a heterogeneous graph model and combining multiple graph structure features, the code smell in the program can be comprehensively and accurately identified.

[0008] The above purpose is achieved through the following technical solutions:

[0009] A code smell detection method integrating graph structure information, the method comprising the following steps:

[0010] Step 1: Code parsing and abstract syntax tree construction: Input the source code file to be analyzed, parse the code using the corresponding parsing tool according to the programming language used in the source code, and construct the abstract syntax tree AST;

[0011] Step 2: Heterogeneous network model construction: Based on the AST constructed in step 1, further analyze the execution logic of the code, construct a control flow graph to capture the key execution path of the code; generate function call graphs and class call graphs to analyze the calling relationship, class inheritance relationship, and method overloading between functions; integrate different dependency information of control flow, data flow, and calling relationship to construct a heterogeneous network model, which contains different types of nodes and different types of edges;

[0012] Step 3: Feature extraction based on multi-network models: In the control flow graph, the branch complexity is calculated to measure the cyclomatic complexity of the code. By analyzing the loop nesting level, the depth of the loop structure in the code is evaluated to identify deep nesting problems that affect code readability and execution efficiency. In the function call graph, the function call depth is extracted to evaluate the dependencies between code modules. In the class call graph, the class inheritance complexity is calculated to determine the degree of close association between modules and identify the increased difficulty of code maintenance due to excessive inheritance.

[0013] Step 4: Feature fusion of multi-dimensional graph structure information: Standardize features from different sources to ensure the consistency of data distribution and avoid affecting model training due to differences in the numerical scales of different features. Use feature splicing methods to splice features of different dimensions of control flow and call relationships to form a unified high-dimensional vector representation, maximizing the retention of information from different graph structures.

[0014] Step 5: Code smell classification based on ensemble algorithm: Train different types of features, use the stacked ensemble method to use the prediction results of multiple models as new input features, train a stronger meta-classifier, and thus improve the generalization ability of the model; combine the prediction results of multiple models, and use a voting mechanism to determine the final code smell detection result.

[0015] Furthermore, the parsing tool in step 1 includes an ast module in Python language, an acorn module in JavaScript language, or an AST parser in C / C++ language.

[0016] Furthermore, the process of step 2 specifically includes the following steps:

[0017] Step 2.1: Generate a control flow graph: Extract basic blocks from AST. Basic blocks are a set of code snippets that are executed sequentially and do not contain jump instructions. Parse control flow statements, which include conditional branches if-else / switch-case, loop structures for / while, and exception handling try-catch-finally, and establish corresponding branch relationships; establish sequential edges between statements that are executed sequentially; establish conditional jump edges between different branches of if-else statements; establish loop edges between the loop bodies and loop conditions of while and for loops to indicate the execution path of the loop; break and continue statements are connected to the corresponding control flow target positions; use all code blocks as nodes and control flow dependencies as directed edges to form a complete control flow graph;

[0018] Step 2.2: Generate function call graph: traverse AST, extract all function declarations and their parameters and return value information; parse function call relationships, find function call statements in AST, and determine the mapping relationship between callers and callees; build call dependency edges. If function A calls function B, then build a call edge from A to B in the call graph; if A is a recursive function, then build a self-loop edge; if B is a virtual function C++ / Java, then further parse the class inheritance relationship to determine the specific call target;

[0019] Step 2.3: Generate class call graph: traverse AST, extract class definition and its attributes and method information, build inheritance relationship, parse class A extends B or class A: public B, establish inheritance edge in class call graph, indicating that A inherits from B; parse method call, parse the calling relationship of this.method(), super.method() and object.method(), and establish method call edge; if the method is overloaded or overridden, it is necessary to parse virtual function table or runtime polymorphism mechanism to accurately match the calling target; analyze inter-class dependency, if class A holds the object of class B as a member variable, establish combination edge; if class A depends on class B, establish dependency edge;

[0020] Step 2.4: Construct a heterogeneous network model: nodes include different types of code entities such as code basic blocks, functions, classes, and variables; edges include control flow, call relationships, and inheritance relationships; use adjacency matrices to uniformly represent the connection relationships of different graphs.

[0021] Furthermore, the process of step 3 specifically includes the following steps:

[0022] Step 3.1: Control flow graph feature extraction:

[0023] First, the cyclomatic complexity F of the control flow graph c It is an indicator to measure the logic complexity of the code. It calculates the number of independent paths in the program and is used to estimate the number of test cases for the code. It reflects the complexity of the program. c The formula is:

[0024] F c =E-N+2P

[0025] Where E is the number of edges in the graph, N is the number of nodes in the graph, and P is the number of connected components in the program;

[0026] Secondly, by analyzing the loop nesting level in the control flow graph, the depth F of the loop in the code is calculated. cd , thereby identifying deep nesting problems that may affect code readability and execution efficiency, and calculating the number of layers of loop body nesting F cl Evaluate the complexity of nesting and identify possible efficiency bottlenecks by analyzing the conditional judgment and loop body of each loop;

[0027] Step 3.2: Function call graph feature extraction: Calculate the function call depth F fd , which refers to the nesting level of the function in the calling process, is an important indicator for measuring the dependency relationship between functions in the program. For any function f, its function call depth F fd Calculated by the following formula:

[0028]

[0029] Among them, F fd represents the calling depth of function f, children(f) represents the set of functions directly called by function f, and F fd (g) represents the calling depth of sub-function g, and 1 represents the calling depth of the current function;

[0030] Step 3.3: Class call graph feature extraction: inheritance complexity F hc It is measured by the inheritance depth and inheritance width of the class. The inheritance depth refers to the number of levels from a class to its furthest ancestor class. The deeper the inheritance level, the more difficult the code is to understand and extend. The calculation formula is defined as:

[0031] F hd (f) = max(Depth(f))

[0032] Among them, F hd (f) represents the inheritance depth of class f, and Depth(f) represents the maximum number of levels between class f and the root class;

[0033] Inheritance width refers to the number of parent classes that a class directly inherits, indicating the multiple inheritance of the class. The larger the inheritance width, the more complex the coupling relationship between the class and multiple other classes. The calculation formula is defined as:

[0034] F hw (f)=|parents(f)|

[0035] Among them, F hw (f) represents the inheritance width of class f, parents(f) represents the set of parent classes directly inherited by class f, and |·| represents the number of elements in the calculated set;

[0036] Inheritance complexity F hc The inheritance complexity of a class is measured by combining inheritance depth and inheritance width. The inheritance complexity of a class is calculated by the weighted sum of its inheritance depth and width:

[0037] F hc =αF hd (f)+βF hw (f)

[0038] Among them, F hd (f) represents the inheritance depth of class f, F hw (f) represents the inheritance width of class f, α and β are weight coefficients used to adjust the influence of inheritance depth and inheritance width on complexity;

[0039] Step 3.4: Heterogeneous graph feature extraction: In a heterogeneous graph, the diameter of the graph, i.e. the maximum shortest path length F gd Reflects the maximum distance between nodes in the system, the density of the graph F ge Represents the ratio of the actual number of edges in the graph to the maximum possible number of edges, the connectivity of the graph F gl It is estimated that there are fewer paths between some nodes.

[0040] Furthermore, the process of step 4 specifically includes the following steps:

[0041] Step 4.1: Use z-score standardization to process features from different sources to ensure that the features have the same numerical scale and distribution, so as to avoid some features having too large or too small impact on model training due to too large or too small numerical range. The specific formula is as follows:

[0042]

[0043] Where x is the original eigenvalue, including the cyclomatic complexity F c , the depth of the loop in the code F cd , the number of levels of loop body nesting F cl , function call depth F hd , class inheritance width F hw , class inheritance depth F fd , inheritance complexity F hc , the connectivity of the graph f gl , μ is the mean of the original feature, σ is the standard deviation of the original feature, and x′ is the standardized feature value;

[0044] Step 4.2: After feature normalization, it is necessary to maximize the retention of information contained in each graph structure and concatenate features from different sources into a unified high-dimensional feature vector:

[0045]

[0046] in, represents the vector concatenation operation, and F is the high-dimensional feature vector after concatenation.

[0047] Furthermore, the process of step 5 specifically includes the following steps:

[0048] Step 5.1: Train the basic classifier. Use multiple basic classifiers to train the features. Different classifiers are represented as C 1 ,C 2 ,…,C n , for each base classifier C i , and its training process is expressed by the following formula:

[0049] Ci =Train(F,y,θ i )

[0050] Where F is the input feature matrix, y is the label vector, and θ i is the classifier C i Parameters of each classifier C i Will make a prediction for the input feature F

[0051] Step 5.2: Each base classifier C i A prediction result will be generated Concatenate these prediction results into a new feature matrix:

[0052]

[0053] Use the new feature vector Z to train a stacked classification model C o , Stacked classification model, the training process of the stacked classification model is expressed as:

[0054] C o = Train(Z,y,θ o )

[0055] Among them, Z is the input feature matrix, y is the label vector, and θ o is a stacked classification model C o Parameters;

[0056] Step 5.3: After training the stacked classification model, use multiple base classifiers and the stacked classification model for prediction. Each base classifier C i Will provide a prediction result for the input feature F Stacked Classification Model C o The final prediction results will also be provided For each input sample F, the prediction results of the base classifiers are combined through a voting mechanism:

[0057] If it is a binary classification problem, the voting mechanism determines the final prediction label by majority rule:

[0058]

[0059] Among them, if The value of 1 indicates that the program is predicted to contain code smell. The value of 0 indicates that the program is predicted to have no code smell. The final predicted label y final The label predicted by most classifiers.

[0060] Beneficial effects: Compared with the prior art, the present invention adopts the above technical solution and has the following advantages:

[0061] By integrating multiple graph structure information, such as control flow graphs, function call graphs, and class call graphs, the complexity and potential bad smells of the program are fully captured, avoiding the shortcomings of traditional methods that are limited to single feature analysis. Through refined feature extraction and stacking integration methods, the present invention significantly improves the accuracy and robustness of bad smell detection, and at the same time enhances the generalization ability of the model by integrating model detection results through a voting mechanism. This method has good scalability, can adapt to multiple programming languages, and effectively improves the maintainability and readability of the code, providing more accurate and scientific technical support for software quality analysis. BRIEF DESCRIPTION OF THE DRAWINGS

[0062] Figure 1 It is a flow chart of the method of the present invention.

[0063] Figure 2 It is a model diagram of a code smell detection method integrating graph structure information of the present invention. DETAILED DESCRIPTION

[0064] The technical solution of the present invention is described in detail below.

[0065] The following is only one embodiment of the present invention. The present invention may have other embodiments. Without departing from the spirit and essence of the present invention, those skilled in the art may make various corresponding changes and modifications based on the present invention. These corresponding changes and modifications should all fall within the scope of protection of the claims attached to the present invention.

[0066] A code odor detection method integrating graph structure information of the present invention comprises the following steps:

[0067] Step 1: Code parsing and abstract syntax tree construction: Input the source code file to be analyzed, parse the code using the corresponding parsing tool according to the programming language used in the source code, and construct the abstract syntax tree AST;

[0068] Step 2, heterogeneous network model construction: Based on the AST constructed in step 1, further analyze the execution logic of the code, construct a control flow graph to capture the key execution path of the code; generate function call graphs and class call graphs to analyze the calling relationships, class inheritance relationships, and method overloading between functions; integrate different dependency information of control flow, data flow, and calling relationships to build a heterogeneous network model, which contains different types of nodes (such as variables, functions, classes) and different types of edges (such as control flow, data flow, calling relationships, etc.). This network model can fully retain the hierarchical structure and logical relationships of the code, and provide efficient and accurate graph structure expression for the detection of code smell;

[0069] Step 3: Feature extraction based on multi-network models: In the control flow graph, the branch complexity is calculated to measure the cyclomatic complexity of the code. By analyzing the loop nesting level, the depth of the loop structure in the code is evaluated to identify deep nesting problems that affect code readability and execution efficiency. In the function call graph, the function call depth is extracted to evaluate the dependencies between code modules. In the class call graph, the class inheritance complexity is calculated to determine the degree of close association between modules and identify the increased difficulty of code maintenance due to excessive inheritance.

[0070] Step 4: Feature fusion of multi-dimensional graph structure information: Standardize features from different sources to ensure the consistency of data distribution and avoid affecting model training due to differences in the numerical scales of different features. Use feature splicing methods to splice features of different dimensions of control flow and call relationships to form a unified high-dimensional vector representation, maximizing the retention of information from different graph structures.

[0071] Step 5: Code smell classification based on integrated algorithms: Use classifiers such as random forest, support vector machine, naive Bayes, and logistic regression to train different types of features. Through the stacking integration method, the prediction results of multiple models are used as new input features to train a stronger meta-classifier, thereby improving the generalization ability of the model; the prediction results of multiple models are combined, and a voting mechanism is used to determine the final smell detection result. Through a multi-level integration strategy, the accuracy and robustness of detection are effectively improved, and false positives and false negatives are reduced, thereby providing more accurate support for code quality analysis.

[0072] In this embodiment, the parsing tool in step 1 includes the ast module in Python language, the acorn module in JavaScript language, or the AST parser in C / C++ language.

[0073] In this embodiment, the process of step 2 specifically includes the following steps:

[0074] Step 2.1: Generate a control flow graph: Extract basic blocks from AST. Basic blocks are a set of code snippets that are executed sequentially and do not contain jump instructions, such as continuous assignment statements, expression evaluations, etc. Parse control flow statements, which include conditional branches if-else / switch-case, loop structures for / while, and exception handling try-catch-finally, and establish corresponding branch relationships; establish sequential edges between statements that are executed sequentially; establish conditional jump edges between different branches of if-else statements; establish loop edges between the loop body and loop condition of while and for loops to indicate the execution path of the loop; break and continue statements are connected to the corresponding control flow target positions; use all code blocks as nodes and control flow dependencies as directed edges to form a complete control flow graph;

[0075] Step 2.2: Generate function call graph: traverse AST, extract all function declarations and their parameters and return value information; parse function call relationships, find function call statements in AST, and determine the mapping relationship between callers and callees; build call dependency edges. If function A calls function B, then build a call edge from A to B in the call graph; if A is a recursive function, then build a self-loop edge; if B is a virtual function C++ / Java, then further parse the class inheritance relationship to determine the specific call target;

[0076] Step 2.3: Generate class call graph: traverse AST, extract class definition and its attributes and method information, build inheritance relationship, parse class A extends B or class A: public B, establish inheritance edge in class call graph, indicating that A inherits from B; parse method call, parse the calling relationship of this.method(), super.method() and object.method(), and establish method call edge; if the method is overloaded or overridden, it is necessary to parse virtual function table or runtime polymorphism mechanism to accurately match the calling target; analyze inter-class dependency, if class A holds the object of class B as a member variable, establish combination edge; if class A depends on class B (for example, as a parameter or return value type), establish dependency edge;

[0077] Step 2.4: Construct a heterogeneous network model: nodes include different types of code entities such as code basic blocks, functions, classes, and variables; edges include control flow, call relationships, and inheritance relationships; use adjacency matrices to uniformly represent the connection relationships of different graphs.

[0078] In this embodiment, the process of step 3 specifically includes the following steps:

[0079] Step 3.1: Control flow graph feature extraction: First, the cyclomatic complexity F of the control flow graph c It is an indicator to measure the logic complexity of the code. It calculates the number of independent paths in the program and is used to estimate the number of test cases for the code. It reflects the complexity of the program. c The formula is:

[0080] F c =E-N+2P

[0081] Where E is the number of edges in the graph, N is the number of nodes in the graph, and P is the number of connected components in the program. The higher the complexity, the more complex the logical structure of the code is, and the more difficult it is to maintain and understand. Highly complex code often means high maintenance costs and is more prone to errors. Secondly, the loop structure often affects the readability and execution efficiency of the program. By analyzing the loop nesting level in the control flow graph, the depth F of the loop in the code is calculated.cd , thereby identifying deep nesting problems that may affect code readability and execution efficiency, and calculating the number of layers of loop body nesting F cl Evaluate the complexity of nesting and identify possible efficiency bottlenecks by analyzing the conditional judgment and loop body of each loop;

[0082] Step 3.2: Function call graph feature extraction: Calculate the function call depth F fd , which refers to the nesting level of a function during the calling process, is an important indicator for measuring the dependencies between functions in a program. Function call depth not only considers the direct calling relationship of a function, but also includes indirect calling relationships, such as recursive calls or multi-layer function calls. By calculating the function call depth, we can evaluate the modularity, maintainability, and coupling between functions of a program. Assume that each function in the function call graph has several call paths, which can be divided into direct calls and indirect calls. For any function f, its function call depth F fd Calculated by the following formula:

[0083]

[0084] Among them, F fd represents the calling depth of function f, children(f) represents the set of functions directly called by function f, and F fd (g) represents the calling depth of sub-function g, and 1 represents the calling depth of the current function;

[0085] Step 3.3: Class call graph feature extraction: inheritance complexity F hc It is measured by the inheritance depth and inheritance width of the class. The inheritance depth refers to the number of levels from a class to its furthest ancestor class. The deeper the inheritance level, the more difficult the code is to understand and extend. The calculation formula is defined as:

[0086] F hd (f) = max(Depth(f))

[0087] Among them, F hd (f) represents the inheritance depth of class f, and Depth(f) represents the maximum number of levels between class f and the root class (usually the base class or the top-level parent class);

[0088] Inheritance width refers to the number of parent classes that a class directly inherits from, indicating the multiple inheritance of the class. The larger the inheritance width, the more complex the coupling relationship between the class and multiple other classes. Especially in multiple inheritance, the properties and methods of multiple parent classes may lead to conflicts or difficult-to-manage dependencies. The calculation formula is defined as:

[0089] F hw (f)=|parents(f)|

[0090] Among them, F hw (f) represents the inheritance width of class f, parents(f) represents the set of parent classes directly inherited by class f, and |·| represents the number of elements in the calculated set;

[0091] Inheritance complexity F hc The inheritance complexity of a class is measured by combining inheritance depth and inheritance width. The inheritance complexity of a class is calculated by the weighted sum of its inheritance depth and width:

[0092] F hc =αF hd (f)+βF hw (f)

[0093] Among them, F hd (f) represents the inheritance depth of class f, F hw (f) represents the inheritance width of class f, α and β are weight coefficients used to adjust the influence of inheritance depth and inheritance width on complexity. Usually α and β can be set to 0.5 and 0.5, and can be set according to specific needs. The larger the value, the greater the influence of the feature on complexity.

[0094] Step 3.4: Heterogeneous graph feature extraction: In a heterogeneous graph, the diameter of the graph, i.e. the maximum shortest path length F gd Reflects the maximum distance between nodes in the system. A larger diameter may mean a higher degree of coupling between modules and poor code scalability. ge It represents the ratio of the actual number of edges in the graph to the maximum possible number of edges. A graph with a higher density usually indicates that there are a large number of tightly coupled modules in the system and the code complexity is high. gl Estimating that fewer paths between certain nodes may mean that there is less coupling between these modules and the code may follow a better modular design.

[0095] In this embodiment, the process of step 4 specifically includes the following steps:

[0096] Step 4.1: Use z-score standardization to process features from different sources to ensure that the features have the same numerical scale and distribution, so as to avoid some features having too large or too small impact on model training due to too large or too small numerical range. The specific formula is as follows:

[0097]

[0098] Where x is the original eigenvalue, including the cyclomatic complexity F c , the depth of the loop in the code F cd , the number of levels of loop body nesting F cl, function call depth F hd , class inheritance width F hw , class inheritance depth F fd , inheritance complexity F hc , the connectivity of the graph F gl , μ is the mean of the original feature, σ is the standard deviation of the original feature, and x′ is the standardized feature value;

[0099] Step 4.2: After feature normalization, it is necessary to maximize the retention of information contained in each graph structure and concatenate features from different sources into a unified high-dimensional feature vector:

[0100]

[0101] in, represents the vector concatenation operation, F c 、F cd 、F cl 、F hd 、F hw 、F fd 、F hc 、F gl etc. are feature vectors from different sources, and F is the concatenated high-dimensional feature vector.

[0102] In this embodiment, the process of step 5 specifically includes the following steps:

[0103] Step 5.1: Train the basic classifier. Use a variety of basic classifiers (random forest, support vector machine, naive Bayes, logistic regression, etc.) to train the features. Different classifiers are represented by C 1 ,C 2 ,…,C n , for each base classifier C i , and its training process is expressed by the following formula:

[0104] C i =Train(F,y,θ i )

[0105] Where F is the input feature matrix, y is the label vector, and θ i is the classifier C i The parameters of each classifier C (such as the tree structure of random forest, the kernel function of support vector machine, etc.) i Will make a prediction for the input feature F

[0106] Step 5.2: Each base classifier C i A prediction result will be generated Concatenate these prediction results into a new feature matrix:

[0107]

[0108] Use the new feature vector Z to train a stacked classification model C o The stacked classification model can be a model such as logistic regression or support vector machine. Here, the support vector machine model is used. The training process of the stacked classification model is expressed as:

[0109] C o = Train(Z,y,θ o )

[0110] Among them, Z is the input feature matrix, y is the label vector, and θ o is a stacked classification model C o Parameters;

[0111] Step 5.3: After training the stacked classification model, use multiple base classifiers and the stacked classification model for prediction. Each base classifier C i Will provide a prediction result for the input feature F Stacked Classification Model C o The final prediction results will also be provided For each input sample F, the prediction results of the base classifiers are combined through a voting mechanism:

[0112] If it is a binary classification problem, the voting mechanism determines the final prediction label by majority rule:

[0113]

[0114] Among them, if The value of 1 indicates that the program is predicted to contain code smell. The value of 0 indicates that the program is predicted to have no code smell. The final predicted label y final The label predicted by most classifiers.

[0115] Four types of code smell data were selected from the Python source code public code smell dataset (address: https: / / github.com / chenzhifei731 / Pysmell) for preliminary experiments. The experimental results are shown in Table 1:

[0116] Table 1. Comparison of experimental results of the method of the present invention with regression model and convolutional neural network (CNN)

[0117]

[0118]

[0119] Experiments show that the method of the present invention performs well in the code smell detection task on this dataset, especially in "Long Parameter List" and "Long Scope Chain", significantly surpassing logistic regression and convolutional neural network (CNN), showing strong generalization ability. In contrast, CNN performs very poorly in these two types of tasks. Although logistic regression performs well in "Long Method", it is not stable enough in other tasks. The method of the present invention has achieved excellent levels of precision and recall in most tasks, and is generally a more efficient code smell detection method.

Claims

1. A code smell detection method integrating graph structure information, characterized in that: The method comprises the following steps: Step 1: Code parsing and abstract syntax tree construction: Input the source code file to be analyzed, parse the code using the corresponding parsing tool according to the programming language used in the source code, and construct the abstract syntax tree AST; Step 2: Heterogeneous network model construction: Based on the AST constructed in step 1, further analyze the execution logic of the code, construct a control flow graph to capture the key execution path of the code; generate function call graphs and class call graphs to analyze the calling relationship, class inheritance relationship, and method overloading between functions; integrate different dependency information of control flow, data flow, and calling relationship to construct a heterogeneous network model, which contains different types of nodes and different types of edges; Step 3: Feature extraction based on multi-network model: Calculate branch complexity in the control flow graph to measure the cyclomatic complexity of the code. By analyzing the loop nesting level, evaluate the depth of the loop structure in the code and identify deep nesting problems that affect code readability and execution efficiency. In the function call graph, extract the function call depth to evaluate the dependencies between code modules; In the class call graph, calculate the class inheritance complexity, determine the close relationship between modules, and identify the increased difficulty of code maintenance due to excessive inheritance; Step 4: Feature fusion of multi-dimensional graph structure information: Standardize the features from different sources, and then use the feature splicing method to splice the features of different dimensions of control flow and call relationship to form a unified high-dimensional vector representation; Step 5: Code smell classification based on ensemble algorithm: Train different types of features, use the stacking ensemble method to take the prediction results of multiple models as new input features, and train a stronger meta-classifier; combine the prediction results of multiple models, and use a voting mechanism to determine the final code smell detection result.

2. The method for detecting code odor by integrating graph structure information according to claim 1, characterized in that: The parsing tool in step 1 includes the ast module in Python language, the acorn module in JavaScript language, or the AST parser in C / C++ language.

3. The code odor detection method integrating graph structure information according to claim 1 is characterized in that: The process of step 2 specifically includes the following steps: Step 2.1: Generate a control flow graph: Extract basic blocks from AST. Basic blocks are a set of code snippets that are executed sequentially and do not contain jump instructions. Parse control flow statements, which include conditional branches if-else / switch-case, loop structures for / while, and exception handling try-catch-finally, and establish corresponding branch relationships; establish sequential edges between statements that are executed sequentially; establish conditional jump edges between different branches of if-else statements; establish loop edges between the loop bodies and loop conditions of while and for loops to indicate the execution path of the loop; break and continue statements are connected to the corresponding control flow target positions; use all code blocks as nodes and control flow dependencies as directed edges to form a complete control flow graph; Step 2.2: Generate function call graph: traverse AST, extract all function declarations and their parameters and return value information; parse function call relationships, find function call statements in AST, and determine the mapping relationship between callers and callees; build call dependency edges. If function A calls function B, then build a call edge from A to B in the call graph; if A is a recursive function, then build a self-loop edge; if B is a virtual function C++ / Java, then further parse the class inheritance relationship to determine the specific call target; Step 2.3: Generate class call graph: traverse AST, extract class definition and its attributes and method information, build inheritance relationship, parse class A extends B or class A: public B, establish inheritance edge in class call graph, indicating that A inherits from B; parse method call, parse the calling relationship of this.method(), super.method() and object.method(), and establish method call edge; if the method is overloaded or overridden, it is necessary to parse virtual function table or runtime polymorphism mechanism to accurately match the calling target; analyze inter-class dependency, if class A holds the object of class B as a member variable, establish combination edge; if class A depends on class B, establish dependency edge; Step 2.4: Construct a heterogeneous network model: nodes include different types of code entities such as code basic blocks, functions, classes, and variables; edges include control flow, call relationships, and inheritance relationships; use adjacency matrices to uniformly represent the connection relationships of different graphs.

4. The code odor detection method integrating graph structure information according to claim 1 is characterized in that: The process of step 3 specifically includes the following steps: Step 3.1: Control flow graph feature extraction: First, the cyclomatic complexity F of the control flow graph c It is an indicator to measure the logic complexity of the code. It calculates the number of independent paths in the program and is used to estimate the number of test cases for the code. It reflects the complexity of the program. c The formula is: F c =E-N+2P Where E is the number of edges in the graph, N is the number of nodes in the graph, and P is the number of connected components in the program; Secondly, by analyzing the loop nesting level in the control flow graph, the depth F of the loop in the code is calculated cd , thereby identifying deep nesting problems that may affect code readability and execution efficiency, and calculating the number of layers of loop body nesting F cl Evaluate the complexity of nesting and identify possible efficiency bottlenecks by analyzing the conditional judgment and loop body of each loop; Step 3.2: Function call graph feature extraction: Calculate the function call depth F fd , which refers to the nesting level of the function in the calling process, is an important indicator for measuring the dependency relationship between functions in the program. For any function f, its function call depth F fd Calculated by the following formula: Among them, F fd represents the calling depth of function f, children(f) represents the set of functions directly called by function f, and F fd (g) represents the calling depth of sub-function g, and 1 represents the calling depth of the current function; Step 3.3: Class call graph feature extraction: inheritance complexity F hc It is measured by the inheritance depth and inheritance width of the class. The inheritance depth refers to the number of levels from a class to its furthest ancestor class. The deeper the inheritance level, the more difficult the code is to understand and extend. The calculation formula is defined as: F hd (f)=max(Depth(f)) Among them, F hd (f) represents the inheritance depth of class f, and Depth(f) represents the maximum number of levels between class f and the root class; Inheritance width refers to the number of parent classes that a class directly inherits, indicating the multiple inheritance of the class. The larger the inheritance width, the more complex the coupling relationship between the class and multiple other classes. The calculation formula is defined as: F hw (f)=|parents(f)| Among them, F hw (f) represents the inheritance width of class f, parents(f) represents the set of parent classes directly inherited by class f, and |·| represents the number of elements in the calculated set; Inheritance complexity F hc The inheritance complexity of a class is measured by combining inheritance depth and inheritance width. The inheritance complexity of a class is calculated by the weighted sum of its inheritance depth and width: F hc =αF hd (f)+βF hw (f) Among them, F hd (f) represents the inheritance depth of class f, F hw (f) represents the inheritance width of class f, α and β are weight coefficients used to adjust the influence of inheritance depth and inheritance width on complexity; Step 3.4: Heterogeneous graph feature extraction: In a heterogeneous graph, the diameter of the graph, i.e. the maximum shortest path length F gd Reflects the maximum distance between nodes in the system, the density of the graph F ge Represents the ratio of the actual number of edges in the graph to the maximum possible number of edges, the connectivity of the graph F gl It is estimated that there are fewer paths between some nodes.

5. The method for detecting code odor by integrating graph structure information according to claim 4, characterized in that: The process of step 4 specifically includes the following steps: Step 4.1: Use z-score standardization to process features from different sources to ensure that the features have the same numerical scale and distribution, so as to avoid some features having too large or too small impact on model training due to too large or too small numerical range. The specific formula is as follows: Where x is the original eigenvalue, including the cyclomatic complexity F c , the depth of the loop in the code F cd , the number of levels of loop body nesting F cl , function call depth F hd , class inheritance width F hw , class inheritance depth F fd , inheritance complexity F hc , the connectivity of the graph F gl , μ is the mean of the original feature, σ is the standard deviation of the original feature, x ′ is the standardized eigenvalue; Step 4.2: After feature normalization, it is necessary to maximize the retention of information contained in each graph structure and concatenate features from different sources into a unified high-dimensional feature vector: in, represents the vector concatenation operation, and F is the high-dimensional feature vector after concatenation.

6. The method for detecting code odor by integrating graph structure information according to claim 1, characterized in that: The process of step 5 specifically includes the following steps: Step 5.1: Train the basic classifier. Use multiple basic classifiers to train the features. Different classifiers are represented as C1, C2, ..., C n , for each base classifier C i , and its training process is expressed by the following formula: C i =Train(F,y,θ i ) Where F is the input feature matrix, y is the label vector, and θ i is the classifier C i Parameters of each classifier C i Will make a prediction for the input feature F Step 5.2: Each base classifier C i A prediction result will be generated Concatenate these prediction results into a new feature matrix: Use the new feature vector Z to train a stacked classification model C o , Stacked classification model, the training process of the stacked classification model is expressed as: C o =Train(Z,y,θ o ) Among them, Z is the input feature matrix, y is the label vector, and θ o is a stacked classification model C o Parameters; Step 5.3: After training the stacked classification model, use multiple base classifiers and the stacked classification model for prediction. Each base classifier C i Will provide a prediction result for the input feature F Stacked Classification Model C o The final prediction results will also be provided For each input sample F, the prediction results of the base classifiers are combined through a voting mechanism: If it is a binary classification problem, the voting mechanism determines the final prediction label by majority rule: Among them, if The value of 1 indicates that the program is predicted to contain code smell. The value of 0 indicates that the program is predicted to have no code smell. The final predicted label y final The label predicted by most classifiers.