nitc :: NitunitMdVisitor :: parse_code
fun parse_code(block: MdCodeBlock) do
var code = block.literal
if code == null then return
var meta = block.info or else "nit"
# Do not try to test non-nit code.
if meta != "nit" then return
# Try to parse code blocks
var executor = self.executor
var ast = executor.toolcontext.parse_something(code)
var mdoc = executor.mdoc
assert mdoc != null
# Skip pure comments
if ast isa TComment then return
# The location is computed according to the starts of the mdoc and the block
# Note, the following assumes that all the comments of the mdoc are correctly aligned.
var loc = block.location
var line_offset = loc.line_start + mdoc.location.line_start - 2
var column_offset = loc.column_start + mdoc.location.column_start
# Hack to handle precise location in blocks
# TODO remove when markdown is more reliable
if block isa MdFencedCodeBlock then
# Skip the starting fence
line_offset += 1
else
# Account a standard 4 space indentation
column_offset += 4
end
# We want executable code
if not (ast isa AModule or ast isa ABlockExpr or ast isa AExpr) then
var message
var l = ast.location
# Get real location of the node (or error)
var location = new Location(mdoc.location.file,
l.line_start + line_offset,
l.line_end + line_offset,
l.column_start + column_offset,
l.column_end + column_offset)
if ast isa AError then
message = ast.message
else
message = "Error: Invalid Nit code."
end
var du = new_docunit
du.block += code
du.error_location = location
du.error = message
executor.toolcontext.modelbuilder.failed_entities += 1
return
end
# Create a first block
# Or create a new block for modules that are more than a main part
var last_docunit = executor.last_docunit
if last_docunit == null or ast isa AModule then
last_docunit = new_docunit
executor.last_docunit = last_docunit
end
# Add it to the file
last_docunit.block += code
# In order to retrieve precise positions,
# the real position of each line of the raw_content is stored.
# See `DocUnit::real_location`
line_offset -= loc.line_start - 1
for i in [loc.line_start..loc.line_end] do
last_docunit.lines.add i + line_offset
last_docunit.columns.add column_offset
end
end
src/testing/testing_doc.nit:355,2--431,4