[go: up one dir, main page]

0% found this document useful (0 votes)
9 views3 pages

Abap Dependency - Py

Uploaded by

Madhu Sudhan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as RTF, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views3 pages

Abap Dependency - Py

Uploaded by

Madhu Sudhan
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as RTF, PDF, TXT or read online on Scribd
You are on page 1/ 3

import re

import networkx as nx
import matplotlib.pyplot as plt

class ABAPDependencyAnalyzer:
def __init__(self, sources: str):
"""
:param sources: single string containing all ABAP source code for
all objects
"""
# Split the sources into objects using a simple heuristic
self.sources = self._split_sources(sources)
self.objects = set(self.sources.keys())
self.graph = nx.DiGraph()

def _split_sources(self, sources: str):


"""
Splits the input string into a dict mapping object name to a tuple
of
(source code string, starting line number in the original text).
Assumes objects start with lines like 'REPORT <name>',
'FUNCTION <name>',
'TABLE <name>', or 'CLASS <name> DEFINITION'.
"""
pattern = re.compile(
r'^(REPORT|FUNCTION|TABLE|CLASS)\s+([A-Z][A-Z0-9_]+)',
re.MULTILINE | re.IGNORECASE
)
matches = list(pattern.finditer(sources))
result = {}
for i, match in enumerate(matches):
obj_name = match.group(2).upper()
start_idx = match.start()
end_idx = matches[i+1].start() if i+1 < len(matches) else
len(sources)
code_block = sources[start_idx:end_idx]
# Calculate starting line number
start_line = sources[:start_idx].count('\n') + 1
result[obj_name] = (code_block.strip(), start_line)
return result

def build_graph(self):
"""
Constructs a directed graph where each node is an ABAP object
and
edges represent "object A references object B".
"""
token_pattern = re.compile(r'\b([A-Z][A-Z0-9_]+)\b')
self.graph.clear()
self.graph.add_nodes_from(self.objects)
for obj, (code, _) in self.sources.items():
tokens = set(token_pattern.findall(code.upper()))
refs = tokens.intersection(self.objects) - {obj}
for ref in refs:
self.graph.add_edge(obj, ref)
return self.graph

def plot_graph(self, title="ABAP Dependency Graph"):


"""
Visualizes the dependency graph using NetworkX and Matplotlib.
"""
plt.figure(figsize=(8, 6))
pos = nx.spring_layout(self.graph)
nx.draw(self.graph, pos, with_labels=True, arrows=True,
node_size=600, font_size=9)
plt.title(title)
plt.tight_layout()
plt.show()

def get_impacted_objects(self, snippet: str):


"""
Parses a raw snippet of ABAP code to identify all directly
referenced
objects, then returns that set plus all their transitive
dependencies.
"""
token_pattern = re.compile(r'\b([A-Z][A-Z0-9_]+)\b')
tokens = set(token_pattern.findall(snippet.upper()))
initial = tokens.intersection(self.objects)
impacted = set(initial)
for obj in initial:
impacted.update(nx.descendants(self.graph, obj))
return list(impacted)

def get_impacted_snippets(self, snippet: str):


"""
Returns a list of dicts for each impacted object with keys:
- 'dependent_obj': the object name
- 'snippet_code': the full code block for that object
- 'start': starting line number in the original source text
- 'end': ending line number in the original source text
"""
impacted = self.get_impacted_objects(snippet)
results = []
for obj in impacted:
code_block, start_line = self.sources[obj]
# Split and strip each line to remove leading/trailing
whitespace
lines = [line.rstrip() for line in code_block.splitlines()]
snippet_code = "\n".join(lines)
end_line = start_line + len(lines) - 1
results.append({
"dependent_obj": obj,
"snippet_code": snippet_code,
"start": start_line,
"end": end_line
})
return results

# Example usage
if __name__ == "__main__":
full_sources = """
REPORT Z_PROG1.
CALL FUNCTION Z_FUNC1.
SELECT * FROM Z_TABLE1.

FUNCTION Z_FUNC1.
WRITE: / Z_TABLE1.
ENDFUNCTION.

TABLE Z_TABLE1.
FIELDS: FIELD1.

CLASS Z_LIB1 DEFINITION.


METHODS: DO_SOMETHING.
ENDCLASS.
CLASS Z_LIB1 IMPLEMENTATION.
METHOD DO_SOMETHING.
READ TABLE Z_TABLE1.
ENDMETHOD.
ENDCLASS.
"""
snippet = "CALL FUNCTION Z_FUNC1."

analyzer = ABAPDependencyAnalyzer(full_sources)
analyzer.build_graph()
analyzer.plot_graph()
impacted_snippets = analyzer.get_impacted_snippets(snippet)
print(impacted_snippets)

You might also like