def analyze_unit(unit: lal.AnalysisUnit) -> None: """Computes and displays the static call graph of some unit.""" if unit.root: if DEBUG: ada_visitor = AdaPrintVisitor(max_depth=20) ada_visitor.visit(unit.root) static_call_graph_visitor = SCG.StaticCallGraphVisitor( context=context, caller_being_defined=None, edges=dict(), nodes=dict()) static_call_graph_visitor.visit(unit.root) analysis_output = make_empty_analysis_output() component_types = analysis_output["component_types"] component_types.add(ontology.SOURCE_FUNCTION) component_types.add(ontology.MODULE) formats = analysis_output["formats"] formats.add(ADA_FORMAT) components = analysis_output["components"] # register all components and the files they live in for component_key in static_call_graph_visitor.nodes: component_node = static_call_graph_visitor.nodes[component_key] component = register_component(analysis_output, component_node, ontology.SOURCE_FUNCTION) file_ = register_ada_file( analysis_output, as_optional_file_identifier(get_node_file(component_node))) component.defined_in = file_ # add "mentions" for caller_key in static_call_graph_visitor.edges: caller_node = static_call_graph_visitor.nodes[caller_key] caller_identifier = ontology.SoftwareComponentIdentifier( get_node_identifier(caller_node)) for callee_key in static_call_graph_visitor.edges[caller_key]: callee_node = static_call_graph_visitor.nodes[callee_key] callee_identifier = ontology.SoftwareComponentIdentifier( get_node_identifier(callee_node)) callee = components[callee_identifier] caller = components[caller_identifier] caller.add_mention(callee) if DEBUG_TURTLE: output_as_turtle(analysis_output) else: output_using_scrapingtoolkit(analysis_output) else: print("No root found, diagnostics:") print(unit.diagnostics)
def register_component( analysis_output: AnalysisOutput, component: GraphNode, component_type: ontology.ComponentTypeIdentifier, ) -> ontology.SoftwareComponent: """ Makes sure that the component is already present in the components dictionary. Adds it if necessary. """ components = analysis_output["components"] component_identifier = ontology.SoftwareComponentIdentifier( get_node_identifier(component)) if component_identifier not in components: components[component_identifier] = ontology.SoftwareComponent( identifier=component_identifier, # does not work because display names may contain special characters # title=SCG.get_node_display_name(component), # using this instead even though less ideal: title=component.doc_name, component_type=ontology.SOURCE_FUNCTION, uri=SOFTWARE_COMPONENT_NS[component_identifier], ) return components[component_identifier]
g.bind("dat", DATA) g.bind("format", FORMAT) txt_format = ontology.Format(ontology.FormatIdentifier("txt"), FORMAT.TEXT_FILE) my_file = ontology.File( identifier="src.txt", uri=DATA["src.txt"], name="src.txt", format_=txt_format, ) c1 = ontology.SoftwareComponent( component_type=ontology.SOURCE_FUNCTION, identifier=ontology.SoftwareComponentIdentifier("fun1"), title="fun1", uri=DATA["fun1"], ) c1.defined_in = my_file c2 = ontology.SoftwareComponent( component_type=ontology.SOURCE_FUNCTION, identifier=ontology.SoftwareComponentIdentifier("fun2"), title="fun2", uri=DATA["fun2"], ) c2.defined_in = my_file c2.add_mention(c1) txt_format.add_to_graph(g)