Module: CrossLanguageSpotter

Defined in:
lib/crosslanguagespotter/basic.rb,
lib/crosslanguagespotter/oracle.rb,
lib/crosslanguagespotter/report.rb,
lib/crosslanguagespotter/context.rb,
lib/crosslanguagespotter/version.rb,
lib/crosslanguagespotter/methods/jaro.rb,
lib/crosslanguagespotter/model_loading.rb,
lib/crosslanguagespotter/methods/context.rb,
lib/crosslanguagespotter/methods/tversky.rb,
lib/crosslanguagespotter/wekaintegration.rb,
lib/crosslanguagespotter/figures_evaluator.rb

Defined Under Namespace

Classes: Context, ContextReferencesProducer, CrossLanguageReferencesProducer, CrossLanguageReferencesProducerMethodsComparator, CrossLanguageRelation, FiguresEvaluator, JaroReferencesProducer, MetaOracleRelationEnd, ModelLoader, NodeId, OracleLoader, OracleRelationEnd, Pair, PointsMap, Project, SequentialAst, Spotter, TverskyReferencesProducer, WekaClassifier

Constant Summary collapse

VERSION =
"0.0.2"
AngularParser =
CodeModels::Html::AngularJs.parser_considering_angular_embedded_code

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

._load_models(dir, base_path = '', models = {}) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/crosslanguagespotter/basic.rb', line 18

def self._load_models(dir,base_path='',models={})
    Dir.foreach(dir) do |f| 
        if f!='.' and f!='..'
            path = dir+'/'+f
            if File.directory?(path)
                _load_models(path,base_path+'/'+dir,models)
            else
                begin
                    models[base_path+'/'+f] = CodeModels.parse_file(path)
                rescue Exception => e
                    puts "No model available for #{path}: #{e}"
                end
            end
        end
    end
    return models
end

Instance Method Details

#_code(files_content, filename, begin_line, end_line, begin_col, end_col) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/crosslanguagespotter/report.rb', line 42

def _code(files_content,filename,begin_line,end_line,begin_col,end_col)
    code = ""
    snippet_lines = _get_snippet_lines(files_content[filename],begin_line)
    snippet_lines[:before].each do |l|
        code += HTMLEntities.new.encode(l,:decimal)
    end
    snippet_lines[:lines].each do |l|
        #l = l.gsub("\t",'    ')
        code += HTMLEntities.new.encode(l[0...(begin_col-1)],:decimal)
        puts "<<<#{l[(begin_col-1)...end_col]}>>>"
        code += '<span style="background-color:yellow;padding:2px">'+HTMLEntities.new.encode(l[(begin_col-1)...end_col],:decimal)+"</span>"
        code += HTMLEntities.new.encode(l[end_col..-1],:decimal)
    end
    snippet_lines[:after].each do |l|
        code += HTMLEntities.new.encode(l,:decimal)
    end
    code = _remove_extra_spaces(code)
    code
end

#_get_snippet_lines(lines, line_index) ⇒ Object



62
63
64
65
66
67
68
69
70
# File 'lib/crosslanguagespotter/report.rb', line 62

def _get_snippet_lines(lines,line_index)   
    around = 5
    start_line = [0,line_index-5].max
    end_line   = [lines.count-1,line_index+5].min
    before = lines[start_line...line_index]
    sel_lines  = [lines[line_index]]
    after  = lines[(line_index+1)..(end_line)]
    {before:before,lines:sel_lines,after:after}
end

#_language_from_filename(filename) ⇒ Object



11
12
13
14
15
16
17
# File 'lib/crosslanguagespotter/report.rb', line 11

def _language_from_filename(filename)
    if filename.end_with?('.html')
        'html'
    else
        'javascript'
    end
end

#_number_of_spaces(s) ⇒ Object



72
73
74
75
# File 'lib/crosslanguagespotter/report.rb', line 72

def _number_of_spaces(s)
    return 0 unless s.start_with?(' ')
    1+_number_of_spaces(s[1..-1])
end

#_remove_extra_spaces(code, newline = "&#10;") ⇒ Object



77
78
79
80
81
82
83
84
85
86
# File 'lib/crosslanguagespotter/report.rb', line 77

def _remove_extra_spaces(code,newline="&#10;")
    lines = code.split(newline)
    spaces = []
    lines.each do |l|
        spaces << _number_of_spaces(l)
    end
    extra_spaces = spaces.min
    lines.each_with_index {|l,i| lines[i] = l[extra_spaces..-1]}    
    lines.join(newline)
end

#build_classifier(training_instances) ⇒ Object



5
6
7
8
9
# File 'lib/crosslanguagespotter/wekaintegration.rb', line 5

def build_classifier(training_instances)
    c = Java::weka::classifiers::trees::RandomTree.new
    c.build_classifier(training_instances)
    c
end

#collect_values_with_declarator(node) ⇒ Object



6
7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/crosslanguagespotter/context.rb', line 6

def collect_values_with_declarator(node)
    declarators_per_value = Hash.new {|h,k| h[k]=[]}
    self.class.ecore.eAllAttributes.each do |a|
        v = self.send(:"#{a.name}")
        if v!=nil
            if a.many
                v.each {|el| values[el]+=1}
            else
                values[v]+=1
            end
        end
    end
    values          
end

#context(node) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/crosslanguagespotter/context.rb', line 114

def context(node)
    ctx = Context.new
    container = node.container_also_foreign
    if container
        ctx.merge(context(container))

        # RGen attributes of the father
        container.collect_values_with_count.keys.each do |value|
            ctx.register(value,container)
        end

        # siblings in different containment reference
        container.all_children_also_foreign.each do |sibling|
            if (sibling.eContainingFeature!=node.eContainingFeature) || (node.eContainingFeature==nil && node!=sibling)
                sibling.traverse(:also_foreign) do |n|
                    n.collect_values_with_count.keys.each do |value|
                        ctx.register(value,n)
                    end
                end             
            end
        end     
    end
    ctx
end

#generate_report_file(relations, output) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/crosslanguagespotter/report.rb', line 19

def generate_report_file(relations,output)
    files_content = Hash.new{|h,k| h[k]=File.readlines(k)}
    template = Liquid::Template.parse(File.read('./resources/template.html'))

    data = []
    relations.each do |rel|
        entry = {}
        entry['filenameA'] = rel[:node_a_file]
        entry['languageA'] = _language_from_filename(entry['filenameA'])
        entry['srcfileA']  = _code(files_content,rel[:node_a_file],
                rel[:node_a_begin_line]-1,rel[:node_a_end_line]-1,
                rel[:node_a_begin_column],rel[:node_a_end_column])
        entry['filenameB'] = rel[:node_b_file]
        entry['languageB'] = _language_from_filename(entry['filenameB'])
        entry['srcfileB']  = _code(files_content,rel[:node_b_file],
                rel[:node_b_begin_line]-1,rel[:node_b_end_line]-1,
                rel[:node_b_begin_column],rel[:node_b_end_column])        
        data << entry
    end

    File.open(output, 'w') {|f| f.write(template.render({"relations"=>data})) }
end

#hash2weka_instances(name, data, keys, class_value) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/crosslanguagespotter/wekaintegration.rb', line 30

def hash2weka_instances(name,data,keys,class_value)
    boolean_values = Java::weka::core::FastVector.new
    boolean_values.add_element("true")
    boolean_values.add_element("false")

    # fill attributes
    attributes = Java::weka::core::FastVector.new
    attributes_map = {}
    attributes_indexes = {}
    i = 0    
    keys.each do |k,v|
        raise "Null key in keys: #{keys}" unless k
        raise "Null value for key #{k} in keys: #{keys}" unless v!=nil
        if v==:numeric
            # creates a numeric attribute
            a = Java::weka::core::Attribute.new(k.to_s)
        elsif v==:boolean
            a = Java::weka::core::Attribute.new(k.to_s,boolean_values)
        else
            raise "Unknown attribute type: #{v}"
        end
        attributes.add_element(a)
        attributes_map[k] = a
        attributes_indexes[k] = i
        i+=1
    end
    instances = Java::weka::core::Instances.new name, attributes, data.count

    # fill instances
    data.each do |row|
        instance = Java::weka::core::Instance.new keys.count
        keys.each do |k,v|
            a = attributes_map[k]
            if v==:numeric
                instance.setValue(a,row[k])
            elsif v==:boolean
                instance.setValue(a,row[k].to_s)
            else
                raise "Unknown attribute type: #{v}"
            end
        end
        instances.add(instance)
    end

    if class_value
        instances.setClassIndex(attributes_indexes[class_value])
    end

    #puts instances.to_s

    return instances
end

#host_lines(node) ⇒ Object



44
45
46
47
# File 'lib/crosslanguagespotter/model_loading.rb', line 44

def host_lines(node)
    [line_referred_to_host(node,node.source.begin_line),
        line_referred_to_host(node,node.source.end_line)]
end

#is_in_line?(node, line) ⇒ Boolean

Returns:

  • (Boolean)


49
50
51
# File 'lib/crosslanguagespotter/model_loading.rb', line 49

def is_in_line?(node,line)
    line>=line_referred_to_host(node,node.source.begin_pos.line) && line<=line_referred_to_host(node,node.source.end_pos.line)  
end

#line_referred_to_host(node, line) ⇒ Object



40
41
42
# File 'lib/crosslanguagespotter/model_loading.rb', line 40

def line_referred_to_host(node,line)
    offset_referred_to_host(node)+line
end

#node_at_traverse_index(root, index) ⇒ Object



21
22
23
24
25
26
27
28
# File 'lib/crosslanguagespotter/model_loading.rb', line 21

def node_at_traverse_index(root,index)
    i = 1
    root.traverse(:also_foreign) do |n|
        return n if (i==index)
        i+=1
    end
    raise "Error... traverse_index: #{index}. Reached #{i}"
end

#offset_referred_to_host(node) ⇒ Object



31
32
33
34
35
36
37
38
# File 'lib/crosslanguagespotter/model_loading.rb', line 31

def offset_referred_to_host(node)
    base = node.eContainer ? offset_referred_to_host(node.eContainer) : 0
    if node.eContainingFeature && node.eContainingFeature==:foreign_asts
        base+node.eContainer.source.begin_pos.line-1
    else
        base
    end
end

#traverse_index(node) ⇒ Object



11
12
13
14
15
16
17
18
19
# File 'lib/crosslanguagespotter/model_loading.rb', line 11

def traverse_index(node)
    root = node.root(:also_foreign)
    i = 1
    root.traverse(:also_foreign) do |n|
        return i if (n==node) && (n.source.position(:absolute)==node.source.position(:absolute))
        i+=1
    end
    raise "Error..."
end