# Incorporating Code Structure and Quality in Deep Code Search
## 3 Code Representation  
Existing code representation methods generally treat a code snippet as three parts: the method name, the API sequence, and the tokens. The API sequence is generated by traversing the AST tree of the code snippet. The API sequence treats the calling of API functions in the code snippet as a chain link. As a result, the API sequence ignores semantics contained in the structure of the code snippet. To overcome this disadvantage, this section introduces a novel code representation method called _program slice_ to preserve structural information when representing code snippets as follows:  
**Method Name Representation:** Method name of each code snippet is divided into a sequence of tokens. These tokens are split according to the corresponding naming conventions such as camelCasing or under_scores. The token sequence is then lowercased. For example, the method name 'Write2 File' will be transformed into token sequence[write, 2, file].  
**Program Slice Representation:** Program slice extends API sequence to preserve structural information of method body [11]. Program slice is generated by two steps: (1) parsing \(AST\) of a code snippet [28; 29] and (2) applying static analysis method on the ASTs [30]. For different statements of code snippet, the processing methods are as follows:  
* For each variable declaration statement, program slice analyzes its corresponding variable type and adds _new_ keyword before the variable type. Taking Golang as an example, _var a string_ is transformed to _new string_.  
* For each condition statement, program slice retains its structural information and _if / else_ keywords. For example, \(if(s_{1})\{s_{2}\}else\{s_{3};\}\) is transformed to \(if(p_{1})\{p_{2};\}else\{p_{3};\}\), where \(p_{1}\), \(p_{2}\), and \(p_{3}\) are the program slices of statements \(s_{1}\), \(s_{2}\), and \(s_{3}\).
* For each loop statement, program slice retains its judgment conditions and cycle body and adds the _for_ keyword. For example, \(for(c_{1};c_{2};c_{3})\{s_{4};\}\) is transformed to \(for(p_{2})\{p_{4};\}\), where \(p_{2}\) and \(p_{4}\) are the program slices of condition \(c_{2}\) and statement \(s_{4}\).
* For each range statement, program slice retains its judgment conditions and cycle body and adds the _range_ keyword. For example, \(for\ i:=range\ c_{1}\{s_{2};\}\) is transformed to \(range(p_{1})\{p_{2};\}\), where \(p_{1}\) and \(p_{2}\) are the program slices of condition \(c_{1}\) and statement \(s_{2}\).
* For each return statement, program slice analyzes its returned variable type and adds _return_ keyword before the variable type. For example, _return_\(10\) is transformed to \(return\ int\).
* For each switch statement, program slice retains its judgment conditions and body and adds the _switch_ keyword. For example, \(switch\ c_{1}\{s_{2}\}\) is transformed to \(switch(p_{1})\{p_{2};\}\), where \(p_{1}\) and \(p_{2}\) are the program slices of condition \(c_{1}\) and statement \(s_{2}\).
* For each call expression, program slice retains only the object type and the called method name. For example, for \(a.b()\) or \(c()\), program slice generates \(A.b\) or \(C\), where \(A\) and \(C\) are the names of class or struct for object \(a\) and \(c\).
* For each nested function calls, program slice uses nested definitions to represent each layer of function calls. For example, \(a.b(c.d(e.f()))\) is transformed to \(A.b(C.d(E.f()))\), where \(A,C,E\) are the name of class or struct for object \(a,c,e\).
* For each operation expression, program slice preserves operation symbols and result types. For example, \(a=1+2\) is converted to \(+int\).  
**Token Representation:** Method body of code snippets are tokenized according to blank space and processed in the same way of method name representation. Duplicated tokens and tokens in a stop word list are removed.  
Figure 2 shows an example of code representation extracted from a Golang method.