Much better autocomplete for foreach loops

This commit is contained in:
Hackerpilot 2014-08-11 15:34:40 -07:00
parent 47113a4a2d
commit 94dd6860be
2 changed files with 69 additions and 6 deletions

View File

@ -129,7 +129,7 @@ final class FirstPass : ASTVisitor
if (dec.functionBody !is null) if (dec.functionBody !is null)
{ {
import std.algorithm; import std.algorithm;
size_t scopeBegin = dec.name.index; size_t scopeBegin = dec.name.index + dec.name.text.length;
size_t scopeEnd = max( size_t scopeEnd = max(
dec.functionBody.inStatement is null ? 0 : dec.functionBody.inStatement.blockStatement.endLocation, dec.functionBody.inStatement is null ? 0 : dec.functionBody.inStatement.blockStatement.endLocation,
dec.functionBody.outStatement is null ? 0 : dec.functionBody.outStatement.blockStatement.endLocation, dec.functionBody.outStatement is null ? 0 : dec.functionBody.outStatement.blockStatement.endLocation,
@ -423,6 +423,49 @@ final class FirstPass : ASTVisitor
tme.mixinTemplateName.symbol.identifierOrTemplateChain)); tme.mixinTemplateName.symbol.identifierOrTemplateChain));
} }
override void visit(const ForeachStatement feStatement)
{
if (feStatement.declarationOrStatement !is null
&& feStatement.declarationOrStatement.statement !is null
&& feStatement.declarationOrStatement.statement.statementNoCaseNoDefault !is null
&& feStatement.declarationOrStatement.statement.statementNoCaseNoDefault.blockStatement !is null)
{
const BlockStatement bs =
feStatement.declarationOrStatement.statement.statementNoCaseNoDefault.blockStatement;
Scope* s = allocate!Scope(semanticAllocator, feStatement.startIndex, bs.endLocation);
s.parent = currentScope;
currentScope.children.insert(s);
feExpression = feStatement.low.items[$ - 1];
feStatement.accept(this);
feExpression = null;
currentScope = currentScope.parent;
}
else
feStatement.accept(this);
}
override void visit(const ForeachTypeList feTypeList)
{
if (feTypeList.items.length == 1)
feTypeList.accept(this);
}
override void visit(const ForeachType feType)
{
// Log.trace("Handling foreachtype ", feType.identifier.text);
SemanticSymbol* symbol = allocateSemanticSymbol(
feType.identifier.text, CompletionKind.variableName,
symbolFile, feType.identifier.index, feType.type);
if (symbol.type is null && feExpression !is null)
{
// Log.trace("Populating initializer");
populateInitializer(symbol, feExpression, true);
// Log.trace(symbol.initializer[]);
}
symbol.parent = currentSymbol;
currentSymbol.addChild(symbol);
}
alias visit = ASTVisitor.visit; alias visit = ASTVisitor.visit;
/// Module scope /// Module scope
@ -544,9 +587,10 @@ private:
return internString(cast(string) app[]); return internString(cast(string) app[]);
} }
void populateInitializer(SemanticSymbol* symbol, const Initializer initializer) void populateInitializer(T)(SemanticSymbol* symbol, const T initializer,
bool appendForeach = false)
{ {
auto visitor = scoped!InitializerVisitor(symbol); auto visitor = scoped!InitializerVisitor(symbol, appendForeach);
visitor.visit(initializer); visitor.visit(initializer);
} }
@ -583,6 +627,8 @@ private:
Module mod; Module mod;
CAllocator semanticAllocator; CAllocator semanticAllocator;
Rebindable!(const AssignExpression) feExpression;
} }
void formatNode(A, T)(ref A appender, const T node) void formatNode(A, T)(ref A appender, const T node)
@ -626,9 +672,10 @@ static string convertChainToImportPath(const IdentifierChain ic)
class InitializerVisitor : ASTVisitor class InitializerVisitor : ASTVisitor
{ {
this (SemanticSymbol* semanticSymbol) this (SemanticSymbol* semanticSymbol, bool appendForeach = false)
{ {
this.semanticSymbol = semanticSymbol; this.semanticSymbol = semanticSymbol;
this.appendForeach = appendForeach;
} }
alias visit = ASTVisitor.visit; alias visit = ASTVisitor.visit;
@ -709,13 +756,16 @@ class InitializerVisitor : ASTVisitor
override void visit(const ArgumentList) {} override void visit(const ArgumentList) {}
override void visit(const Initializer initializer) override void visit(const AssignExpression initializer)
{ {
on = true; on = true;
initializer.accept(this); initializer.accept(this);
if (appendForeach)
semanticSymbol.initializer.insert("foreach");
on = false; on = false;
} }
SemanticSymbol* semanticSymbol; SemanticSymbol* semanticSymbol;
bool on = false; bool on = false;
const bool appendForeach;
} }

View File

@ -203,7 +203,20 @@ private:
{ {
s = s.type; s = s.type;
// Log.trace("resolveInitializerType: ", __LINE__, ":", slice.front); // Log.trace("resolveInitializerType: ", __LINE__, ":", slice.front);
if (slice.front == "[]") if (slice.front == "foreach")
{
if (s.qualifier == SymbolQualifier.array)
s = s.type;
else
{
ACSymbol*[] f = s.getPartsByName(internString("front"));
if (f.length > 0)
s = f[0].type;
else
s = null;
}
}
else if (slice.front == "[]")
s = s.type; s = s.type;
else else
{ {