这段代码主要实现了从给定的 bug_id 中获取代码的位置信息。具体来说,代码分为两个部分:

  1. get_loc_file 函数

这个函数根据传入的 bug_idperfect 参数,返回对应的位置文件的路径。如果 perfectTrue,则返回 groundtruth 文件夹下对应 bug_id 的位置文件路径;否则,返回 ochiai 文件夹下对应 bug_id 的位置文件路径。最后,将路径进行合并并返回。

import os

def get_loc_file(bug_id, perfect):
    dirname = os.path.dirname(__file__)
    if perfect:
        loc_file = '../location/groundtruth/%s/%s' % (bug_id.split('-')[0].lower(), bug_id.split('-')[1])
    else:
        loc_file = '../location/ochiai/%s/%s.txt' % (bug_id.split('-')[0].lower(), bug_id.split('-')[1])
    loc_file = os.path.join(dirname, loc_file)
    if os.path.isfile(loc_file):
        return loc_file
    else:
        print(loc_file)
        return ''
  1. get_location 函数

这个函数首先根据 bug_id 获取源代码目录的路径,然后调用 get_loc_file 函数获取位置文件的路径。如果返回的路径为空,则直接返回空的位置信息列表。

如果 perfectTrue,则从位置文件中读取每个缺陷的位置信息,并将其转换为 (file, line) 的形式,并添加到 location 列表中。如果 perfectFalse,则读取位置文件中的前 top_n 行,并将其添加到 location 列表中。在这里,为了避免重复添加相同的位置信息,使用了 location_dict 字典来记录已经添加的位置信息。

最后,将 location 列表的前 top_n 个位置信息返回。

# grab location info from bug_id given
# perfect fault localization returns 1 line, top n gets top n lines for non-perfect FL (40 = decoder top n)
def get_location(bug_id, perfect=True, top_n=40):
    source_dir = os.popen('defects4j export -p dir.src.classes -w /tmp/' + bug_id).readlines()[-1].strip() + '/'
    location = []
    location_dict = {}
    loc_file = get_loc_file(bug_id, perfect)
    if loc_file == '':
        return location
    if perfect:
        lines = open(loc_file, 'r').readlines()
        for loc_line in lines:
            loc_line = loc_line.split('||')[0]  # take first line in lump
            classname, line_id = loc_line.split(':')
            classname = '.'.join(classname.split('.')[:-1])  # remove function name
            if '$' in classname:
                classname = classname[:classname.index('$')]
            file = source_dir + '/' + '/'.join(classname.split('.')) + '.java'
            location.append((file, int(line_id) - 1))
    else:
        lines = open(loc_file, 'r').readlines()
        for loc_line in lines:
            loc_line = loc_line.split(',')[0]
            classname, line_id = loc_line.split('#')
            if '$' in classname:
                classname = classname[:classname.index('$')]
            file = source_dir + '/' + '/'.join(classname.split('.')) + '.java'
            if file + line_id not in location_dict:
                location.append((file, int(line_id) - 1))
                location_dict[file + line_id] = 0
            else:
                print('Same Fault Location: {}, {}'.format(file, line_id))
        pass

    return location[:top_n]

通过这两个函数,代码可以准确地从 Bug ID 中获取代码的位置信息,为后续的缺陷定位和代码分析工作提供基础数据。

Python 代码分析:从 Bug ID 获取代码位置信息

原文地址: https://www.cveoy.top/t/topic/mVSQ 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录