Implement with statement support. #56
This commit is contained in:
parent
b37b4b9dab
commit
d9abe32f6c
|
@ -1 +1 @@
|
|||
Subproject commit 27f45e6490e7ef0e9a6ef604e51f68a54b10ee2d
|
||||
Subproject commit d57e38c169613edfa39088adb933fd220b6208f3
|
|
@ -41,7 +41,7 @@ enum SymbolQualifier : ubyte
|
|||
{
|
||||
/// _none
|
||||
none,
|
||||
/// the symbol is an _array
|
||||
/// the symbol is an array
|
||||
array,
|
||||
/// the symbol is a associative array
|
||||
assocArray,
|
||||
|
@ -61,6 +61,9 @@ public:
|
|||
*/
|
||||
@disable this();
|
||||
|
||||
/// ditto
|
||||
@disable this(this);
|
||||
|
||||
/**
|
||||
* Params:
|
||||
* name = the symbol's name
|
||||
|
@ -253,8 +256,12 @@ struct Scope
|
|||
{
|
||||
foreach (item; sc.symbols[])
|
||||
{
|
||||
if (item.kind == CompletionKind.importSymbol) foreach (i; item.type.parts[])
|
||||
symbols.insert(i);
|
||||
if (item.kind == CompletionKind.importSymbol
|
||||
|| item.kind == CompletionKind.withSymbol)
|
||||
{
|
||||
foreach (i; item.type.parts[])
|
||||
symbols.insert(i);
|
||||
}
|
||||
else
|
||||
symbols.insert(item);
|
||||
}
|
||||
|
@ -276,6 +283,25 @@ struct Scope
|
|||
auto er = symbols.equalRange(&s);
|
||||
if (!er.empty)
|
||||
return array(er);
|
||||
|
||||
// Check symbols from "with" statement
|
||||
ACSymbol ir2 = ACSymbol(WITH_SYMBOL_NAME);
|
||||
auto r2 = symbols.equalRange(&ir2);
|
||||
if (!r2.empty)
|
||||
{
|
||||
auto app = appender!(ACSymbol*[])();
|
||||
foreach (e; r2)
|
||||
{
|
||||
if (e.type is null)
|
||||
continue;
|
||||
foreach (withSymbol; e.type.parts.equalRange(&s))
|
||||
app.put(withSymbol);
|
||||
}
|
||||
if (app.data.length > 0)
|
||||
return app.data;
|
||||
}
|
||||
|
||||
// Check imported symbols
|
||||
ACSymbol ir = ACSymbol(IMPORT_SYMBOL_NAME);
|
||||
auto r = symbols.equalRange(&ir);
|
||||
if (!r.empty)
|
||||
|
@ -386,6 +412,7 @@ private immutable(string[24]) builtinTypeNames;
|
|||
* static construction.
|
||||
*/
|
||||
immutable string IMPORT_SYMBOL_NAME;
|
||||
immutable string WITH_SYMBOL_NAME;
|
||||
|
||||
/**
|
||||
* Translates the IDs for built-in types into an interned string.
|
||||
|
@ -454,6 +481,7 @@ static this()
|
|||
builtinTypeNames[23] = internString("creal");
|
||||
|
||||
IMPORT_SYMBOL_NAME = internString("public");
|
||||
WITH_SYMBOL_NAME = internString("with");
|
||||
|
||||
|
||||
auto bool_ = allocate!ACSymbol(Mallocator.it, "bool", CompletionKind.keyword);
|
||||
|
|
|
@ -385,9 +385,9 @@ final class FirstPass : ASTVisitor
|
|||
|
||||
if (blockStatement.declarationsAndStatements !is null)
|
||||
{
|
||||
currentScope = s;
|
||||
currentScope = s;
|
||||
visit (blockStatement.declarationsAndStatements);
|
||||
currentScope = s.parent;
|
||||
currentScope = s.parent;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -453,6 +453,30 @@ final class FirstPass : ASTVisitor
|
|||
currentSymbol.addChild(symbol);
|
||||
}
|
||||
|
||||
override void visit(const WithStatement withStatement)
|
||||
{
|
||||
if (withStatement.expression !is null
|
||||
&& withStatement.statementNoCaseNoDefault !is null)
|
||||
{
|
||||
Scope* s = allocate!Scope(semanticAllocator,
|
||||
withStatement.statementNoCaseNoDefault.startLocation,
|
||||
withStatement.statementNoCaseNoDefault.endLocation);
|
||||
SemanticSymbol* symbol = allocateSemanticSymbol(WITH_SYMBOL_NAME,
|
||||
CompletionKind.withSymbol, symbolFile, s.startLocation, null);
|
||||
symbol.acSymbol.qualifier = SymbolQualifier.withSymbol;
|
||||
Log.trace("WithStatement bounds: ", s.startLocation, " ", s.endLocation);
|
||||
s.parent = currentScope;
|
||||
currentScope.children.insert(s);
|
||||
populateInitializer(symbol, withStatement.expression, false);
|
||||
symbol.parent = currentSymbol;
|
||||
currentSymbol.addChild(symbol);
|
||||
withStatement.accept(this);
|
||||
currentScope = currentScope.parent;
|
||||
}
|
||||
else
|
||||
withStatement.accept(this);
|
||||
}
|
||||
|
||||
alias visit = ASTVisitor.visit;
|
||||
|
||||
/// Module scope
|
||||
|
|
|
@ -81,9 +81,11 @@ private:
|
|||
*/
|
||||
void assignToScopes(ACSymbol* currentSymbol)
|
||||
{
|
||||
Scope* s = moduleScope.getScopeByCursor(currentSymbol.location);
|
||||
if (currentSymbol.kind != CompletionKind.moduleName)
|
||||
{
|
||||
Scope* s = moduleScope.getScopeByCursor(currentSymbol.location);
|
||||
s.symbols.insert(currentSymbol);
|
||||
}
|
||||
foreach (part; currentSymbol.parts[])
|
||||
{
|
||||
if (part.kind != CompletionKind.keyword)
|
||||
|
|
|
@ -70,14 +70,19 @@ private:
|
|||
case interfaceName:
|
||||
resolveInheritance(currentSymbol);
|
||||
break;
|
||||
case withSymbol:
|
||||
case variableName:
|
||||
case memberVariableName:
|
||||
case functionName:
|
||||
case aliasName:
|
||||
ACSymbol* t = resolveType(currentSymbol.initializer,
|
||||
currentSymbol.type, currentSymbol.acSymbol.location);
|
||||
while (t !is null && t.kind == CompletionKind.aliasName)
|
||||
while (t !is null && (t.kind == CompletionKind.aliasName
|
||||
|| (currentSymbol.acSymbol.kind == CompletionKind.withSymbol
|
||||
&& t.kind == CompletionKind.variableName)))
|
||||
{
|
||||
t = t.type;
|
||||
}
|
||||
currentSymbol.acSymbol.type = t;
|
||||
break;
|
||||
case structName:
|
||||
|
|
|
@ -31,6 +31,10 @@ enum CompletionKind : char
|
|||
/// be returned in a completion response.
|
||||
importSymbol = '*',
|
||||
|
||||
/// With symbol. This is used internally and will never
|
||||
/// be returned in a completion response.
|
||||
withSymbol = 'w',
|
||||
|
||||
/// class names
|
||||
className = 'c',
|
||||
|
||||
|
|
Loading…
Reference in New Issue