1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//! `Loc` implementation for Perl.
#![allow(
clippy::enum_glob_use,
clippy::match_same_arms,
clippy::struct_field_names,
clippy::wildcard_imports
)]
#![allow(
clippy::cast_precision_loss,
clippy::cast_possible_truncation,
clippy::cast_sign_loss
)]
use super::*;
impl Loc for PerlCode {
fn compute(node: &Node, stats: &mut Stats, is_func_space: bool, is_unit: bool) {
use Perl as P;
let (start, end) = init(node, stats, is_func_space, is_unit);
match node.kind_id().into() {
P::SourceFile
| P::Block
| P::StandaloneBlock
| P::PodContent
// Internal string tokens — already accounted for by the
// parent string node's start row.
| P::SQUOTE
| P::DQUOTE
| P::StringContent
| P::StringSingleQuotedContent
| P::StringSingleQQuotedContent
| P::StringQqQuotedContent
| P::StringDoubleQuotedContent
| P::EscapeSequence
| P::EscapeSequenceToken1
| P::Interpolation => {}
// Multi-line-capable string literals: their interior rows are
// real code, not blank lines, so credit every spanned row to
// PLOC to match Python's #415 decision (#778). `HeredocBodyStatement`
// / `HeredocContent` are the body of a `<<EOT … EOT` heredoc; the
// quoted forms span rows when their literal text contains newlines.
P::HeredocBodyStatement
| P::HeredocContent
| P::StringSingleQuoted
| P::StringDoubleQuoted
| P::StringQQuoted
| P::StringQqQuoted
| P::BacktickQuoted
| P::CommandQxQuoted => {
add_multiline_string_ploc(node, stats, start, end);
}
P::Comments | P::PodStatement => {
add_cloc_lines(stats, start, end);
}
P::SingleLineStatement
| P::IfStatement
| P::UnlessStatement
| P::WhileStatement
| P::UntilStatement
| P::ForStatement1
| P::ForStatement2
| P::LoopControlStatement
| P::PackageStatement
| P::RequireStatement
| P::UseNoStatement
| P::UseNoFeatureStatement
| P::UseNoIfStatement
| P::UseNoSubsStatement
| P::UseConstantStatement
| P::UseParentStatement
| P::UseNoVersion
| P::EllipsisStatement => {
stats.lloc.logical_lines += 1;
}
P::SEMI => {
// A `;` at top of `source_file` / a function `block` ends a
// statement (Perl wraps simple expressions in semicolons
// rather than emitting a dedicated statement kind), so it
// contributes one LLOC. Then fall through to the same PLOC
// bookkeeping the catch-all arm does.
if let Some(parent) = node.parent()
&& matches!(parent.kind_id().into(), P::SourceFile | P::Block)
{
stats.lloc.logical_lines += 1;
}
check_comment_ends_on_code_line(stats, start);
stats.ploc.lines.insert(start);
}
_ => {
check_comment_ends_on_code_line(stats, start);
stats.ploc.lines.insert(start);
}
}
}
}