Coverage Report

Created: 2020-02-15 09:57

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Format/AffectedRangeManager.cpp
Line
Count
Source
1
//===--- AffectedRangeManager.cpp - Format C++ code -----------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
///
9
/// \file
10
/// This file implements AffectRangeManager class.
11
///
12
//===----------------------------------------------------------------------===//
13
14
#include "AffectedRangeManager.h"
15
16
#include "FormatToken.h"
17
#include "TokenAnnotator.h"
18
19
namespace clang {
20
namespace format {
21
22
bool AffectedRangeManager::computeAffectedLines(
23
153k
    SmallVectorImpl<AnnotatedLine *> &Lines) {
24
153k
  SmallVectorImpl<AnnotatedLine *>::iterator I = Lines.begin();
25
153k
  SmallVectorImpl<AnnotatedLine *>::iterator E = Lines.end();
26
153k
  bool SomeLineAffected = false;
27
153k
  const AnnotatedLine *PreviousLine = nullptr;
28
281k
  while (I != E) {
29
128k
    AnnotatedLine *Line = *I;
30
128k
    Line->LeadingEmptyLinesAffected = affectsLeadingEmptyLines(*Line->First);
31
128k
32
128k
    // If a line is part of a preprocessor directive, it needs to be formatted
33
128k
    // if any token within the directive is affected.
34
128k
    if (Line->InPPDirective) {
35
8.23k
      FormatToken *Last = Line->Last;
36
8.23k
      SmallVectorImpl<AnnotatedLine *>::iterator PPEnd = I + 1;
37
12.3k
      while (PPEnd != E && 
!(*PPEnd)->First->HasUnescapedNewline10.8k
) {
38
4.12k
        Last = (*PPEnd)->Last;
39
4.12k
        ++PPEnd;
40
4.12k
      }
41
8.23k
42
8.23k
      if (affectsTokenRange(*Line->First, *Last,
43
8.23k
                            /*IncludeLeadingNewlines=*/false)) {
44
6.94k
        SomeLineAffected = true;
45
6.94k
        markAllAsAffected(I, PPEnd);
46
6.94k
      }
47
8.23k
      I = PPEnd;
48
8.23k
      continue;
49
8.23k
    }
50
120k
51
120k
    if (nonPPLineAffected(Line, PreviousLine, Lines))
52
101k
      SomeLineAffected = true;
53
120k
54
120k
    PreviousLine = Line;
55
120k
    ++I;
56
120k
  }
57
153k
  return SomeLineAffected;
58
153k
}
59
60
bool AffectedRangeManager::affectsCharSourceRange(
61
663k
    const CharSourceRange &Range) {
62
663k
  for (SmallVectorImpl<CharSourceRange>::const_iterator I = Ranges.begin(),
63
663k
                                                        E = Ranges.end();
64
816k
       I != E; 
++I153k
) {
65
707k
    if (!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(), I->getBegin()) &&
66
707k
        
!SourceMgr.isBeforeInTranslationUnit(I->getEnd(), Range.getBegin())641k
)
67
554k
      return true;
68
707k
  }
69
663k
  
return false109k
;
70
663k
}
71
72
bool AffectedRangeManager::affectsTokenRange(const FormatToken &First,
73
                                             const FormatToken &Last,
74
534k
                                             bool IncludeLeadingNewlines) {
75
534k
  SourceLocation Start = First.WhitespaceRange.getBegin();
76
534k
  if (!IncludeLeadingNewlines)
77
130k
    Start = Start.getLocWithOffset(First.LastNewlineOffset);
78
534k
  SourceLocation End = Last.getStartOfNonWhitespace();
79
534k
  End = End.getLocWithOffset(Last.TokenText.size());
80
534k
  CharSourceRange Range = CharSourceRange::getCharRange(Start, End);
81
534k
  return affectsCharSourceRange(Range);
82
534k
}
83
84
128k
bool AffectedRangeManager::affectsLeadingEmptyLines(const FormatToken &Tok) {
85
128k
  CharSourceRange EmptyLineRange = CharSourceRange::getCharRange(
86
128k
      Tok.WhitespaceRange.getBegin(),
87
128k
      Tok.WhitespaceRange.getBegin().getLocWithOffset(Tok.LastNewlineOffset));
88
128k
  return affectsCharSourceRange(EmptyLineRange);
89
128k
}
90
91
void AffectedRangeManager::markAllAsAffected(
92
    SmallVectorImpl<AnnotatedLine *>::iterator I,
93
17.5k
    SmallVectorImpl<AnnotatedLine *>::iterator E) {
94
28.2k
  while (I != E) {
95
10.6k
    (*I)->Affected = true;
96
10.6k
    markAllAsAffected((*I)->Children.begin(), (*I)->Children.end());
97
10.6k
    ++I;
98
10.6k
  }
99
17.5k
}
100
101
bool AffectedRangeManager::nonPPLineAffected(
102
    AnnotatedLine *Line, const AnnotatedLine *PreviousLine,
103
120k
    SmallVectorImpl<AnnotatedLine *> &Lines) {
104
120k
  bool SomeLineAffected = false;
105
120k
  Line->ChildrenAffected = computeAffectedLines(Line->Children);
106
120k
  if (Line->ChildrenAffected)
107
1.93k
    SomeLineAffected = true;
108
120k
109
120k
  // Stores whether one of the line's tokens is directly affected.
110
120k
  bool SomeTokenAffected = false;
111
120k
  // Stores whether we need to look at the leading newlines of the next token
112
120k
  // in order to determine whether it was affected.
113
120k
  bool IncludeLeadingNewlines = false;
114
120k
115
120k
  // Stores whether the first child line of any of this line's tokens is
116
120k
  // affected.
117
120k
  bool SomeFirstChildAffected = false;
118
120k
119
646k
  for (FormatToken *Tok = Line->First; Tok; 
Tok = Tok->Next526k
) {
120
526k
    // Determine whether 'Tok' was affected.
121
526k
    if (affectsTokenRange(*Tok, *Tok, IncludeLeadingNewlines))
122
442k
      SomeTokenAffected = true;
123
526k
124
526k
    // Determine whether the first child of 'Tok' was affected.
125
526k
    if (!Tok->Children.empty() && 
Tok->Children.front()->Affected2.05k
)
126
2.01k
      SomeFirstChildAffected = true;
127
526k
128
526k
    IncludeLeadingNewlines = Tok->Children.empty();
129
526k
  }
130
120k
131
120k
  // Was this line moved, i.e. has it previously been on the same line as an
132
120k
  // affected line?
133
120k
  bool LineMoved = PreviousLine && 
PreviousLine->Affected86.6k
&&
134
120k
                   
Line->First->NewlinesBefore == 068.9k
;
135
120k
136
120k
  bool IsContinuedComment =
137
120k
      Line->First->is(tok::comment) && 
Line->First->Next == nullptr2.32k
&&
138
120k
      
Line->First->NewlinesBefore < 21.75k
&&
PreviousLine1.69k
&&
139
120k
      
PreviousLine->Affected897
&&
PreviousLine->Last->is(tok::comment)882
;
140
120k
141
120k
  bool IsAffectedClosingBrace =
142
120k
      Line->First->is(tok::r_brace) &&
143
120k
      
Line->MatchingOpeningBlockLineIndex != UnwrappedLine::kInvalidIndex21.2k
&&
144
120k
      
Lines[Line->MatchingOpeningBlockLineIndex]->Affected21.1k
;
145
120k
146
120k
  if (SomeTokenAffected || 
SomeFirstChildAffected20.6k
||
LineMoved20.6k
||
147
120k
      
IsContinuedComment19.0k
||
IsAffectedClosingBrace19.0k
) {
148
101k
    Line->Affected = true;
149
101k
    SomeLineAffected = true;
150
101k
  }
151
120k
  return SomeLineAffected;
152
120k
}
153
154
} // namespace format
155
} // namespace clang