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> &nbsp; <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:

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>