Adding return type symbol (#720)

This commit is contained in:
Vushu 2023-03-05 18:00:50 +01:00 committed by GitHub
parent 92f2d73731
commit 1b67f493d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 114 additions and 27 deletions

View File

@ -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)
{ {

View File

@ -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,

View File

@ -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;