def _get_field_elements(self, field_name, prefix, kind): prefix = '{0}{1}'.format(prefix, cu.get_codebase_key(self.codebase)) code_elements = cu.get_value( prefix, field_name, gl.get_type_code_elements, [field_name, self.codebase, kind, True, FieldElement]) return code_elements
def _link_all_references(self, unknown_refs, ucount, progress_monitor): skipped = 0 class_tuples = [] progress_monitor.start('Parsing all unknown refs', ucount) for reference in unknown_refs: content = su.safe_strip(reference.content) if content is None or content == '': progress_monitor.info('Empty {0}'.format(reference.pk)) progress_monitor.work('Empty {0}'.format(reference.pk), 1) skipped += 1 (simple, fqn) = je.clean_java_name(je.get_clean_name(content)) prefix = '{0}{1}'.format(PREFIX_GENERIC_LINKER, cu.get_codebase_key(self.codebase)) code_elements = cu.get_value(prefix, simple, gl.get_any_code_element, [simple, self.codebase]) classified_elements = self._classify_code_elements(code_elements) class_tuples.append((reference, simple, fqn) + classified_elements) count = self._process_tuples(class_tuples, progress_monitor) progress_monitor.info( 'Associated {0} elements, Skipped {1} elements'.format( count, skipped)) progress_monitor.done()
def reclassify_java(code_element, scode_reference): reclassified = False if scode_reference.snippet is not None or code_element is not None: # We assume that references from snippet are always correctly # classified. References that were linked to a code element # do not need to be reclassified. return reclassified automatic_reclass = set(['method', 'field', 'annotation field', 'enumeration value', 'annotation', 'enumeration']) unknown_kind = cu.get_value(PREFIX_UNKNOWN, UNKNOWN_KEY, gl.get_unknown_kind, None) if scode_reference.kind_hint.kind in automatic_reclass: scode_reference.kind_hint = unknown_kind reclassified = True elif scode_reference.child_references.count() == 0: # This was a single class reference, not mixed with a field or a # method (in which case, the field/method will be reclassified if # there is a need to). Maybe it was a reference to a method or a # field. The simple name will be compared with all code elements scode_reference.kind_hint = unknown_kind reclassified = True if reclassified: scode_reference.save() return reclassified
def _link_enumerations(self, enum_refs, ecount, progress_monitor): count = 0 progress_monitor.start('Parsing enumerations', ecount) log = gl.LinkerLog(self, self.enum_kind.kind) for scode_reference in enum_refs: if scode_reference.declaration: progress_monitor.work('Skipped declaration', 1) continue (simple, fqn) = je.get_annotation_name(scode_reference.content, scode_reference.snippet is not None) if simple is not None: prefix = '{0}{1}{2}'.format(PREFIX_ENUMERATION_LINKER, EXACT, cu.get_codebase_key(self.codebase)) code_elements = cu.get_value( prefix, simple, gl.get_type_code_elements, [simple, self.codebase, self.enum_kind]) (code_element, potentials) = self.get_code_element( scode_reference, code_elements, simple, fqn, log) count += gl.save_link(scode_reference, code_element, potentials, self) if not log.custom_filtered: reclassify_java(code_element, scode_reference) progress_monitor.work('Processed enumeration', 1) log.close() progress_monitor.done() print('Associated {0} enumerations'.format(count))
def compute_project_code_words(codebases): code_words = set() for codebase in codebases: code_words.update( get_value(PREFIX_CODEBASE_CODE_WORDS, get_codebase_key(codebase), compute_code_words, [codebase])) return code_words
def reclassify_java(code_element, scode_reference): reclassified = False if scode_reference.snippet is not None or code_element is not None: # We assume that references from snippet are always correctly # classified. References that were linked to a code element # do not need to be reclassified. return reclassified automatic_reclass = set([ 'method', 'field', 'annotation field', 'enumeration value', 'annotation', 'enumeration' ]) unknown_kind = cu.get_value(PREFIX_UNKNOWN, UNKNOWN_KEY, gl.get_unknown_kind, None) if scode_reference.kind_hint.kind in automatic_reclass: scode_reference.kind_hint = unknown_kind reclassified = True elif scode_reference.child_references.count() == 0: # This was a single class reference, not mixed with a field or a # method (in which case, the field/method will be reclassified if # there is a need to). Maybe it was a reference to a method or a # field. The simple name will be compared with all code elements scode_reference.kind_hint = unknown_kind reclassified = True if reclassified: scode_reference.save() return reclassified
def _link_all_references(self, unknown_refs, ucount, progress_monitor): skipped = 0 class_tuples = [] progress_monitor.start('Parsing all unknown refs', ucount) for reference in unknown_refs: content = su.safe_strip(reference.content) if content is None or content == '': progress_monitor.info('Empty {0}'.format(reference.pk)) progress_monitor.work('Empty {0}'.format(reference.pk), 1) skipped += 1 (simple, fqn) = je.clean_java_name(je.get_clean_name(content)) prefix = '{0}{1}'.format(PREFIX_GENERIC_LINKER, cu.get_codebase_key(self.codebase)) code_elements = cu.get_value( prefix, simple, gl.get_any_code_element, [simple, self.codebase]) classified_elements = self._classify_code_elements(code_elements) class_tuples.append((reference, simple, fqn) + classified_elements) count = self._process_tuples(class_tuples, progress_monitor) progress_monitor.info('Associated {0} elements, Skipped {1} elements' .format(count, skipped)) progress_monitor.done()
def get_project_code_words(project): codebases = CodeBase.objects.filter(project_release__project=project).all() return get_value( PREFIX_PROJECT_CODE_WORDS, project.pk, compute_project_code_words, [codebases] )
def compute_project_code_words(codebases): code_words = set() for codebase in codebases: code_words.update( get_value(PREFIX_CODEBASE_CODE_WORDS, get_codebase_key(codebase), compute_code_words, [codebase]) ) return code_words
def _get_method_elements(self, method_info): prefix = '{0}{1}'.format(PREFIX_METHOD_LINKER, cu.get_codebase_key(self.codebase)) method_name = method_info.method_name code_elements = cu.get_value(prefix, method_name, gl.get_type_code_elements, [ method_name, self.codebase, self.method_kind, True, MethodElement ]) return code_elements
def _get_method_elements(self, method_info): prefix = '{0}{1}'.format(PREFIX_METHOD_LINKER, cu.get_codebase_key(self.codebase)) method_name = method_info.method_name code_elements = cu.get_value( prefix, method_name, gl.get_type_code_elements, [method_name, self.codebase, self.method_kind, True, MethodElement]) return code_elements
def test_cache_hit(self): self.assertEqual(3, cu.get_value("p", "k", func1, None)) self.assertEqual("6", cu.get_value("p", "k2", func2, [1, 5])) self.assertEqual(3, cu.get_value("p", "k", func1, None)) self.assertEqual("6", cu.get_value("p", "k2", func2, [1, 5])) self.assertEqual(3, cu.get_value("p", "k", func1, None)) self.assertEqual("6", cu.get_value("p", "k2", func2, [1, 5])) self.assertEqual(2, cu.cache_miss) self.assertEqual(6, cu.cache_total)
def test_cache_hit(self): self.assertEqual(3, cu.get_value('p', 'k', func1, None)) self.assertEqual('6', cu.get_value('p', 'k2', func2, [1, 5])) self.assertEqual(3, cu.get_value('p', 'k', func1, None)) self.assertEqual('6', cu.get_value('p', 'k2', func2, [1, 5])) self.assertEqual(3, cu.get_value('p', 'k', func1, None)) self.assertEqual('6', cu.get_value('p', 'k2', func2, [1, 5])) self.assertEqual(2, cu.cache_miss) self.assertEqual(6, cu.cache_total)
def test_cache_clear(self): self.assertEqual(3, cu.get_value('p', 'k', func1, None)) self.assertEqual('6', cu.get_value('p', 'k2', func2, [1, 5])) self.assertEqual(3, cu.get_value('p', 'k', func1, None)) self.assertEqual('6', cu.get_value('p', 'k2', func2, [1, 5])) cu.clear_cache() self.assertEqual(3, cu.get_value('p', 'k', func1, None)) self.assertEqual('6', cu.get_value('p', 'k2', func2, [1, 5])) self.assertEqual(4, cu.cache_miss) self.assertEqual(6, cu.cache_total)
def test_cache_clear(self): self.assertEqual(3, cu.get_value("p", "k", func1, None)) self.assertEqual("6", cu.get_value("p", "k2", func2, [1, 5])) self.assertEqual(3, cu.get_value("p", "k", func1, None)) self.assertEqual("6", cu.get_value("p", "k2", func2, [1, 5])) cu.clear_cache() self.assertEqual(3, cu.get_value("p", "k", func1, None)) self.assertEqual("6", cu.get_value("p", "k2", func2, [1, 5])) self.assertEqual(4, cu.cache_miss) self.assertEqual(6, cu.cache_total)
def _link_enumerations(self, enum_refs, ecount, progress_monitor): count = 0 progress_monitor.start('Parsing enumerations', ecount) log = gl.LinkerLog(self, self.enum_kind.kind) for scode_reference in enum_refs: if scode_reference.declaration: progress_monitor.work('Skipped declaration', 1) continue (simple, fqn) = je.get_annotation_name(scode_reference.content, scode_reference.snippet is not None) if simple is not None: prefix = '{0}{1}{2}'.format(PREFIX_ENUMERATION_LINKER, EXACT, cu.get_codebase_key(self.codebase)) code_elements = cu.get_value( prefix, simple, gl.get_type_code_elements, [simple, self.codebase, self.enum_kind]) (code_element, potentials) = self.get_code_element(scode_reference, code_elements, simple, fqn, log) count += gl.save_link(scode_reference, code_element, potentials, self) if not log.custom_filtered: reclassify_java(code_element, scode_reference) progress_monitor.work('Processed enumeration', 1) log.close() progress_monitor.done() print('Associated {0} enumerations'.format(count))
def get_container(code_element): return cu.get_value(PREFIX_GETCONTAINER, code_element.pk, get_container_value, [code_element])
def get_hierarchy(code_element): return cu.get_value(PREFIX_GETHIERARCHY, code_element.pk, get_hierarchy_value, [code_element])
def link_references(self, progress_monitor=NullProgressMonitor(), local_object_id=None): # Get link to filter. linksets = ReleaseLinkSet.objects\ .filter(project_release=self.prelease)\ .filter(first_link__code_element__kind__is_type=True) count = linksets.count() progress_monitor.start('Post-Processing Classes', count) log = gl.LinkerLog(self, 'type') for linkset in queryset_iterator(linksets): log.reset_variables() scode_reference = linkset.code_reference lcount = linkset.links.count() if lcount <= 1: log.log_type('', '', scode_reference, linkset.first_link.code_element, [linkset.first_link], lcount, 'onlyone') progress_monitor.work('Skipped a linkset.', 1) continue local_ctx_id = scode_reference.local_object_id source = scode_reference.source prefix = '{0}{1}{2}'.format(PREFIX_CLASS_POST_LINKER, cu.get_codebase_key(self.codebase), source) package_freq = cu.get_value(prefix, local_ctx_id, get_package_freq, [local_ctx_id, source, self.prelease]) # Find package with highest frequency code_element = self._find_package_by_freq(linkset, package_freq) rationale = 'highest_frequency' # Heuristic if code_element is None: code_element = self._find_package_by_depth(linkset) rationale = 'heuristic_depth' # Update links if code_element is not None: linkset.first_link.code_element = code_element linkset.first_link.linker_name = self.name linkset.first_link.rationale = rationale linkset.first_link.save() for link in linkset.links.all()[1:]: link.delete() log.log_type('', '', scode_reference, linkset.first_link.code_element, [linkset.first_link], lcount, rationale) progress_monitor.info( 'FOUND Best Package {0} because {1}'.format( code_element.fqn, rationale)) else: potentials =\ [link.code_element for link in linkset.links.all()] log.log_type('', '', scode_reference, linkset.first_link.code_element, potentials, lcount, 'nomatch') progress_monitor.work('Processed a linkset.', 1) progress_monitor.done()
def _link_classes(self, class_refs, ccount, progress_monitor): count = 0 progress_monitor.start('Parsing classes', ccount) log = gl.LinkerLog(self, self.class_kind.kind) for scode_reference in class_refs: if scode_reference.declaration: progress_monitor.work('Skipped declaration', 1) continue (simple, fqn) = je.get_annotation_name(scode_reference.content, scode_reference.snippet is not None) case_insensitive = scode_reference.snippet == None and\ self.source != 'd' if case_insensitive: exact = False exact_prefix = IEXACT else: exact = True exact_prefix = EXACT if simple is not None: prefix = '{0}{1}{2}'.format(PREFIX_CLASS_LINKER, exact_prefix, cu.get_codebase_key(self.codebase)) code_elements = [] code_elements.extend(cu.get_value( prefix, simple, gl.get_type_code_elements, [simple, self.codebase, self.class_kind, exact])) prefix = '{0}{1}{2}'.format(PREFIX_ANNOTATION_LINKER, exact_prefix, cu.get_codebase_key(self.codebase)) code_elements.extend(cu.get_value( prefix, simple, gl.get_type_code_elements, [simple, self.codebase, self.ann_kind, exact])) prefix = '{0}{1}{2}'.format(PREFIX_ENUMERATION_LINKER, exact_prefix, cu.get_codebase_key(self.codebase)) code_elements.extend(cu.get_value( prefix, simple, gl.get_type_code_elements, [simple, self.codebase, self.enum_kind, exact])) (code_element, potentials) = self.get_code_element( scode_reference, code_elements, simple, fqn, log, not exact) count += gl.save_link(scode_reference, code_element, potentials, self) if not log.custom_filtered: reclassify_java(code_element, scode_reference) progress_monitor.work('Processed class', 1) log.close() progress_monitor.done() print('Associated {0} classes'.format(count))
def get_context_types_hierarchy(context_id, source, filter_func, codebase, context_level): return cu.get_value( PREFIX_GETCONTEXT + HIERARCHY + source + context_level, context_id, get_context_types_hier_value, [context_id, source, filter_func, codebase, context_level])
def get_filters(codebase): return get_value(PREFIX_CODEBASE_FILTERS, get_codebase_key(codebase), compute_filters, [codebase])
def get_ancestors(code_element): return cu.get_value(PREFIX_GETANCESTORS, code_element.pk, get_ancestors_value, [code_element])
def get_descendants(code_element): return cu.get_value(PREFIX_GETDESCENDANTS, code_element.pk, get_descendants_value, [code_element])
def link_references(self, progress_monitor=NullProgressMonitor(), local_object_id=None): # Get link to filter. linksets = ReleaseLinkSet.objects\ .filter(project_release=self.prelease)\ .filter(first_link__code_element__kind__is_type=True) count = linksets.count() progress_monitor.start('Post-Processing Classes', count) log = gl.LinkerLog(self, 'type') for linkset in queryset_iterator(linksets): log.reset_variables() scode_reference = linkset.code_reference lcount = linkset.links.count() if lcount <= 1: log.log_type('', '', scode_reference, linkset.first_link.code_element, [linkset.first_link], lcount, 'onlyone') progress_monitor.work('Skipped a linkset.', 1) continue local_ctx_id = scode_reference.local_object_id source = scode_reference.source prefix = '{0}{1}{2}'.format(PREFIX_CLASS_POST_LINKER, cu.get_codebase_key(self.codebase), source) package_freq = cu.get_value( prefix, local_ctx_id, get_package_freq, [local_ctx_id, source, self.prelease]) # Find package with highest frequency code_element = self._find_package_by_freq(linkset, package_freq) rationale = 'highest_frequency' # Heuristic if code_element is None: code_element = self._find_package_by_depth(linkset) rationale = 'heuristic_depth' # Update links if code_element is not None: linkset.first_link.code_element = code_element linkset.first_link.linker_name = self.name linkset.first_link.rationale = rationale linkset.first_link.save() for link in linkset.links.all()[1:]: link.delete() log.log_type('', '', scode_reference, linkset.first_link.code_element, [linkset.first_link], lcount, rationale) progress_monitor.info('FOUND Best Package {0} because {1}' .format(code_element.fqn, rationale)) else: potentials =\ [link.code_element for link in linkset.links.all()] log.log_type('', '', scode_reference, linkset.first_link.code_element, potentials, lcount, 'nomatch') progress_monitor.work('Processed a linkset.', 1) progress_monitor.done()
def get_context_types(context_id, source, filter_func, codebase, context_level): return cu.get_value(PREFIX_GETCONTEXT + source + context_level, context_id, get_context_types_value, [context_id, source, filter_func, codebase])
def get_project_code_words(project): codebases = CodeBase.objects.filter(project_release__project=project).all() return get_value(PREFIX_PROJECT_CODE_WORDS, project.pk, compute_project_code_words, [codebases])
def get_context_types_hierarchy(context_id, source, filter_func, codebase, context_level): return cu.get_value(PREFIX_GETCONTEXT + HIERARCHY + source + context_level, context_id, get_context_types_hier_value, [context_id, source, filter_func, codebase, context_level])
def _link_classes(self, class_refs, ccount, progress_monitor): count = 0 progress_monitor.start('Parsing classes', ccount) log = gl.LinkerLog(self, self.class_kind.kind) for scode_reference in class_refs: if scode_reference.declaration: progress_monitor.work('Skipped declaration', 1) continue (simple, fqn) = je.get_annotation_name(scode_reference.content, scode_reference.snippet is not None) case_insensitive = scode_reference.snippet == None and\ self.source != 'd' if case_insensitive: exact = False exact_prefix = IEXACT else: exact = True exact_prefix = EXACT if simple is not None: prefix = '{0}{1}{2}'.format(PREFIX_CLASS_LINKER, exact_prefix, cu.get_codebase_key(self.codebase)) code_elements = [] code_elements.extend( cu.get_value( prefix, simple, gl.get_type_code_elements, [simple, self.codebase, self.class_kind, exact])) prefix = '{0}{1}{2}'.format(PREFIX_ANNOTATION_LINKER, exact_prefix, cu.get_codebase_key(self.codebase)) code_elements.extend( cu.get_value( prefix, simple, gl.get_type_code_elements, [simple, self.codebase, self.ann_kind, exact])) prefix = '{0}{1}{2}'.format(PREFIX_ENUMERATION_LINKER, exact_prefix, cu.get_codebase_key(self.codebase)) code_elements.extend( cu.get_value( prefix, simple, gl.get_type_code_elements, [simple, self.codebase, self.enum_kind, exact])) (code_element, potentials) = self.get_code_element(scode_reference, code_elements, simple, fqn, log, not exact) count += gl.save_link(scode_reference, code_element, potentials, self) if not log.custom_filtered: reclassify_java(code_element, scode_reference) progress_monitor.work('Processed class', 1) log.close() progress_monitor.done() print('Associated {0} classes'.format(count))