🧹️🧼 Hotfix: VariableExpression dependency node generaiton (#26)
* Dependency
- Removed crap for `VariableExpression` dependency node generation
- This is a work-in-progress clean up
* Dependency
- Added some comments
* Dependency
- Avoid path hopping by making this beanch constantly `true`
* Dependency
- Cleaned up some more, added link to issue regarding context sets
* Dependency
- Don't fetch-and-set context for `bruh` (the entity being referenced)
* Dependency
- Removed path-hopper code
* Dependency
- Checking iets
* Dependency
- Undid checking-iets
* Dependency
- Checking iets (fr)
* Revert "Dependency"
This reverts commit 5ddab9dd3d
.
* Dependency
- No need to set it here if set above
* Dependency
- Removed no-op branch
* Dependency
- Cleaned up some more
* Dependency
- Refactored code
* Dependency
- Cleaned up
This commit is contained in:
parent
3d9bf28f3b
commit
d7b9a89552
|
@ -737,291 +737,98 @@ public class DNodeGenerator
|
||||||
*/
|
*/
|
||||||
else if(cast(VariableExpression)exp)
|
else if(cast(VariableExpression)exp)
|
||||||
{
|
{
|
||||||
/* TODO: Figure out where the variable lies */
|
// Extract the variable's name
|
||||||
|
|
||||||
/* TODO: Change this later */
|
|
||||||
// return new DNode(this, exp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extract the variable name
|
|
||||||
*/
|
|
||||||
VariableExpression varExp = cast(VariableExpression)exp;
|
VariableExpression varExp = cast(VariableExpression)exp;
|
||||||
|
string nearestName = varExp.getName();
|
||||||
string path = varExp.getName();
|
|
||||||
long nearestDot = indexOf(path, ".");
|
|
||||||
|
|
||||||
|
// Set the context of the variable expression
|
||||||
gprintln("VariableExpressionPass(): Path: "~path, DebugType.WARNING);
|
|
||||||
gprintln("VarExp Context set? (before): "~to!(string)(varExp.getContext()));
|
|
||||||
|
|
||||||
/* See issue #9 on Gitea */
|
|
||||||
/* FIXME: We only set context in some situations - we MUST fix this */
|
|
||||||
/* NOTE: I think THIS is wrong - varExp.setContext(context); */
|
|
||||||
/* What we need to do is set the variable itself me thinks */
|
|
||||||
/* NOTE: But the above seems to also be needed */
|
|
||||||
|
|
||||||
/* FIXME: Remove the context sets below */
|
|
||||||
|
|
||||||
/* NOTE: Fix is below I think (it doesn't crash then) */
|
|
||||||
/* Set context for expression and the variable itself */
|
|
||||||
varExp.setContext(context);
|
varExp.setContext(context);
|
||||||
gprintln("Context (after): "~to!(string)(varExp.getContext().getContainer()));
|
|
||||||
Entity bruh = tc.getResolver().resolveBest(context.getContainer(), path);
|
// Resolve the entity the name refers to
|
||||||
bruh.setContext(context);
|
Entity namedEntity = tc.getResolver().resolveBest(context.getContainer(), nearestName);
|
||||||
|
|
||||||
/* Has two dots? */
|
|
||||||
bool hasTwoDots = indexOf(path, ".", nearestDot+1) == lastIndexOf(path, ".") && indexOf(path, ".", nearestDot+1) > -1;
|
|
||||||
gprintln(indexOf(path, ".", nearestDot+1));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Current named entity
|
|
||||||
*/
|
|
||||||
string nearestName;
|
|
||||||
|
|
||||||
/**
|
/* If the entity was found */
|
||||||
* If the `path` has no dots
|
if(namedEntity)
|
||||||
*
|
|
||||||
* Example: `variableX`
|
|
||||||
*/
|
|
||||||
if(nearestDot == -1)
|
|
||||||
{
|
{
|
||||||
/* The name is exactly the path */
|
/* FIXME: Below assumes basic variable declarations at module level, fix later */
|
||||||
nearestName = path;
|
|
||||||
|
|
||||||
/* Resolve the Entity */
|
/**
|
||||||
Entity namedEntity = tc.getResolver().resolveBest(context.getContainer(), nearestName);
|
* If `namedEntity` is a `Variable`
|
||||||
|
*
|
||||||
|
* Think of, well, a variable
|
||||||
|
*/
|
||||||
/**
|
if(cast(Variable)namedEntity)
|
||||||
* NEW CODE!!!! (Added 25th Oct)
|
|
||||||
*
|
|
||||||
* Update name for later typechecking resolution of var
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
varExp.setContext(context);
|
|
||||||
gprintln("Kont: "~to!(string)(context));
|
|
||||||
|
|
||||||
|
|
||||||
if(namedEntity)
|
|
||||||
{
|
{
|
||||||
/* FIXME: Below assumes basic variable declarations at module level, fix later */
|
/* Get the entity as a Variable */
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the Entity as a Variable
|
|
||||||
*/
|
|
||||||
Variable variable = cast(Variable)namedEntity;
|
Variable variable = cast(Variable)namedEntity;
|
||||||
|
|
||||||
if(variable)
|
/* Pool the node */
|
||||||
|
VariableNode varDecNode = poolT!(VariableNode, Variable)(variable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the variable being referenced has been
|
||||||
|
* visited (i.e. declared)
|
||||||
|
*
|
||||||
|
* If it has then setup dependency, if not then error
|
||||||
|
* out
|
||||||
|
*/
|
||||||
|
if(varDecNode.isVisisted())
|
||||||
{
|
{
|
||||||
/* Pool the node */
|
dnode.needs(varDecNode);
|
||||||
VariableNode varDecNode = poolT!(VariableNode, Variable)(variable);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the variable being referenced has been
|
|
||||||
* visited (i.e. declared)
|
|
||||||
*
|
|
||||||
* If it has then setup dependency, if not then error
|
|
||||||
* out
|
|
||||||
*/
|
|
||||||
if(varDecNode.isVisisted())
|
|
||||||
{
|
|
||||||
dnode.needs(varDecNode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
expect("Cannot reference variable "~nearestName~" which exists but has not been declared yet");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Use the Context to make a decision */
|
|
||||||
}
|
|
||||||
else if(cast(Function)namedEntity)
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* FIXME: Yes it isn't a funcall not, and it is not a variable and is probably
|
|
||||||
* being returned as the lookup, so a FUnction node i guess
|
|
||||||
*/
|
|
||||||
Function funcHandle = cast(Function)namedEntity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FIXME: Find the best place for this. Functions will always
|
|
||||||
* be declared (atleast for basic examples as like now) in
|
|
||||||
* the module level
|
|
||||||
*/
|
|
||||||
Context cont = new Context(tc.getModule(), InitScope.STATIC);
|
|
||||||
// cont.container = tc.getModule();
|
|
||||||
// cont.
|
|
||||||
funcHandle.setContext(cont);
|
|
||||||
|
|
||||||
// funcHandle
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FIXME: Do we have to visit the function, I am not sure, like maybe declaration
|
|
||||||
* or surely it is already declared??!?!?
|
|
||||||
*
|
|
||||||
* Does pooling it make sense? Do we force a visitation?
|
|
||||||
*/
|
|
||||||
FuncDecNode funcDecNode = poolT!(FuncDecNode, Function)(funcHandle);
|
|
||||||
dnode.needs(funcDecNode);
|
|
||||||
|
|
||||||
gprintln("Muh function handle: "~namedEntity.toString(), DebugType.WARNING);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* TODO: Add check ? */
|
expect("Cannot reference variable "~nearestName~" which exists but has not been declared yet");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* If `namedEntity` is a `Function`
|
||||||
|
*
|
||||||
|
* Think of a function handle
|
||||||
|
*/
|
||||||
|
else if(cast(Function)namedEntity)
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* FIXME: Yes it isn't a funcall not, and it is not a variable and is probably
|
||||||
|
* being returned as the lookup, so a FUnction node i guess
|
||||||
|
*/
|
||||||
|
Function funcHandle = cast(Function)namedEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIXME: Find the best place for this. Functions will always
|
||||||
|
* be declared (atleast for basic examples as like now) in
|
||||||
|
* the module level
|
||||||
|
*/
|
||||||
|
Context cont = new Context(tc.getModule(), InitScope.STATIC);
|
||||||
|
// cont.container = tc.getModule();
|
||||||
|
// cont.
|
||||||
|
funcHandle.setContext(cont);
|
||||||
|
|
||||||
|
// funcHandle
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FIXME: Do we have to visit the function, I am not sure, like maybe declaration
|
||||||
|
* or surely it is already declared??!?!?
|
||||||
|
*
|
||||||
|
* Does pooling it make sense? Do we force a visitation?
|
||||||
|
*/
|
||||||
|
FuncDecNode funcDecNode = poolT!(FuncDecNode, Function)(funcHandle);
|
||||||
|
dnode.needs(funcDecNode);
|
||||||
|
|
||||||
|
gprintln("Muh function handle: "~namedEntity.toString(), DebugType.WARNING);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
expect("No entity by the name "~nearestName~" exists (at all)");
|
/* TODO: Add check ? */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/**
|
/* If the entity could not be found */
|
||||||
* If the `path` has dots
|
|
||||||
*
|
|
||||||
* Example: `container.variableX`
|
|
||||||
*
|
|
||||||
* We want to start left to right, first look at `variableX`,
|
|
||||||
* take that node, then recurse on `container.` (everything
|
|
||||||
* without the last segment) as this results in the correct
|
|
||||||
* dependency sub-tree
|
|
||||||
*
|
|
||||||
* FIXME: We should stop at `x.y` and not go further as we need
|
|
||||||
* to know what we are acessing
|
|
||||||
*/
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Chop off the last segment */
|
expect("No entity by the name "~nearestName~" exists (at all)");
|
||||||
long lastDot = lastIndexOf(path, ".");
|
|
||||||
string remainingSegment = path[0..(lastDot)];
|
|
||||||
|
|
||||||
/* TODO: Check th container passed in */
|
|
||||||
/* Lookup the name within the current entity's context */
|
|
||||||
gprintln("Now looking up: "~remainingSegment);
|
|
||||||
Entity namedEntity = tc.getResolver().resolveBest(context.getContainer(), remainingSegment);
|
|
||||||
gprintln("namedEntity: "~to!(string)(namedEntity));
|
|
||||||
gprintln("Context used for resolution: "~to!(string)(context.getContainer()));
|
|
||||||
|
|
||||||
/* The remaining segment must EXIST */
|
|
||||||
if(namedEntity)
|
|
||||||
{
|
|
||||||
/* The remaining segment must be a CONTAINER */
|
|
||||||
Container container = cast(Container)namedEntity;
|
|
||||||
if(container)
|
|
||||||
{
|
|
||||||
/* If we have a class then it needs static init */
|
|
||||||
if(cast(Clazz)container)
|
|
||||||
{
|
|
||||||
Clazz containerClass = cast(Clazz)container;
|
|
||||||
DNode classStaticAllocate = classPassStatic(containerClass);
|
|
||||||
dnode.needs(classStaticAllocate);
|
|
||||||
gprintln("Hello "~remainingSegment, DebugType.ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FIXME: Decide what requires new dep and what doesn't, instance vs class access etc
|
|
||||||
*
|
|
||||||
* How detailed we need to be? Will we combine these and consume later, we need to take these things
|
|
||||||
* into account. I am erring on the side of one single access, the only things along the way are possible static
|
|
||||||
* allocations, but that is my feeling - each path segment doesn't need something for simply existing
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* If we only have one dot left s(TODO: implement ) */
|
|
||||||
bool hasMoreDot = indexOf(remainingSegment, ".") > -1;
|
|
||||||
if(hasMoreDot)
|
|
||||||
{
|
|
||||||
gprintln("has mor dot");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a VariableExpression for the remaining segment,
|
|
||||||
* run `passExpression()` on it (recurse) and make the CURRENT
|
|
||||||
* DNode (`dnode`) depend on the returned DNode
|
|
||||||
*
|
|
||||||
* TOOD: Double check the Context passed in
|
|
||||||
*/
|
|
||||||
// Context varExpRemContext = new Context(tc.getModule(), InitScope.STATIC);
|
|
||||||
VariableExpression varExpRem = new VariableExpression(remainingSegment);
|
|
||||||
DNode varExpRemDNode = expressionPass(varExpRem, context);
|
|
||||||
|
|
||||||
/* TODO: Double check if we need this, problems lie here and when we NEED to do and and when NOT */
|
|
||||||
dnode.needs(varExpRemDNode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Do access operation here */
|
|
||||||
gprintln("No more dot");
|
|
||||||
|
|
||||||
gprintln("No mord to accevssor(): "~to!(string)(dnode));
|
|
||||||
|
|
||||||
/* TODO: We now have `TestClass.P` so accessor op or what? */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
expect("Could not acces \""~remainingSegment~"\" as it is not a container");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* If an entity by that name doesn't exist then
|
|
||||||
* this is a typechecking error and we should
|
|
||||||
* break
|
|
||||||
*/
|
|
||||||
else
|
|
||||||
{
|
|
||||||
expect("Could not find an entity named "~remainingSegment);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO:C lean up and mke DNode */
|
|
||||||
|
|
||||||
/* TODO: Process `nearestName` by doing a tc.resolveWithin() */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* TODO: SPlit the path up and resolve the shit */
|
|
||||||
|
|
||||||
/* TODO: gte start of path (TODO)*/
|
|
||||||
/* TODO: Then check that within current context, then we shift context for another call */
|
|
||||||
string currentName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If we can resolve anywhere (TODO: Perhaps module level was better
|
|
||||||
*/
|
|
||||||
if(context.isAllowUp())
|
|
||||||
{
|
|
||||||
/* TODO: Use normal resolveBest */
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Only within resolution allowed
|
|
||||||
*/
|
|
||||||
else
|
|
||||||
{
|
|
||||||
gprintln("87er78fgy678fyg678g6f8gfyduhgfjfgdjkgfdhjkfgdhjfkgdhgfdjkhgfjkhgfdjkhgfdjkhgfdjkfgdhjkfgdhjkfdghjgkfdhgfdjkhgfdjkhgfdjkhfgdjkhfgd");
|
|
||||||
Entity entity = tc.getResolver().resolveWithin(context.getContainer(), nearestName);
|
|
||||||
|
|
||||||
/* TODO: If dots remain then make sure cast(Container)entity is non-zero, i.e. is a container, else fail, typecheck error! */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
gprintln("VarExp Context set? (after): "~to!(string)(varExp.getContext()));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Binary operator
|
* Binary operator
|
||||||
|
|
Loading…
Reference in New Issue