Better lifetime management

This commit is contained in:
Hackerpilot 2015-06-15 04:18:42 -07:00
parent ff1ff2d067
commit 9e253f966a
1 changed files with 31 additions and 17 deletions

View File

@ -63,11 +63,11 @@ public AutocompleteResponse getDoc(const AutocompleteRequest request)
AutocompleteResponse response; AutocompleteResponse response;
auto allocator = scoped!(ASTAllocator)(); auto allocator = scoped!(ASTAllocator)();
auto cache = StringCache(StringCache.defaultBucketCount); auto cache = StringCache(StringCache.defaultBucketCount);
DSymbol*[] symbols = getSymbolsForCompletion(request, CompletionType.ddoc, ScopeSymbolPair pair = getSymbolsForCompletion(request, CompletionType.ddoc,
allocator, &cache); allocator, &cache);
if (symbols.length == 0) if (pair.symbols.length == 0)
warning("Could not find symbol"); warning("Could not find symbol");
else foreach (symbol; symbols.filter!(a => !a.doc.empty)) else foreach (symbol; pair.symbols.filter!(a => !a.doc.empty))
response.docComments ~= formatComment(symbol.doc); response.docComments ~= formatComment(symbol.doc);
return response; return response;
} }
@ -84,12 +84,12 @@ public AutocompleteResponse findDeclaration(const AutocompleteRequest request)
AutocompleteResponse response; AutocompleteResponse response;
auto allocator = scoped!(ASTAllocator)(); auto allocator = scoped!(ASTAllocator)();
auto cache = StringCache(StringCache.defaultBucketCount); auto cache = StringCache(StringCache.defaultBucketCount);
DSymbol*[] symbols = getSymbolsForCompletion(request, ScopeSymbolPair pair = getSymbolsForCompletion(request,
CompletionType.location, allocator, &cache); CompletionType.location, allocator, &cache);
if (symbols.length > 0) if (pair.symbols.length > 0)
{ {
response.symbolLocation = symbols[0].location; response.symbolLocation = pair.symbols[0].location;
response.symbolFilePath = symbols[0].symbolFile.idup; response.symbolFilePath = pair.symbols[0].symbolFile.idup;
} }
else else
warning("Could not find symbol declaration"); warning("Could not find symbol declaration");
@ -322,6 +322,21 @@ auto getTokensBeforeCursor(const(ubyte[]) sourceCode, size_t cursorPosition,
return sortedTokens.lowerBound(cast(size_t) cursorPosition); return sortedTokens.lowerBound(cast(size_t) cursorPosition);
} }
struct ScopeSymbolPair
{
~this()
{
if (scope_ !is null)
{
scope_.destroySymbols();
typeid(Scope).destroy(scope_);
}
}
DSymbol*[] symbols;
Scope* scope_;
}
/** /**
* Params: * Params:
* request = the autocompletion request * request = the autocompletion request
@ -330,17 +345,16 @@ auto getTokensBeforeCursor(const(ubyte[]) sourceCode, size_t cursorPosition,
* all symbols that should be considered for the autocomplete list based on * all symbols that should be considered for the autocomplete list based on
* the request's source code, cursor position, and completion type. * the request's source code, cursor position, and completion type.
*/ */
DSymbol*[] getSymbolsForCompletion(const AutocompleteRequest request, ScopeSymbolPair getSymbolsForCompletion(const AutocompleteRequest request,
const CompletionType type, IAllocator allocator, StringCache* cache) const CompletionType type, IAllocator allocator, StringCache* cache)
{ {
const(Token)[] tokenArray; const(Token)[] tokenArray;
auto beforeTokens = getTokensBeforeCursor(request.sourceCode, auto beforeTokens = getTokensBeforeCursor(request.sourceCode,
request.cursorPosition, cache, tokenArray); request.cursorPosition, cache, tokenArray);
Scope* completionScope = generateAutocompleteTrees(tokenArray, allocator); Scope* completionScope = generateAutocompleteTrees(tokenArray, allocator);
scope(exit) typeid(Scope).destroy(completionScope);
auto expression = getExpression(beforeTokens); auto expression = getExpression(beforeTokens);
return getSymbolsByTokenChain(completionScope, expression, return ScopeSymbolPair(getSymbolsByTokenChain(completionScope, expression,
request.cursorPosition, type); request.cursorPosition, type), completionScope);
} }
/** /**
@ -550,9 +564,9 @@ body
} }
} }
foreach (s; symbols.parts[]) foreach (s; symbols.opSlice())
{ {
if (s.kind == CompletionKind.importSymbol) foreach (sy; s.type.parts[]) if (s.kind == CompletionKind.importSymbol) foreach (sy; s.type.opSlice())
addSymbolToResponses(sy); addSymbolToResponses(sy);
else else
addSymbolToResponses(s); addSymbolToResponses(s);
@ -825,9 +839,9 @@ void setCompletions(T)(ref AutocompleteResponse response,
if (symbols.length == 0) if (symbols.length == 0)
return; return;
} }
foreach (sym; symbols[0].parts[]) foreach (sym; symbols[0].opSlice())
{ {
if (sym.kind == CompletionKind.importSymbol) foreach (s; sym.type.parts[]) if (sym.kind == CompletionKind.importSymbol) foreach (s; sym.type.opSlice())
{ {
response.completionKinds ~= s.kind; response.completionKinds ~= s.kind;
response.completions ~= s.name.dup; response.completions ~= s.name.dup;
@ -916,8 +930,8 @@ body
{ {
string generatedStructConstructorCalltip = "this("; string generatedStructConstructorCalltip = "this(";
size_t i = 0; size_t i = 0;
immutable c = count(symbol.parts[].filter!(a => a.kind == CompletionKind.variableName)); immutable c = count(symbol.opSlice().filter!(a => a.kind == CompletionKind.variableName));
foreach (part; array(symbol.parts[]).sort!((a, b) => a.location < b.location)) foreach (part; array(symbol.opSlice()).sort!((a, b) => a.location < b.location))
{ {
if (part.kind != CompletionKind.variableName) if (part.kind != CompletionKind.variableName)
continue; continue;