Skip to content

Commit

Permalink
backend/sdoc_source_code: general source code reader: support scope=file
Browse files Browse the repository at this point in the history
  • Loading branch information
stanislaw committed Nov 3, 2024
1 parent 1d5f1de commit f3288e3
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 4 deletions.
2 changes: 1 addition & 1 deletion docs/sphinx/source/strictdoc_01_user_guide.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1803,7 +1803,7 @@ The marker must be added to the top comment of a file. Currently supported only
"""
This class implements ...
@relation(REQ-1, scope=file)
@relation(REQ-1, scope=class)
"""
**3\) Linking a function to a requirement (Python and C only)**
Expand Down
2 changes: 1 addition & 1 deletion docs/strictdoc_01_user_guide.sdoc
Original file line number Diff line number Diff line change
Expand Up @@ -2145,7 +2145,7 @@ The marker must be added to the top comment of a file. Currently supported only
"""
This class implements ...

@relation(REQ-1, scope=file)
@relation(REQ-1, scope=class)
"""

**3\) Linking a function to a requirement (Python and C only)**
Expand Down
7 changes: 6 additions & 1 deletion strictdoc/backend/sdoc_source_code/grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// The EmptyLine is needed in addition to the SingleLineString because
// otherwise textX's get_location() ignores the whitespaces.
// TODO: Maybe there is a trick to disable that and only use SingleLineString.
EmptyLine | RangeMarker | LineMarker | SingleLineString
EmptyLine | RangeMarker | LineMarker | FunctionRangeMarker | SingleLineString
;
EmptyLine[noskipws]:
Expand All @@ -31,6 +31,11 @@
)
;
FunctionRangeMarker[noskipws]:
/^.*?@relation/
"(" (reqs_objs += Req[', ']) ', scope=file)' '\n'?
;
LineMarker[noskipws]:
// It is a hard-won result: it is important that the "@sdoc" is within the
// regex. Putting it next to the regex as "@sdoc" does not work.
Expand Down
36 changes: 35 additions & 1 deletion strictdoc/backend/sdoc_source_code/reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@

from strictdoc.backend.sdoc.error_handling import StrictDocSemanticError
from strictdoc.backend.sdoc_source_code.grammar import SOURCE_FILE_GRAMMAR
from strictdoc.backend.sdoc_source_code.models.function_range_marker import (
FunctionRangeMarker,
)
from strictdoc.backend.sdoc_source_code.models.range_marker import (
LineMarker,
RangeMarker,
Expand Down Expand Up @@ -206,10 +209,37 @@ def line_marker_processor(line_marker: LineMarker, parse_context: ParseContext):
markers.append(line_marker)


def function_range_marker_processor(
function_range_marker: FunctionRangeMarker, parse_context: ParseContext
):
location = get_location(function_range_marker)
line = location["line"]
column = location["col"]

if (
len(parse_context.marker_stack) > 0
and parse_context.marker_stack[-1].ng_is_nodoc
):
# This marker is within a "nosdoc" block, so we ignore it.
return

parse_context.markers.append(function_range_marker)
function_range_marker.ng_source_line_begin = 1
function_range_marker.ng_range_line_begin = 1
function_range_marker.ng_range_line_end = parse_context.lines_total
function_range_marker.ng_marker_line = line
function_range_marker.ng_marker_column = column

for req in function_range_marker.reqs:
markers = parse_context.map_reqs_to_markers.setdefault(req, [])
markers.append(function_range_marker)


class SourceFileTraceabilityReader:
SOURCE_FILE_MODELS = [
Req,
FunctionRangeMarker,
LineMarker,
Req,
SourceFileTraceabilityInfo,
RangeMarker,
]
Expand Down Expand Up @@ -241,8 +271,12 @@ def read(self, input_string, file_path=None) -> SourceFileTraceabilityInfo:
parse_line_marker_processor = partial(
line_marker_processor, parse_context=parse_context
)
parse_function_range_marker_processor = partial(
function_range_marker_processor, parse_context=parse_context
)

obj_processors = {
"FunctionRangeMarker": parse_function_range_marker_processor,
"LineMarker": parse_line_marker_processor,
"RangeMarker": parse_range_marker_processor,
"Req": parse_req_processor,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""
@relation(REQ-001, scope=file)
"""

def hello_world():
# @sdoc[REQ-001]
print("ignored hello world") # noqa: T201
print("ignored hello world") # noqa: T201
# @sdoc[/REQ-001]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[DOCUMENT]
TITLE: Hello world doc

[REQUIREMENT]
UID: REQ-001
TITLE: Requirement Title
STATEMENT: Requirement Statement
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[project]

features = [
"REQUIREMENT_TO_SOURCE_TRACEABILITY",
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
RUN: %strictdoc export %S --output-dir Output | filecheck %s --dump-input=fail
CHECK: Published: Hello world doc

RUN: %check_exists --file "%S/Output/html/_source_files/file.py.html"

RUN: %cat %S/Output/html/_source_files/file.py.html | filecheck %s --dump-input=fail --check-prefix CHECK-SOURCE-FILE
CHECK-SOURCE-FILE: [ 3 ]
CHECK-SOURCE-FILE: [ 5-8 ]
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,27 @@ def test_050_line_marker():
assert markers[2].ng_range_line_end == 5


def test_060_file_level_marker():
source_input = """
\"\"\"
@relation(REQ-001, scope=file)
\"\"\"
def hello_world():
pass
""".lstrip()

reader = SourceFileTraceabilityReader()

document = reader.read(source_input)
assert len(document.markers) == 1
markers = document.markers
assert markers[0].reqs == ["REQ-001"]
assert markers[0].ng_source_line_begin == 2
assert markers[0].ng_range_line_begin == 2
assert markers[0].ng_range_line_end == 2


def test_validation_01_one_range_marker_begin_req_not_equal_to_end_req():
source_input = """
# @sdoc[REQ-001]
Expand Down

0 comments on commit f3288e3

Please sign in to comment.