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

protofire / solhint / #143847

09 May 2026 04:07PM UTC coverage: 92.035% (-5.8%) from 97.831%
#143847

push

400 of 483 branches covered (82.82%)

1063 of 1155 relevant lines covered (92.03%)

117.56 hits per line

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

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

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

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

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

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

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

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

35
      return
2✔
36
    }
37

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

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

45
      return
2✔
46
    }
47

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

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

53
      return
3✔
54
    }
55

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

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

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

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

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

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

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

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

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

1,875✔
95
  disableRules(curLine, newRules) {
1,875✔
96
    if (newRules === 'all') {
97
      this.disableAllByLine[curLine] = true
98
    } else {
99
      const lineRules = this.disableRuleByLine[curLine]
100
      this.disableRuleByLine[curLine] = new Set([...lineRules, ...newRules])
15✔
101
    }
11✔
102
  }
103

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

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

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

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

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

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

15✔
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