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