Skip to content

Commit 02063b8

Browse files
committed
More import fixes
1 parent c97fca7 commit 02063b8

File tree

4 files changed

+98
-43
lines changed

4 files changed

+98
-43
lines changed

src/autocomplete.d

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -394,12 +394,25 @@ body
394394
HashSet!string h;
395395
foreach (s; symbols.parts[])
396396
{
397-
auto a = ACSymbol(s.name);
398-
if (!builtinSymbols.contains(&a) && !h.contains(s.name))
397+
if (s.kind == CompletionKind.importSymbol) foreach (sy; s.type.parts[])
399398
{
400-
response.completionKinds ~= s.kind;
401-
response.completions ~= s.name;
402-
h.insert(s.name);
399+
auto a = ACSymbol(sy.name);
400+
if (!builtinSymbols.contains(&a) && sy.name !is null && !h.contains(sy.name))
401+
{
402+
response.completionKinds ~= sy.kind;
403+
response.completions ~= sy.name;
404+
h.insert(sy.name);
405+
}
406+
}
407+
else
408+
{
409+
auto a = ACSymbol(s.name);
410+
if (!builtinSymbols.contains(&a) && s.name !is null && !h.contains(s.name))
411+
{
412+
response.completionKinds ~= s.kind;
413+
response.completions ~= s.name;
414+
h.insert(s.name);
415+
}
403416
}
404417
}
405418
response.completionType = CompletionType.identifiers;

src/conversion/second.d

Lines changed: 74 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -37,26 +37,48 @@ struct SecondPass
3737
{
3838
public:
3939

40+
/**
41+
* Construct this with the results of the first pass
42+
* Params:
43+
* first = the first pass
44+
*/
4045
this(FirstPass first)
4146
{
4247
this.rootSymbol = first.rootSymbol;
4348
this.moduleScope = first.moduleScope;
4449
this.symbolAllocator = first.symbolAllocator;
4550
}
4651

52+
/**
53+
* Runs the second pass on the module.
54+
*/
4755
void run()
4856
{
4957
rootSymbol.acSymbol.parts.insert(builtinSymbols[]);
5058
assignToScopes(rootSymbol.acSymbol);
5159
resolveImports(moduleScope);
5260
}
5361

62+
/**
63+
* Allocator used for allocating autocomplete symbols.
64+
*/
5465
CAllocator symbolAllocator;
66+
67+
/**
68+
* The root symbol from the first pass
69+
*/
5570
SemanticSymbol* rootSymbol;
71+
72+
/**
73+
* The module scope from the first pass
74+
*/
5675
Scope* moduleScope;
5776

5877
private:
5978

79+
/**
80+
* Assigns symbols to scopes based on their location.
81+
*/
6082
void assignToScopes(ACSymbol* currentSymbol)
6183
{
6284
Scope* s = moduleScope.getScopeByCursor(currentSymbol.location);
@@ -71,12 +93,19 @@ private:
7193

7294
/**
7395
* Creates package symbols as necessary to contain the given module symbol
96+
* Params:
97+
* info = the import information for the module being imported
98+
* currentScope = the scope in which the import statement is located
99+
* moduleSymbol = the module being imported
100+
* Returns: A package symbol that can be used for auto-completing qualified
101+
* symbol names.
74102
*/
75103
ACSymbol* createImportSymbols(ImportInformation* info, Scope* currentScope,
76104
ACSymbol* moduleSymbol)
77105
in
78106
{
79107
assert (info !is null);
108+
assert (currentScope !is null);
80109
assert (moduleSymbol !is null);
81110
}
82111
body
@@ -89,7 +118,6 @@ private:
89118
else
90119
firstSymbol = allocate!ACSymbol(symbolAllocator, firstPart,
91120
CompletionKind.packageName);
92-
currentScope.symbols.insert(firstSymbol);
93121
ACSymbol* currentSymbol = firstSymbol;
94122
size_t i = 0;
95123
foreach (string importPart; info.importParts[])
@@ -99,9 +127,17 @@ private:
99127
if (i + 2 >= info.importParts.length) // Skip the last item as it's the module name
100128
break;
101129
symbols = currentSymbol.getPartsByName(importPart);
102-
ACSymbol* s = symbols.length > 0
103-
? cast(ACSymbol*) symbols[0] : allocate!ACSymbol(symbolAllocator,
104-
importPart, CompletionKind.packageName);
130+
ACSymbol* s = null;
131+
if (symbols.length > 0) foreach (sy; symbols)
132+
{
133+
if (sy.kind == CompletionKind.packageName)
134+
{
135+
s = sy;
136+
break;
137+
}
138+
}
139+
if (s is null)
140+
s = allocate!ACSymbol(symbolAllocator, importPart, CompletionKind.packageName);
105141
currentSymbol.parts.insert(s);
106142
currentSymbol = s;
107143
}
@@ -120,45 +156,50 @@ private:
120156
if (symbol is null)
121157
continue;
122158
ACSymbol* moduleSymbol = createImportSymbols(importInfo, currentScope, symbol);
123-
currentScope.symbols.insert(symbol.parts[]);
124159
if (importInfo.importedSymbols.length == 0)
125160
{
126161
if (importInfo.isPublic && currentScope.parent is null)
127-
{
128162
rootSymbol.acSymbol.parts.insert(allocate!ACSymbol(symbolAllocator,
129163
IMPORT_SYMBOL_NAME, CompletionKind.importSymbol, symbol));
130-
}
164+
else
165+
currentScope.symbols.insert(symbol.parts[]);
131166
continue;
132167
}
133-
symbolLoop: foreach (sym; symbol.parts[])
168+
169+
foreach (tup; importInfo.importedSymbols[])
134170
{
135-
foreach (tup; importInfo.importedSymbols[])
171+
ACSymbol needle = ACSymbol(tup[0]);
172+
ACSymbol* sym;
173+
auto r = symbol.parts.equalRange(&needle);
174+
if (r.empty) foreach (sy; symbol.parts[])
136175
{
137-
if (tup[0] != symbol.name)
138-
continue symbolLoop;
139-
if (tup[1] !is null)
140-
{
141-
ACSymbol* s = allocate!ACSymbol(symbolAllocator, tup[1],
142-
sym.kind, sym.type);
143-
s.parts.insert(sym.parts[]);
144-
s.callTip = sym.callTip;
145-
s.doc = sym.doc;
146-
s.qualifier = sym.qualifier;
147-
s.location = sym.location;
148-
s.symbolFile = sym.symbolFile;
149-
currentScope.symbols.insert(s);
150-
moduleSymbol.parts.insert(s);
151-
if (importInfo.isPublic && currentScope.parent is null)
152-
rootSymbol.acSymbol.parts.insert(s);
153-
}
154-
else
155-
{
156-
moduleSymbol.parts.insert(sym);
157-
currentScope.symbols.insert(sym);
158-
if (importInfo.isPublic && currentScope.parent is null)
159-
rootSymbol.acSymbol.parts.insert(sym);
160-
}
176+
if (sy.kind != CompletionKind.importSymbol || sy.type is null)
177+
continue;
178+
auto ra = sy.type.parts.equalRange(&needle);
179+
if (ra.empty)
180+
continue;
181+
sym = ra.front;
161182
}
183+
else
184+
sym = r.front;
185+
if (sym is null)
186+
continue;
187+
if (tup[1] !is null)
188+
{
189+
ACSymbol* s = allocate!ACSymbol(symbolAllocator, tup[1],
190+
sym.kind, sym.type);
191+
s.parts.insert(sym.parts[]);
192+
s.callTip = sym.callTip;
193+
s.doc = sym.doc;
194+
s.qualifier = sym.qualifier;
195+
s.location = sym.location;
196+
s.symbolFile = sym.symbolFile;
197+
sym = s;
198+
}
199+
moduleSymbol.parts.insert(sym);
200+
currentScope.symbols.insert(sym);
201+
if (importInfo.isPublic && currentScope.parent is null)
202+
rootSymbol.acSymbol.parts.insert(sym);
162203
}
163204
}
164205
foreach (childScope; currentScope.children)

src/modulecache.d

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ static this()
9595
*/
9696
struct ModuleCache
9797
{
98+
/// No copying.
9899
@disable this();
99100

100101
/**
@@ -219,7 +220,7 @@ struct ModuleCache
219220
{
220221
string dotDi = buildPath(path, moduleName) ~ ".di";
221222
string dotD = dotDi[0 .. $ - 1];
222-
string withoutSuffix = dotDi[0 .. $ - 2];
223+
string withoutSuffix = dotDi[0 .. $ - 3];
223224
if (exists(dotD) && isFile(dotD))
224225
alternatives = (dotD) ~ alternatives;
225226
else if (exists(dotDi) && isFile(dotDi))
@@ -244,6 +245,7 @@ struct ModuleCache
244245
return importPaths[];
245246
}
246247

248+
/// Count of autocomplete symbols that have been allocated
247249
static uint symbolsAllocated;
248250

249251
private:

src/server.d

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,9 @@ int main(string[] args)
9999
scope(exit) Mallocator.it.deallocate(buffer);
100100

101101
sw.stop();
102-
Log.info("Startup completed in ", sw.peek().to!("msecs", float), " milliseconds");
103-
// float symbolMegs = (cast(float) (ACSymbol.sizeof * ModuleCache.symbolsAllocated)) / (1024f * 1024f);
104-
// Log.info(ModuleCache.symbolsAllocated, " symbols allocated, taking up ",
105-
// symbolMegs, " megabytes");
102+
Log.info(ModuleCache.symbolsAllocated, " symbols cached.");
103+
Log.info("Startup completed in ", sw.peek().to!("msecs", float), " milliseconds.");
104+
106105

107106
// No relative paths
108107
version (Posix) chdir("/");

0 commit comments

Comments
 (0)