Adding return type symbol (#720)
This commit is contained in:
parent
92f2d73731
commit
1b67f493d4
|
@ -37,6 +37,7 @@ import std.experimental.allocator;
|
||||||
import std.experimental.allocator.gc_allocator : GCAllocator;
|
import std.experimental.allocator.gc_allocator : GCAllocator;
|
||||||
import std.experimental.logger;
|
import std.experimental.logger;
|
||||||
import std.typecons : Rebindable;
|
import std.typecons : Rebindable;
|
||||||
|
import std.array : appender;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* First Pass handles the following:
|
* First Pass handles the following:
|
||||||
|
@ -148,6 +149,10 @@ final class FirstPass : ASTVisitor
|
||||||
processParameters(currentSymbol, dec.returnType,
|
processParameters(currentSymbol, dec.returnType,
|
||||||
currentSymbol.acSymbol.name, dec.parameters, dec.templateParameters);
|
currentSymbol.acSymbol.name, dec.parameters, dec.templateParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dec.returnType !is null){
|
||||||
|
addTypeToLookups(currentSymbol.typeLookups, dec.returnType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override void visit(const FunctionLiteralExpression exp)
|
override void visit(const FunctionLiteralExpression exp)
|
||||||
|
@ -778,7 +783,6 @@ private:
|
||||||
|
|
||||||
void createConstructor()
|
void createConstructor()
|
||||||
{
|
{
|
||||||
import std.array : appender;
|
|
||||||
import std.range : zip;
|
import std.range : zip;
|
||||||
|
|
||||||
auto app = appender!string();
|
auto app = appender!string();
|
||||||
|
@ -1064,7 +1068,6 @@ private:
|
||||||
istring formatCallTip(const Type returnType, string name,
|
istring formatCallTip(const Type returnType, string name,
|
||||||
const Parameters parameters, const TemplateParameters templateParameters)
|
const Parameters parameters, const TemplateParameters templateParameters)
|
||||||
{
|
{
|
||||||
import std.array : appender;
|
|
||||||
|
|
||||||
auto app = appender!string();
|
auto app = appender!string();
|
||||||
if (returnType !is null)
|
if (returnType !is null)
|
||||||
|
@ -1136,7 +1139,6 @@ private:
|
||||||
lookup.breadcrumbs.insert(POINTER_SYMBOL_NAME);
|
lookup.breadcrumbs.insert(POINTER_SYMBOL_NAME);
|
||||||
else if (suffix.delegateOrFunction != tok!"")
|
else if (suffix.delegateOrFunction != tok!"")
|
||||||
{
|
{
|
||||||
import std.array : appender;
|
|
||||||
auto app = appender!string();
|
auto app = appender!string();
|
||||||
formatNode(app, type);
|
formatNode(app, type);
|
||||||
istring callTip = istring(app.data);
|
istring callTip = istring(app.data);
|
||||||
|
@ -1341,7 +1343,6 @@ void writeIotcTo(T)(const IdentifierOrTemplateChain iotc, ref T output) nothrow
|
||||||
static istring convertChainToImportPath(const IdentifierChain ic)
|
static istring convertChainToImportPath(const IdentifierChain ic)
|
||||||
{
|
{
|
||||||
import std.path : dirSeparator;
|
import std.path : dirSeparator;
|
||||||
import std.array : appender;
|
|
||||||
auto app = appender!string();
|
auto app = appender!string();
|
||||||
foreach (i, ident; ic.identifiers)
|
foreach (i, ident; ic.identifiers)
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,6 +33,8 @@ import std.experimental.allocator.gc_allocator : GCAllocator;
|
||||||
import std.experimental.logger;
|
import std.experimental.logger;
|
||||||
import dparse.ast;
|
import dparse.ast;
|
||||||
import dparse.lexer;
|
import dparse.lexer;
|
||||||
|
import std.algorithm : filter;
|
||||||
|
import std.range;
|
||||||
|
|
||||||
void secondPass(SemanticSymbol* currentSymbol, Scope* moduleScope, ref ModuleCache cache)
|
void secondPass(SemanticSymbol* currentSymbol, Scope* moduleScope, ref ModuleCache cache)
|
||||||
{
|
{
|
||||||
|
@ -312,8 +314,6 @@ private:
|
||||||
void resolveInheritance(DSymbol* symbol, ref TypeLookups typeLookups,
|
void resolveInheritance(DSymbol* symbol, ref TypeLookups typeLookups,
|
||||||
Scope* moduleScope, ref ModuleCache cache)
|
Scope* moduleScope, ref ModuleCache cache)
|
||||||
{
|
{
|
||||||
import std.algorithm : filter;
|
|
||||||
|
|
||||||
outer: foreach (TypeLookup* lookup; typeLookups[])
|
outer: foreach (TypeLookup* lookup; typeLookups[])
|
||||||
{
|
{
|
||||||
if (lookup.kind != TypeLookupKind.inherit)
|
if (lookup.kind != TypeLookupKind.inherit)
|
||||||
|
@ -355,9 +355,6 @@ void resolveInheritance(DSymbol* symbol, ref TypeLookups typeLookups,
|
||||||
void resolveAliasThis(DSymbol* symbol,
|
void resolveAliasThis(DSymbol* symbol,
|
||||||
ref TypeLookups typeLookups, Scope* moduleScope, ref ModuleCache cache)
|
ref TypeLookups typeLookups, Scope* moduleScope, ref ModuleCache cache)
|
||||||
{
|
{
|
||||||
import std.algorithm : filter;
|
|
||||||
import std.array : array;
|
|
||||||
|
|
||||||
foreach (aliasThis; typeLookups[].filter!(a => a.kind == TypeLookupKind.aliasThis))
|
foreach (aliasThis; typeLookups[].filter!(a => a.kind == TypeLookupKind.aliasThis))
|
||||||
{
|
{
|
||||||
assert(aliasThis.breadcrumbs.length > 0);
|
assert(aliasThis.breadcrumbs.length > 0);
|
||||||
|
@ -379,8 +376,6 @@ void resolveAliasThis(DSymbol* symbol,
|
||||||
void resolveMixinTemplates(DSymbol* symbol,
|
void resolveMixinTemplates(DSymbol* symbol,
|
||||||
ref TypeLookups typeLookups, Scope* moduleScope, ref ModuleCache cache)
|
ref TypeLookups typeLookups, Scope* moduleScope, ref ModuleCache cache)
|
||||||
{
|
{
|
||||||
import std.algorithm : filter;
|
|
||||||
|
|
||||||
foreach (mix; typeLookups[].filter!(a => a.kind == TypeLookupKind.mixinTemplate))
|
foreach (mix; typeLookups[].filter!(a => a.kind == TypeLookupKind.mixinTemplate))
|
||||||
{
|
{
|
||||||
assert(mix.breadcrumbs.length > 0);
|
assert(mix.breadcrumbs.length > 0);
|
||||||
|
@ -414,13 +409,8 @@ void resolveMixinTemplates(DSymbol* symbol,
|
||||||
void resolveType(DSymbol* symbol, ref TypeLookups typeLookups,
|
void resolveType(DSymbol* symbol, ref TypeLookups typeLookups,
|
||||||
Scope* moduleScope, ref ModuleCache cache)
|
Scope* moduleScope, ref ModuleCache cache)
|
||||||
{
|
{
|
||||||
|
// going through the lookups
|
||||||
import std.conv;
|
foreach(lookup; typeLookups) {
|
||||||
|
|
||||||
if (typeLookups.length == 0)
|
|
||||||
return;
|
|
||||||
assert(typeLookups.length == 1);
|
|
||||||
auto lookup = typeLookups.front;
|
|
||||||
if (lookup.kind == TypeLookupKind.varOrFunType)
|
if (lookup.kind == TypeLookupKind.varOrFunType)
|
||||||
resolveTypeFromType(symbol, lookup, moduleScope, cache, null);
|
resolveTypeFromType(symbol, lookup, moduleScope, cache, null);
|
||||||
else if (lookup.kind == TypeLookupKind.initializer)
|
else if (lookup.kind == TypeLookupKind.initializer)
|
||||||
|
@ -430,6 +420,7 @@ void resolveType(DSymbol* symbol, ref TypeLookups typeLookups,
|
||||||
resolveInheritance(symbol, typeLookups, moduleScope, cache);
|
resolveInheritance(symbol, typeLookups, moduleScope, cache);
|
||||||
else
|
else
|
||||||
assert(false, "How did this happen?");
|
assert(false, "How did this happen?");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void resolveTypeFromInitializer(DSymbol* symbol, TypeLookup* lookup,
|
void resolveTypeFromInitializer(DSymbol* symbol, TypeLookup* lookup,
|
||||||
|
|
|
@ -126,6 +126,101 @@ unittest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
ModuleCache cache;
|
||||||
|
writeln("Get return type name");
|
||||||
|
auto source = q{ int meaningOfLife() { return 42; } };
|
||||||
|
auto pair = generateAutocompleteTrees(source, cache);
|
||||||
|
auto meaningOfLife = pair.symbol.getFirstPartNamed(istring("meaningOfLife"));
|
||||||
|
assert(meaningOfLife.type.name == "int");
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
ModuleCache cache;
|
||||||
|
writeln("Get return type name from class method");
|
||||||
|
auto source = q{ class Life { uint meaningOfLife() { return 42; } }};
|
||||||
|
auto pair = generateAutocompleteTrees(source, cache);
|
||||||
|
auto lifeClass = pair.symbol.getFirstPartNamed(istring("Life"));
|
||||||
|
auto meaningOfLife = lifeClass.getFirstPartNamed(istring("meaningOfLife"));
|
||||||
|
assert(meaningOfLife.type.name == "uint");
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
ModuleCache cache;
|
||||||
|
writeln("Return type of auto should be null");
|
||||||
|
auto source = q{ class Life { auto meaningOfLife() { return 42; } }};
|
||||||
|
auto pair = generateAutocompleteTrees(source, cache);
|
||||||
|
auto lifeClass = pair.symbol.getFirstPartNamed(istring("Life"));
|
||||||
|
auto meaningOfLife = lifeClass.getFirstPartNamed(istring("meaningOfLife"));
|
||||||
|
assert(meaningOfLife.type is null);
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
ModuleCache cache;
|
||||||
|
writeln("Return type of scope should be null");
|
||||||
|
auto source = q{ class Life { scope meaningOfLife() { return 42; } }};
|
||||||
|
auto pair = generateAutocompleteTrees(source, cache);
|
||||||
|
auto lifeClass = pair.symbol.getFirstPartNamed(istring("Life"));
|
||||||
|
auto meaningOfLife = lifeClass.getFirstPartNamed(istring("meaningOfLife"));
|
||||||
|
assert(meaningOfLife.type is null);
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
ModuleCache cache;
|
||||||
|
writeln("Templated return type should be deduced correctly");
|
||||||
|
auto source = q{
|
||||||
|
struct AnswerToLife(T) {
|
||||||
|
T life;
|
||||||
|
}
|
||||||
|
AnswerToLife!int meaningOfLife() { return AnswerToLife!int(42); }
|
||||||
|
|
||||||
|
};
|
||||||
|
ScopeSymbolPair pair = generateAutocompleteTrees(source, cache);
|
||||||
|
auto answerToLife = pair.symbol.getFirstPartNamed(istring("AnswerToLife"));
|
||||||
|
DSymbol* meaningOfLife = pair.symbol.getFirstPartNamed(istring("meaningOfLife"));
|
||||||
|
assert(meaningOfLife.type.name == "AnswerToLife");
|
||||||
|
assert(meaningOfLife.type is answerToLife);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
ModuleCache cache;
|
||||||
|
writeln("Array return type should be deduced correctly");
|
||||||
|
auto source = q{
|
||||||
|
int[] meaningOfLife() { return [42]; }
|
||||||
|
|
||||||
|
};
|
||||||
|
ScopeSymbolPair pair = generateAutocompleteTrees(source, cache);
|
||||||
|
DSymbol* meaningOfLife = pair.symbol.getFirstPartNamed(istring("meaningOfLife"));
|
||||||
|
assert(meaningOfLife.type.name == "*arr*");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
unittest
|
||||||
|
{
|
||||||
|
ModuleCache cache;
|
||||||
|
writeln("Int* return type should be deduced correctly");
|
||||||
|
auto source = q{
|
||||||
|
int* meaningOfLife()
|
||||||
|
{
|
||||||
|
auto life = 42;
|
||||||
|
return &life;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
ScopeSymbolPair pair = generateAutocompleteTrees(source, cache);
|
||||||
|
DSymbol* meaningOfLife = pair.symbol.getFirstPartNamed(istring("meaningOfLife"));
|
||||||
|
writeln(meaningOfLife.type.name);
|
||||||
|
assert(meaningOfLife.type.name == "int");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
ModuleCache cache;
|
ModuleCache cache;
|
||||||
|
|
Loading…
Reference in New Issue