• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

protofire / solhint / #143846

09 May 2026 04:07PM UTC coverage: 97.831% (+5.8%) from 92.08%
#143846

push

589 of 666 branches covered (88.44%)

2796 of 2858 relevant lines covered (97.83%)

119.24 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.31
/../lib/comment-directive-parser.js
1
class CommentDirectiveParser {
2
  constructor(tokens) {
3
    const lastToken = tokens[tokens.length - 1]
267✔
4
    this.lastLine = lastToken ? lastToken.loc.end.line : 0
267✔
5
    this.ruleStore = new RuleStore(this.lastLine)
6

267✔
7
    this.parseComments(tokens)
8
  }
9

10
  parseComments(tokens) {
267✔
11
    const items = tokens.filter(
267✔
12
      (token) => token.type === 'Keyword' && /^(\/\/|\/\*)/.test(token.value),
28✔
13
    )
14
    items.forEach((item) => this.onComment(item))
15
  }
16

17
  onComment(lexema) {
35✔
18
    const text = lexema.value
35✔
19
    const curLine = lexema.loc.start.line
35✔
20
    const ruleStore = this.ruleStore
21

35✔
22
    if (text.includes('solhint-disable-line')) {
2✔
23
      const rules = this.parseRuleIds(text, 'solhint-disable-line')
2✔
24
      ruleStore.disableRules(curLine, rules)
2✔
25
      return
26
    }
27

33✔
28
    if (text.includes('solhint-disable-next-line')) {
7✔
29
      const rules = this.parseRuleIds(text, 'solhint-disable-next-line')
30

7✔
31
      if (curLine + 1 <= this.lastLine) {
4✔
32
        ruleStore.disableRules(curLine + 1, rules)
33
      }
34

7✔
35
      return
36
    }
37

26✔
38
    if (text.includes('solhint-disable-previous-line')) {
4✔
39
      const rules = this.parseRuleIds(text, 'solhint-disable-previous-line')
40

4!
41
      if (curLine > 0) {
4✔
42
        ruleStore.disableRules(curLine - 1, rules)
43
      }
44

4✔
45
      return
46
    }
47

22✔
48
    if (text.includes('solhint-disable')) {
10✔
49
      const rules = this.parseRuleIds(text, 'solhint-disable')
50

10✔
51
      ruleStore.disableRulesToEndOfFile(curLine, rules)
52

10✔
53
      return
54
    }
55

12✔
56
    if (text.includes('solhint-enable')) {
6✔
57
      const rules = this.parseRuleIds(text, 'solhint-enable')
58

6✔
59
      ruleStore.enableRulesToEndOfFile(curLine, rules)
60
    }
61
  }
62

63
  parseRuleIds(text, start) {
29✔
64
    const ruleIds = text.replace('//', '').replace('/*', '').replace('*/', '').replace(start, '')
65

66
    const rules = ruleIds
67
      .split(',')
68
      .map((curRule) => curRule.trim())
69
      .filter((i) => i.length > 0)
29✔
70

71
    return rules.length > 0 ? rules : 'all'
29✔
72
  }
29✔
73

74
  isRuleEnabled(line, ruleId) {
29✔
75
    return this.ruleStore.isRuleEnabled(line, ruleId)
76
  }
77
}
78

219✔
79
class RuleStore {
80
  constructor(lastLine) {
81
    this.disableRuleByLine = []
82
    this.disableAllByLine = []
83
    this.lastLine = lastLine
84

267✔
85
    this.initRulesTable()
267✔
86
  }
267✔
87

88
  initRulesTable() {
267✔
89
    for (let i = 1; i <= this.lastLine; i += 1) {
90
      this.disableRuleByLine[i] = new Set()
91
      this.disableAllByLine[i] = false
92
    }
267✔
93
  }
2,865✔
94

2,865✔
95
  disableRules(curLine, newRules) {
96
    if (newRules === 'all') {
97
      this.disableAllByLine[curLine] = true
98
    } else {
99
      const lineRules = this.disableRuleByLine[curLine]
56✔
100
      this.disableRuleByLine[curLine] = new Set([...lineRules, ...newRules])
37✔
101
    }
102
  }
19✔
103

19✔
104
  disableRulesToEndOfFile(startLine, rules) {
105
    this._toEndOfFile(startLine, (i) => this.disableRules(i, rules))
106
  }
107

108
  enableRules(curLine, rules) {
46✔
109
    if (rules === 'all') {
110
      this.disableAllByLine[curLine] = false
111
    } else {
112
      const lineRules = this.disableRuleByLine[curLine]
18✔
113
      rules.forEach((curRule) => lineRules.delete(curRule))
9✔
114
    }
115
  }
9✔
116

9✔
117
  enableRulesToEndOfFile(startLine, rules) {
118
    this._toEndOfFile(startLine, (i) => this.enableRules(i, rules))
119
  }
120

121
  isRuleEnabled(line, ruleId) {
18✔
122
    const allRulesDisabled = this.disableAllByLine[line]
123
    const ruleDisabled = this.disableRuleByLine[line] && this.disableRuleByLine[line].has(ruleId)
124
    return !allRulesDisabled && !ruleDisabled
125
  }
219✔
126

127
  _toEndOfFile(from, callback) {
128
    if (!callback) {
129
      return
16!
130
    }
×
131

132
    for (let i = from; i <= this.lastLine; i += 1) {
133
      callback(i)
16✔
134
    }
64✔
135
  }
136
}
137

138
module.exports = CommentDirectiveParser
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc