15
15
#include " SourceKit/Support/Concurrency.h"
16
16
#include " TestOptions.h"
17
17
#include " swift/Demangling/ManglingMacros.h"
18
- #include " clang/Rewrite/Core/RewriteBuffer.h"
19
18
#include " llvm/ADT/ArrayRef.h"
20
19
#include " llvm/ADT/IntrusiveRefCntPtr.h"
21
20
#include " llvm/ADT/Optional.h"
@@ -2088,53 +2087,85 @@ static void printStatistics(sourcekitd_variant_t Info, raw_ostream &OS) {
2088
2087
});
2089
2088
}
2090
2089
2091
- static void initializeRewriteBuffer (StringRef Input,
2092
- clang::RewriteBuffer &RewriteBuf) {
2093
- RewriteBuf.Initialize (Input);
2094
- StringRef CheckStr = " CHECK" ;
2095
- size_t Pos = 0 ;
2096
- while (true ) {
2097
- Pos = Input.find (CheckStr, Pos);
2098
- if (Pos == StringRef::npos)
2099
- break ;
2100
- Pos = Input.substr (0 , Pos).rfind (" //" );
2101
- assert (Pos != StringRef::npos);
2102
- size_t EndLine = Input.find (' \n ' , Pos);
2103
- assert (EndLine != StringRef::npos);
2104
- ++EndLine;
2105
- RewriteBuf.RemoveText (Pos, EndLine-Pos);
2106
- Pos = EndLine;
2090
+ static std::string initializeSource (StringRef Input) {
2091
+ std::string result;
2092
+ {
2093
+ llvm::raw_string_ostream OS (result);
2094
+ StringRef CheckStr = " CHECK" ;
2095
+ size_t Pos = 0 ;
2096
+ while (true ) {
2097
+ auto checkPos = Input.find (CheckStr, Pos);
2098
+ if (checkPos == StringRef::npos)
2099
+ break ;
2100
+ checkPos = Input.substr (0 , checkPos).rfind (" //" );
2101
+ assert (checkPos != StringRef::npos);
2102
+ size_t EndLine = Input.find (' \n ' , checkPos);
2103
+ assert (EndLine != StringRef::npos);
2104
+ ++EndLine;
2105
+ OS << Input.slice (Pos, checkPos);
2106
+ Pos = EndLine;
2107
+ }
2108
+
2109
+ OS << Input.slice (Pos, StringRef::npos);
2107
2110
}
2111
+ return result;
2108
2112
}
2109
2113
2110
- static std::vector <std::pair<unsigned , unsigned >>
2111
- getPlaceholderRanges (StringRef Source) {
2114
+ static Optional <std::pair<unsigned , unsigned >>
2115
+ firstPlaceholderRange (StringRef Source, unsigned from ) {
2112
2116
const char *StartPtr = Source.data ();
2113
- std::vector<std::pair<unsigned , unsigned >> Ranges;
2117
+ Source = Source.drop_front (from);
2118
+
2114
2119
while (true ) {
2115
2120
size_t Pos = Source.find (" <#" );
2116
2121
if (Pos == StringRef::npos)
2117
2122
break ;
2118
2123
unsigned OffsetStart = Source.data () + Pos - StartPtr;
2119
2124
Source = Source.substr (Pos+2 );
2125
+ if (Source.startswith (" __skip__" ) || Source.startswith (" T##__skip__" ))
2126
+ continue ;
2120
2127
Pos = Source.find (" #>" );
2121
2128
if (Pos == StringRef::npos)
2122
2129
break ;
2123
2130
unsigned OffsetEnd = Source.data () + Pos + 2 - StartPtr;
2124
2131
Source = Source.substr (Pos+2 );
2125
- Ranges. emplace_back (OffsetStart, OffsetEnd-OffsetStart);
2132
+ return std::make_pair (OffsetStart, OffsetEnd-OffsetStart);
2126
2133
}
2127
- return Ranges ;
2134
+ return llvm::None ;
2128
2135
}
2129
2136
2130
2137
static void expandPlaceholders (llvm::MemoryBuffer *SourceBuf,
2131
2138
llvm::raw_ostream &OS) {
2132
- clang::RewriteBuffer RewriteBuf;
2133
- initializeRewriteBuffer (SourceBuf->getBuffer (), RewriteBuf);
2134
- auto Ranges = getPlaceholderRanges (SourceBuf->getBuffer ());
2135
- for (auto Range : Ranges) {
2136
- unsigned Offset = Range.first ;
2137
- unsigned Length = Range.second ;
2139
+ auto syncEdit = [=](unsigned offset, unsigned length, const char *text) {
2140
+ auto SourceBufID = SourceBuf->getBufferIdentifier ();
2141
+ auto req = sourcekitd_request_dictionary_create (nullptr , nullptr , 0 );
2142
+ sourcekitd_request_dictionary_set_uid (req, KeyRequest,
2143
+ RequestEditorReplaceText);
2144
+ sourcekitd_request_dictionary_set_stringbuf (req, KeyName,
2145
+ SourceBufID.data (),
2146
+ SourceBufID.size ());
2147
+ sourcekitd_request_dictionary_set_int64 (req, KeyOffset, offset);
2148
+ sourcekitd_request_dictionary_set_int64 (req, KeyLength, length);
2149
+ sourcekitd_request_dictionary_set_string (req, KeySourceText, text);
2150
+
2151
+ sourcekitd_response_t resp = sourcekitd_send_request_sync (req);
2152
+ if (sourcekitd_response_is_error (resp)) {
2153
+ sourcekitd_response_description_dump (resp);
2154
+ exit (1 );
2155
+ }
2156
+ sourcekitd_request_release (req);
2157
+ sourcekitd_response_dispose (resp);
2158
+ };
2159
+
2160
+ std::string source = initializeSource (SourceBuf->getBuffer ());
2161
+ // Sync contents with modified source.
2162
+ syncEdit (0 , SourceBuf->getBuffer ().size (), source.c_str ());
2163
+
2164
+ unsigned cursor = 0 ;
2165
+
2166
+ while (auto Range = firstPlaceholderRange (source, cursor)) {
2167
+ unsigned Offset = Range->first ;
2168
+ unsigned Length = Range->second ;
2138
2169
sourcekitd_object_t Exp = sourcekitd_request_dictionary_create (nullptr ,
2139
2170
nullptr , 0 );
2140
2171
sourcekitd_request_dictionary_set_uid (Exp, KeyRequest,
@@ -2156,16 +2187,25 @@ static void expandPlaceholders(llvm::MemoryBuffer *SourceBuf,
2156
2187
sourcekitd_variant_t Info = sourcekitd_response_get_value (Resp);
2157
2188
const char *Text = sourcekitd_variant_dictionary_get_string (Info, KeySourceText);
2158
2189
if (!Text) {
2190
+ cursor = Offset + Length;
2159
2191
sourcekitd_response_dispose (Resp);
2160
2192
continue ;
2161
2193
}
2162
2194
unsigned EditOffset = sourcekitd_variant_dictionary_get_int64 (Info, KeyOffset);
2163
2195
unsigned EditLength = sourcekitd_variant_dictionary_get_int64 (Info, KeyLength);
2164
- RewriteBuf.ReplaceText (EditOffset, EditLength, Text);
2196
+
2197
+ // Apply edit locally.
2198
+ source.replace (EditOffset, EditLength, Text);
2199
+
2200
+ // Apply edit on server.
2201
+ syncEdit (EditOffset, EditLength, Text);
2202
+
2203
+ // Adjust cursor to after the edit (we do not expand recursively).
2204
+ cursor = EditOffset + strlen (Text);
2165
2205
sourcekitd_response_dispose (Resp);
2166
2206
}
2167
2207
2168
- RewriteBuf. write (OS) ;
2208
+ OS << source ;
2169
2209
}
2170
2210
2171
2211
static std::pair<unsigned , unsigned >
0 commit comments