23 #include "llvm/ADT/STLExtras.h" 24 #include "llvm/ADT/SmallVector.h" 25 #include "llvm/Support/Debug.h" 29 #define DEBUG_TYPE "format-formatter" 34 class FormatTokenLexer;
72 bool IsExport =
false;
98 if (LHS.
Category == JsModuleReference::ReferenceCategory::SIDE_EFFECT)
104 if (LHS.
URL.empty() != RHS.
URL.empty())
105 return LHS.
URL.empty() < RHS.
URL.empty();
106 if (
int Res = LHS.
URL.compare_lower(RHS.
URL))
123 FileContents(Env.getSourceManager().getBufferData(Env.getFileID())) {}
125 std::pair<tooling::Replacements, unsigned>
130 AffectedRangeMgr.computeAffectedLines(AnnotatedLines);
135 std::tie(References, FirstNonImportLine) =
136 parseModuleReferences(Keywords, AnnotatedLines);
138 if (References.empty())
142 for (
unsigned i = 0, e = References.size(); i != e; ++i)
143 Indices.push_back(i);
144 llvm::stable_sort(Indices, [&](
unsigned LHSI,
unsigned RHSI) {
145 return References[LHSI] < References[RHSI];
147 bool ReferencesInOrder = std::is_sorted(Indices.begin(), Indices.end());
149 std::string ReferencesText;
150 bool SymbolsInOrder =
true;
151 for (
unsigned i = 0, e = Indices.size(); i != e; ++i) {
153 if (appendReference(ReferencesText, Reference))
154 SymbolsInOrder =
false;
157 ReferencesText +=
"\n";
161 (Reference.
IsExport != References[Indices[i + 1]].IsExport ||
162 Reference.
Category != References[Indices[i + 1]].Category))
163 ReferencesText +=
"\n";
167 if (ReferencesInOrder && SymbolsInOrder)
171 InsertionPoint.
setEnd(References[References.size() - 1].Range.getEnd());
180 unsigned PreviousSize = getSourceText(InsertionPoint).size();
181 while (ReferencesText.size() < PreviousSize) {
182 ReferencesText +=
" ";
187 ReferencesText +=
"\n";
189 LLVM_DEBUG(llvm::dbgs() <<
"Replacing imports:\n" 190 << getSourceText(InsertionPoint) <<
"\nwith:\n" 191 << ReferencesText <<
"\n");
211 StringRef FileContents;
213 void skipComments() { Current = skipComments(Current); }
216 while (Tok && Tok->
is(tok::comment))
222 Current = Current->
Next;
224 if (!Current || Current == LineEnd->
Next) {
228 Current = &invalidToken;
252 if (Symbols == Reference.
Symbols) {
254 StringRef ReferenceStmt = getSourceText(Reference.
Range);
255 Buffer += ReferenceStmt;
261 Buffer += getSourceText(Reference.
Range.
getBegin(), SymbolsStart);
263 for (
auto I = Symbols.begin(), E = Symbols.end(); I != E; ++I) {
264 if (I != Symbols.begin())
266 Buffer += getSourceText(I->Range);
269 Buffer += getSourceText(SymbolsEnd, Reference.
Range.
getEnd());
276 std::pair<SmallVector<JsModuleReference, 16>,
AnnotatedLine *>
282 bool AnyImportAffected =
false;
283 for (
auto Line : AnnotatedLines) {
284 Current =
Line->First;
285 LineEnd =
Line->Last;
287 if (Start.
isInvalid() || References.empty())
291 Start =
Line->First->Tok.getLocation();
294 FirstNonImportLine =
Line;
299 if (!parseModuleReference(Keywords, Reference)) {
300 if (!FirstNonImportLine)
301 FirstNonImportLine =
Line;
304 FirstNonImportLine =
nullptr;
305 AnyImportAffected = AnyImportAffected ||
Line->Affected;
308 llvm::dbgs() <<
"JsModuleReference: {" 309 <<
"is_export: " << Reference.
IsExport 311 <<
", url: " << Reference.
URL 312 <<
", prefix: " << Reference.
Prefix;
313 for (
size_t i = 0; i < Reference.
Symbols.size(); ++i)
314 llvm::dbgs() <<
", " << Reference.
Symbols[i].Symbol <<
" as " 316 llvm::dbgs() <<
", text: " << getSourceText(Reference.
Range);
317 llvm::dbgs() <<
"}\n";
319 References.push_back(Reference);
323 if (!AnyImportAffected)
325 return std::make_pair(References, FirstNonImportLine);
335 Reference.
IsExport = Current->
is(tok::kw_export);
340 Reference.
Category = JsModuleReference::ReferenceCategory::SIDE_EFFECT;
346 if (!parseModuleBindings(Keywords, Reference))
357 if (Reference.
URL.startswith(
".."))
359 JsModuleReference::ReferenceCategory::RELATIVE_PARENT;
360 else if (Reference.
URL.startswith(
"."))
361 Reference.
Category = JsModuleReference::ReferenceCategory::RELATIVE;
363 Reference.
Category = JsModuleReference::ReferenceCategory::ABSOLUTE;
366 Reference.
Category = JsModuleReference::ReferenceCategory::RELATIVE;
373 if (parseStarBinding(Keywords, Reference))
375 return parseNamedBindings(Keywords, Reference);
381 if (Current->
isNot(tok::star))
387 if (Current->
isNot(tok::identifier))
396 if (Current->
is(tok::identifier)) {
400 if (Current->
isNot(tok::comma))
404 if (Current->
isNot(tok::l_brace))
408 while (Current->
isNot(tok::r_brace)) {
410 if (Current->
is(tok::r_brace))
412 if (!Current->
isOneOf(tok::identifier, tok::kw_default))
422 if (Current->
is(Keywords.
kw_as)) {
424 if (!Current->
isOneOf(tok::identifier, tok::kw_default))
430 Reference.
Symbols.push_back(Symbol);
432 if (!Current->
isOneOf(tok::r_brace, tok::comma))
443 StringRef FileName) {
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
Defines the SourceManager interface.
void setBegin(SourceLocation b)
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file implements a token annotator, i.e.
void setKind(tok::TokenKind K)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
Defines the Diagnostic-related interfaces.
const AnnotatedLine * Line
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
SourceLocation getEnd() const
static CharSourceRange getCharRange(SourceRange R)
unsigned getFileOffset(SourceLocation SpellingLoc) const
Returns the offset from the start of the file that the specified SourceLocation represents.
Encodes a location in the source.
Dataflow Directional Tag Classes.
This file implements a sorter for JavaScript ES6 imports.
This file declares an abstract TokenAnalyzer, and associated helper classes.
Defines the clang::SourceLocation class and associated facilities.
void setEnd(SourceLocation e)
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
This class handles loading and caching of source files into memory.
SourceLocation getEndLoc() const