Let’s create a code naming tool
Are you still struggling with code naming?
So how to better name it? Is there a good tool to support our naming? After searching the Internet, I didn't find anything satisfactory, so I had plenty of food and clothing by myself, https://jadepeng.gitee.io/code-naming-tool/ 。
Usage: after opening the web page, enter the Chinese name in the Chinese input box, and then press enter. You can also directly enter English in the English input box to search for candidates.
Existing tools
unbug. github. Io/codelf/ provides a choice. The author first calls Youdao, Baidu and other translations, then calls searchcode search code to extract variable names from the search code.
The interface is cool, but the quality of the recommended variable names is uneven and loses its reference significance.
New ideas
We often say that we can learn from history and change our thinking. We can absorb their naming experience from excellent open source libraries and see how they are named for our reference.
Implementation ideas: 1 Read variables, methods and class names from spring, Apache and other code libraries 2 Match candidate names according to keywords 3 Candidate result sorting
Get excellent naming
To get the naming, the first thought is to read the code base. You need to download the code first, and then parse it -- the workload is huge, pass.
How to do that? From another angle, it can be realized through java reflection.
First add a secondary Library:
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.12</version>
</dependency>
Then initialize reflections. Filterbuilder can be used to filter class libraries. We set "org", "javax", "com" and "IO", which basically encapsulate the main open source class libraries, such as spring, Apache, etc
List<ClassLoader> classLoadersList = new LinkedList<ClassLoader>();
classLoadersList.add(ClasspathHelper.contextClassLoader());
classLoadersList.add(ClasspathHelper.staticClassLoader());
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setScanners(new SubTypesScanner(false),new ResourcesScanner())
.setUrls(ClasspathHelper.forClassLoader(classLoadersList.toArray(new ClassLoader[0])))
.filterInputsBy(new FilterBuilder().includePackage("org","io")));
You can then use reflections getSubTypesOf(Object.class); To get the relevant classes. Note that we initialize a map < string, integer > name2count = new HashMap < string, integer > (); Used to store code names and corresponding occurrences.
Set<Class<? extends Object>> allClasses =
reflections.getSubTypesOf(Object.class);
Map<String,Integer>();
for (Class<?> clazz : allClasses) {
System.out.println(clazz.getName());
try {
appendToNameMap(name2count,clazz.getSimpleName());
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
String name = field.getName();
appendToNameMap(name2count,name);
}
Method[] methods = clazz.getmethods();
for (Method method : methods) {
String name = method.getName();
appendToNameMap(name2count,name);
// parameters
Parameter[] parameters = method.getParameters();
for (Parameter param : parameters) {
name = param.getName();
appendToNameMap(name2count,name);
}
}
}catch(Throwable t)
{ }
Where appendtonamemap:
private static void appendToNameMap(Map<String,Integer> name2count,String name) {
// filter
if(name.contains("-") || name.contains("_")|| name.contains("$")){
return;
}
if (!name2count.containsKey(name)) {
name2count.put(name,1);
} else {
name2count.put(name,name2count.get(name) +1);
}
}
Finally, the results are stored in a file as our resources.
FileUtils.writeAllText(JSON.toJSONString(name2count),new File("name2count.txt"));
Yes https://gitee.com/jadepeng/code-naming-tool/blob/master/vars.js View the results.
Naming recommendation
Name recommendation or follow, translate first, and then search and recall according to the translation results.
Among them, the translator directly calls Netease Youdao, but how to do the search?
The simplest method must be word segmentation and then indexing. Lucene is standard. But on Lucene, you have to go to the server, pass!
Let's find a Lucene on the browser side and select flexsearch after Google
Flexsearch GitHub has 6.5k star, so it is preferred.
Let's look at the specific implementation.
Indexing
Initialize flexsearch, and then name and index the previously obtained code.
var index = new FlexSearch({
encode: "advanced",tokenize: "reverse",suggest: true,cache: true
})
var data = []
var i = 0
for (var name in names) {
var indexName = name.replace(/([A-Z])/g," $1")
data[i] = {
"name": name,"count": names[name]
}
index.add(i++,indexName)
}
Here's a tip, name Replace (/ ([A-Z]) / g, "$1") can split hump naming into words. At the same time, the data array will save all naming and response occurrences.
Search candidates
Translate first, and then send the translation results to flexsearch search.
function searchFromIndex(value) {
var results = index.search(value,25)
results = results.map(function (i) {
return data[i]
})
results = results.sort(function (a,b) {
return b.count - a.count
})
return results
}
First, the search result is the index serial number in data, which is converted into a list object, and then inverted according to count.
Tips: in theory, some stop words can be removed from the translation results, and the search effect should be better. Put it here first.
Format the results:
function formatSuggestion(item){
return `${item.name} <span class='tips'>代码库共出现${item.count}次 (相关搜索: <a target='_blank' href='https://unbug.github.io/codelf/#${item.name}'>codelf</a> <a target='_blank' href='https://searchcode.com/?q=${item.name}&lan=23'>searchcode</a>)</span>`;
}
Add links to codelf and searchcode, and the results are as follows:
Open source address
Naming tool address: https://jadepeng.gitee.io/code-naming-tool/
Welcome to experience and use. Welcome to fork and contribute code.
Follow up outlook
At present, only translation + search is used, and there are many places that can be optimized: