Fix autocompletion with alias this. Added struct constructor calltips to fix #113

This commit is contained in:
Hackerpilot 2014-07-10 14:44:09 -07:00
parent 1afdec1c63
commit f17b25e1dc
3 changed files with 55 additions and 7 deletions

View File

@ -107,7 +107,11 @@ public:
ACSymbol*[] getPartsByName(string name) ACSymbol*[] getPartsByName(string name)
{ {
ACSymbol s = ACSymbol(name); ACSymbol s = ACSymbol(name);
return array(parts.equalRange(&s)); auto er = parts.equalRange(&s);
if (er.empty)
return array(aliasThisParts.equalRange(&s));
else
return array(er);
} }
/** /**
@ -121,6 +125,11 @@ public:
*/ */
TTree!(ACSymbol*, true, "a < b", false) parts; TTree!(ACSymbol*, true, "a < b", false) parts;
/**
* Symbols included due to an alias this.
*/
TTree!(ACSymbol*, true, "a < b", false) aliasThisParts;
/** /**
* Calltip to display if this is a function * Calltip to display if this is a function
*/ */
@ -315,7 +324,7 @@ TTree!(ACSymbol*, true, "a < b", false) arraySymbols;
TTree!(ACSymbol*, true, "a < b", false) assocArraySymbols; TTree!(ACSymbol*, true, "a < b", false) assocArraySymbols;
/** /**
* Enum, union, class, and interface properties * Struct, enum, union, class, and interface properties
*/ */
TTree!(ACSymbol*, true, "a < b", false) aggregateSymbols; TTree!(ACSymbol*, true, "a < b", false) aggregateSymbols;
@ -508,7 +517,7 @@ static this()
s.parts.insert(stringof_); s.parts.insert(stringof_);
} }
aggregateSymbols.insert(allocate!ACSymbol(Mallocator.it, "tupleof", CompletionKind.variableName)); aggregateSymbols.insert(allocate!ACSymbol(Mallocator.it, "tupleof", CompletionKind.keyword));
aggregateSymbols.insert(mangleof_); aggregateSymbols.insert(mangleof_);
aggregateSymbols.insert(alignof_); aggregateSymbols.insert(alignof_);
aggregateSymbols.insert(sizeof_); aggregateSymbols.insert(sizeof_);

View File

@ -185,7 +185,6 @@ AutocompleteResponse complete(const AutocompleteRequest request)
case tok!"[": case tok!"[":
case tok!";": case tok!";":
case tok!":": case tok!":":
// TODO: global scope
break; break;
default: default:
break; break;
@ -501,6 +500,7 @@ void setCompletions(T)(ref AutocompleteResponse response,
if (completionType == CompletionType.identifiers) if (completionType == CompletionType.identifiers)
{ {
import containers.ttree;
if (symbols[0].qualifier == SymbolQualifier.func if (symbols[0].qualifier == SymbolQualifier.func
|| symbols[0].kind == CompletionKind.functionName) || symbols[0].kind == CompletionKind.functionName)
{ {
@ -509,7 +509,10 @@ void setCompletions(T)(ref AutocompleteResponse response,
if (symbols.length == 0) if (symbols.length == 0)
return; return;
} }
foreach (s; symbols[0].parts[].filter!(a => a.name !is null TTree!(ACSymbol*, true, "a < b", false) parts;
parts.insert(symbols[0].parts[]);
parts.insert(symbols[0].aliasThisParts[]);
foreach (s; parts[].filter!(a => a.name !is null
&& a.name.length > 0 && a.name[0] != '*' && a.name.length > 0 && a.name[0] != '*'
&& (partial is null ? true : a.name.toUpper().startsWith(partial.toUpper())) && (partial is null ? true : a.name.toUpper().startsWith(partial.toUpper()))
&& !response.completions.canFind(a.name))) && !response.completions.canFind(a.name)))
@ -550,7 +553,15 @@ void setCompletions(T)(ref AutocompleteResponse response,
{ {
auto constructor = symbols[0].getPartsByName("*constructor*"); auto constructor = symbols[0].getPartsByName("*constructor*");
if (constructor.length == 0) if (constructor.length == 0)
return; {
// Build a call tip out of the struct fields
if (symbols[0].kind == CompletionKind.structName)
{
response.completionType = CompletionType.calltips;
response.completions = [generateStructConstructorCalltip(symbols[0])];
return;
}
}
else else
{ {
symbols = constructor; symbols = constructor;
@ -568,6 +579,34 @@ void setCompletions(T)(ref AutocompleteResponse response,
} }
} }
string generateStructConstructorCalltip(const ACSymbol* symbol)
in
{
assert (symbol.kind == CompletionKind.structName);
}
body
{
string generatedStructConstructorCalltip = "this(";
size_t i = 0;
immutable c = count(symbol.parts[].filter!(a => a.kind == CompletionKind.variableName));
foreach (part; array(symbol.parts[]).sort!((a, b) => a.location < b.location))
{
if (part.kind != CompletionKind.variableName)
continue;
i++;
if (part.type !is null)
{
generatedStructConstructorCalltip ~= part.type.name;
generatedStructConstructorCalltip ~= " ";
}
generatedStructConstructorCalltip ~= part.name;
if (i < c)
generatedStructConstructorCalltip ~= ", ";
}
generatedStructConstructorCalltip ~= ")";
return generatedStructConstructorCalltip;
}
/** /**
* *
*/ */

View File

@ -145,7 +145,7 @@ private:
auto parts = currentSymbol.acSymbol.getPartsByName(aliasThis); auto parts = currentSymbol.acSymbol.getPartsByName(aliasThis);
if (parts.length == 0 || parts[0].type is null) if (parts.length == 0 || parts[0].type is null)
continue; continue;
currentSymbol.acSymbol.parts.insert(parts[0].type.parts[]); currentSymbol.acSymbol.aliasThisParts.insert(parts[0].type.parts[]);
} }
} }