@@ -162,20 +162,25 @@ class ContextOverride {
162
162
// / The location after which this override takes effect.
163
163
SourceLoc ApplicableFrom;
164
164
};
165
+
166
+ // / The current override, if set.
165
167
Optional<Override> Value;
166
168
167
169
public:
170
+ // / Clears this override.
171
+ void clear () { Value = None; }
172
+
168
173
// / Sets this override to make an IndentContext indent relative to the exact
169
174
// / column of AlignLoc if the IndentContext's ContextLoc is >= AlignLoc and
170
175
// / on the same line.
171
176
void setExact (SourceManager &SM, SourceLoc AlignLoc) {
172
177
Value = {AlignLoc, IndentContext::Exact, AlignLoc};
173
178
}
174
179
175
- // / Sets this override to propagate the given ContextLoc along to any
180
+ // / Sets this override to propagate the given ContextLoc and Kind along to any
176
181
// / IndentContext with a ContextLoc >= L and on the same line. If this
177
182
// / override's existing value applies to the provided ContextLoc, its
178
- // / ContextLoc is propagated instead.
183
+ // / ContextLoc and Kind are propagated instead.
179
184
// /
180
185
// / This propagation is necessary for cases like the trailing closure of 'bar'
181
186
// / in the example below. It's direct ContextLoc is 'bar', but we want
@@ -197,55 +202,47 @@ class ContextOverride {
197
202
if (R.isValid () && isOnSameLine (SM, L, R))
198
203
return ContextLoc;
199
204
200
- Override NewValue = {ContextLoc, Kind, L};
201
- if (Value) {
202
- // If the existing override applies to the same line, it's ContextLoc
203
- // should override this ContextLoc - don't propagate the intermediary.
204
- if (isOnSameLine (SM, Value->ApplicableFrom , NewValue.ApplicableFrom )) {
205
- assert (!SM.isBeforeInBuffer (NewValue.ContextLoc ,
206
- Value->ContextLoc ) &&
207
- " children walked before parents?" );
208
- return ContextLoc;
209
- }
210
- // Apply the existing value to NewValue before we overwrite it so its
211
- // ContextLoc propagates.
212
- applyIfNeeded (SM, NewValue.ContextLoc , NewValue.Kind );
213
- }
214
- Value = NewValue;
215
- return Value->ContextLoc ;
205
+ // Similarly if the ContextLoc and L are on the same line, there's no need
206
+ // to propagate. Overrides applicable to ContextLoc will already apply
207
+ // to child ranges on the same line as L.
208
+ if (isOnSameLine (SM, ContextLoc, L))
209
+ return ContextLoc;
210
+
211
+ applyIfNeeded (SM, ContextLoc, Kind);
212
+ Value = {ContextLoc, Kind, L};
213
+ return ContextLoc;
216
214
}
217
215
218
216
// / Applies the overriding ContextLoc and Kind to the given IndentContext if it
219
217
// / starts after ApplicableFrom and on the same line.
220
218
void applyIfNeeded (SourceManager &SM, IndentContext &Ctx) {
219
+ // Exactly aligned indent contexts should always set a matching exact
220
+ // alignment context override so child braces/parens/brackets are indented
221
+ // correctly. If the given innermost indent context is Exact and the
222
+ // override doesn't match its Kind and ContextLoc, something is wrong.
223
+ assert ((Ctx.Kind != IndentContext::Exact ||
224
+ (Value && Value->Kind == IndentContext::Exact &&
225
+ Value->ContextLoc == Ctx.ContextLoc )) &&
226
+ " didn't set override ctx when exact innermost context was set?" );
227
+
221
228
applyIfNeeded (SM, Ctx.ContextLoc , Ctx.Kind );
222
229
}
223
230
224
- // / Applies the overriding ContextLoc and Kind to the given ContextLoc and
225
- // / Kind if the given ContextLoc starts after ApplicableFrom and on the same
226
- // / line.
231
+ // / Applies the overriding ContextLoc and Kind to the given Override if its
232
+ // / ContextLoc starts after ApplicableFrom and on the same line.
227
233
void applyIfNeeded (SourceManager &SM, SourceLoc &ContextLoc,
228
234
IndentContext::ContextKind &Kind) {
229
- if (!Value)
230
- return ;
231
-
232
- if (!isOnSameLine (SM, ContextLoc, Value->ApplicableFrom ) ||
233
- SM.isBeforeInBuffer (ContextLoc, Value->ApplicableFrom ))
235
+ if (!isApplicableTo (SM, ContextLoc))
234
236
return ;
235
-
236
- // Exactly aligned indent contexts should always set a matching exact
237
- // alignment context override so child braces/parens/brackets are indented
238
- // correctly. If the given innermost indent context is Exact and the
239
- // override doesn't match its Kind and ContextLoc, something is wrong.
240
- assert ((Kind != IndentContext::Exact ||
241
- (Value->Kind == IndentContext::Exact &&
242
- ContextLoc == Value->ContextLoc )) &&
243
- " didn't set override ctx when exact innermost context was set?" );
244
237
ContextLoc = Value->ContextLoc ;
245
238
Kind = Value->Kind ;
246
239
}
247
240
248
- void clear () { Value = None; }
241
+ private:
242
+ bool isApplicableTo (SourceManager &SM, SourceLoc Loc) const {
243
+ return Value && isOnSameLine (SM, Loc, Value->ApplicableFrom ) &&
244
+ !SM.isBeforeInBuffer (Loc, Value->ApplicableFrom );
245
+ }
249
246
};
250
247
251
248
@@ -826,18 +823,23 @@ class OutdentChecker: protected RangeWalker {
826
823
}
827
824
828
825
SourceLoc propagateContextLocs (SourceLoc ContextLoc, SourceLoc L, SourceLoc R) {
826
+ bool HasSeparateContext = !isOnSameLine (SM, L, ContextLoc);
827
+
829
828
// Update ContextLoc for the currently active override on its line.
830
- ContextOverride &CtxOverride = getOverrideForLineContaining (ContextLoc);
829
+ ContextOverride &Upstream = getOverrideForLineContaining (ContextLoc);
831
830
IndentContext::ContextKind Kind = IndentContext::LineStart;
832
- CtxOverride .applyIfNeeded (SM, ContextLoc, Kind);
831
+ Upstream .applyIfNeeded (SM, ContextLoc, Kind);
833
832
834
- // If ContextLoc is L there's nothing to propagate.
835
- if (L == ContextLoc)
833
+ // If the original ContextLoc and L were on the same line, there's no need
834
+ // to propagate anything. Child ranges later on the same line will pick up
835
+ // whatever override we picked up above anyway, and if there wasn't
836
+ // one, their normal ContextLoc should already be correct.
837
+ if (!HasSeparateContext)
836
838
return ContextLoc;
837
839
838
- // Set an override to propagate the context loc onto the line of L.
839
- ContextOverride &Propagated = getOverrideForLineContaining (L);
840
- ContextLoc = Propagated .propagateContext (SM, ContextLoc,
840
+ // Set an override to propagate the context loc onto the line of L.
841
+ ContextOverride &Downstream = getOverrideForLineContaining (L);
842
+ ContextLoc = Downstream .propagateContext (SM, ContextLoc,
841
843
Kind, L, R);
842
844
return ContextLoc;
843
845
}
0 commit comments