Now Container is an interface and Clazz is a kind-of Type (class-hierachy) and kind-of Container (interface)
Added assertion checks when casting for sanity (all casts to Entity from Container should never break as so far we do not have an object with a kind-of typeID tree that is imp,ementing interface Container and NOT Entity (class)entity_declaration_type_checking
parent
2cf9c07c1d
commit
114f0c5c39
|
@ -126,7 +126,7 @@ public final class TypeChecker
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -266,6 +266,15 @@ public final class TypeChecker
|
||||||
*/
|
*/
|
||||||
private void checkContainer(Container c)
|
private void checkContainer(Container c)
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* TODO: Always make sure this holds
|
||||||
|
*
|
||||||
|
* All objects that implement Container so far
|
||||||
|
* are also Entities (hence they have a name)
|
||||||
|
*/
|
||||||
|
Entity containerEntity = cast(Entity)c;
|
||||||
|
assert(containerEntity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all Entities of the Container with order Clazz, Function, Variable
|
* Get all Entities of the Container with order Clazz, Function, Variable
|
||||||
*/
|
*/
|
||||||
|
@ -285,9 +294,9 @@ public final class TypeChecker
|
||||||
/**
|
/**
|
||||||
* If the current entity's name matches the container then error
|
* If the current entity's name matches the container then error
|
||||||
*/
|
*/
|
||||||
else if (cmp(c.getName(), entity.getName()) == 0)
|
else if (cmp(containerEntity.getName(), entity.getName()) == 0)
|
||||||
{
|
{
|
||||||
throw new CollidingNameException(this, c, entity, c);
|
throw new CollidingNameException(this, containerEntity, entity, c);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* If there are conflicting names within the current container
|
* If there are conflicting names within the current container
|
||||||
|
@ -305,7 +314,7 @@ public final class TypeChecker
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string fullPath = resolver.generateName(modulle, entity);
|
string fullPath = resolver.generateName(modulle, entity);
|
||||||
string containerNameFullPath = resolver.generateName(modulle, c);
|
string containerNameFullPath = resolver.generateName(modulle, containerEntity);
|
||||||
gprintln("Entity \"" ~ fullPath
|
gprintln("Entity \"" ~ fullPath
|
||||||
~ "\" is allowed to be defined within container \""
|
~ "\" is allowed to be defined within container \""
|
||||||
~ containerNameFullPath ~ "\"");
|
~ containerNameFullPath ~ "\"");
|
||||||
|
@ -399,6 +408,15 @@ public final class TypeChecker
|
||||||
*/
|
*/
|
||||||
private void checkClassNames(Container c)
|
private void checkClassNames(Container c)
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* TODO: Always make sure this holds
|
||||||
|
*
|
||||||
|
* All objects that implement Container so far
|
||||||
|
* are also Entities (hence they have a name)
|
||||||
|
*/
|
||||||
|
Entity containerEntity = cast(Entity)c;
|
||||||
|
assert(containerEntity);
|
||||||
|
|
||||||
/* Get all types (Clazz so far) */
|
/* Get all types (Clazz so far) */
|
||||||
Clazz[] classTypes;
|
Clazz[] classTypes;
|
||||||
|
|
||||||
|
@ -431,21 +449,21 @@ public final class TypeChecker
|
||||||
Parser.expect("Cannot define class \"" ~ resolver.generateName(modulle,
|
Parser.expect("Cannot define class \"" ~ resolver.generateName(modulle,
|
||||||
clazz) ~ "\" as one with same name, \"" ~ resolver.generateName(modulle,
|
clazz) ~ "\" as one with same name, \"" ~ resolver.generateName(modulle,
|
||||||
resolver.resolveUp(c, clazz.getName())) ~ "\" exists in container \"" ~ resolver.generateName(
|
resolver.resolveUp(c, clazz.getName())) ~ "\" exists in container \"" ~ resolver.generateName(
|
||||||
modulle, c) ~ "\"");
|
modulle, containerEntity) ~ "\"");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Get the current container's parent container */
|
/* Get the current container's parent container */
|
||||||
Container parentContainer = c.parentOf();
|
Container parentContainer = containerEntity.parentOf();
|
||||||
|
|
||||||
/* Don't allow a class to be named after it's container */
|
/* Don't allow a class to be named after it's container */
|
||||||
// if(!parentContainer)
|
// if(!parentContainer)
|
||||||
// {
|
// {
|
||||||
if (cmp(c.getName(), clazz.getName()) == 0)
|
if (cmp(containerEntity.getName(), clazz.getName()) == 0)
|
||||||
{
|
{
|
||||||
Parser.expect("Class \"" ~ resolver.generateName(modulle,
|
Parser.expect("Class \"" ~ resolver.generateName(modulle,
|
||||||
clazz) ~ "\" cannot be defined within container with same name, \"" ~ resolver.generateName(
|
clazz) ~ "\" cannot be defined within container with same name, \"" ~ resolver.generateName(
|
||||||
modulle, c) ~ "\"");
|
modulle, containerEntity) ~ "\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Loop througn Container ENtitys here */
|
/* TODO: Loop througn Container ENtitys here */
|
||||||
|
|
|
@ -23,11 +23,11 @@ public final class Resolver
|
||||||
{
|
{
|
||||||
string[] name = generateName_Internal(relativeTo, entity);
|
string[] name = generateName_Internal(relativeTo, entity);
|
||||||
string path;
|
string path;
|
||||||
for(ulong i = 0; i < name.length; i++)
|
for (ulong i = 0; i < name.length; i++)
|
||||||
{
|
{
|
||||||
path ~= name[name.length-1-i];
|
path ~= name[name.length - 1 - i];
|
||||||
|
|
||||||
if(i != name.length-1)
|
if (i != name.length - 1)
|
||||||
{
|
{
|
||||||
path ~= ".";
|
path ~= ".";
|
||||||
}
|
}
|
||||||
|
@ -38,18 +38,27 @@ public final class Resolver
|
||||||
|
|
||||||
private string[] generateName_Internal(Container relativeTo, Entity entity)
|
private string[] generateName_Internal(Container relativeTo, Entity entity)
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* TODO: Always make sure this holds
|
||||||
|
*
|
||||||
|
* All objects that implement Container so far
|
||||||
|
* are also Entities (hence they have a name)
|
||||||
|
*/
|
||||||
|
Entity containerEntity = cast(Entity) relativeTo;
|
||||||
|
assert(containerEntity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the Entity and Container are the same then
|
* If the Entity and Container are the same then
|
||||||
* just returns its name
|
* just returns its name
|
||||||
*/
|
*/
|
||||||
if(relativeTo == entity)
|
if (relativeTo == entity)
|
||||||
{
|
{
|
||||||
return [relativeTo.getName()];
|
return [containerEntity.getName()];
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* If the Entity is contained within the Container
|
* If the Entity is contained within the Container
|
||||||
*/
|
*/
|
||||||
else if(isDescendant(relativeTo, entity))
|
else if (isDescendant(relativeTo, entity))
|
||||||
{
|
{
|
||||||
string[] items;
|
string[] items;
|
||||||
|
|
||||||
|
@ -57,12 +66,22 @@ public final class Resolver
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
items ~= currentEntity.getName();
|
items ~= currentEntity.getName();
|
||||||
currentEntity = currentEntity.parentOf();
|
|
||||||
|
/**
|
||||||
|
* TODO: Make sure this condition holds
|
||||||
|
*
|
||||||
|
* So far all objects we have being used
|
||||||
|
* of which are kind-of Containers are also
|
||||||
|
* and ONLY also kind-of Entity's hence the
|
||||||
|
* cast should never fail
|
||||||
|
*/
|
||||||
|
assert(cast(Entity) currentEntity.parentOf());
|
||||||
|
currentEntity = cast(Entity)(currentEntity.parentOf());
|
||||||
}
|
}
|
||||||
while(currentEntity != relativeTo);
|
while (currentEntity != relativeTo);
|
||||||
|
|
||||||
/* Add the relative to container */
|
/* Add the relative to container */
|
||||||
items ~= relativeTo.getName();
|
items ~= containerEntity.getName();
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +101,7 @@ public final class Resolver
|
||||||
/**
|
/**
|
||||||
* If they are the same
|
* If they are the same
|
||||||
*/
|
*/
|
||||||
if(c == e)
|
if (c == e)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -95,14 +114,23 @@ public final class Resolver
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
currentEntity = currentEntity.parentOf();
|
/**
|
||||||
|
* TODO: Make sure this condition holds
|
||||||
|
*
|
||||||
|
* So far all objects we have being used
|
||||||
|
* of which are kind-of Containers are also
|
||||||
|
* and ONLY also kind-of Entity's hence the
|
||||||
|
* cast should never fail
|
||||||
|
*/
|
||||||
|
assert(cast(Entity) currentEntity.parentOf());
|
||||||
|
currentEntity = cast(Entity)(currentEntity.parentOf());
|
||||||
|
|
||||||
if(currentEntity == c)
|
if (currentEntity == c)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while(currentEntity);
|
while (currentEntity);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -112,25 +140,25 @@ public final class Resolver
|
||||||
{
|
{
|
||||||
Statement[] statements = currentContainer.getStatements();
|
Statement[] statements = currentContainer.getStatements();
|
||||||
|
|
||||||
foreach(Statement statement; statements)
|
foreach (Statement statement; statements)
|
||||||
{
|
{
|
||||||
/* TODO: Only acuse parser not done yet */
|
/* TODO: Only acuse parser not done yet */
|
||||||
if(statement !is null)
|
if (statement !is null)
|
||||||
{
|
{
|
||||||
Entity entity = cast(Entity)statement;
|
Entity entity = cast(Entity) statement;
|
||||||
|
|
||||||
if(entity)
|
if (entity)
|
||||||
{
|
{
|
||||||
if(cmp(entity.getName(), name) == 0)
|
if (cmp(entity.getName(), name) == 0)
|
||||||
{
|
{
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Entity resolveUp(Container currentContainer, string name)
|
public Entity resolveUp(Container currentContainer, string name)
|
||||||
{
|
{
|
||||||
|
@ -146,17 +174,26 @@ public final class Resolver
|
||||||
gprintln(entity);
|
gprintln(entity);
|
||||||
|
|
||||||
/* If we found it return it */
|
/* If we found it return it */
|
||||||
if(entity)
|
if (entity)
|
||||||
{
|
{
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
/* If we didn't then try go up a container */
|
/* If we didn't then try go up a container */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Container possibleParent = currentContainer.parentOf();
|
/**
|
||||||
|
* TODO: Make sure this condition holds
|
||||||
|
*
|
||||||
|
* So far all objects we have being used
|
||||||
|
* of which are kind-of Containers are also
|
||||||
|
* and ONLY also kind-of Entity's hence the
|
||||||
|
* cast should never fail
|
||||||
|
*/
|
||||||
|
assert(cast(Entity) currentContainer);
|
||||||
|
Container possibleParent = (cast(Entity) currentContainer).parentOf();
|
||||||
|
|
||||||
/* Can we go up */
|
/* Can we go up */
|
||||||
if(possibleParent)
|
if (possibleParent)
|
||||||
{
|
{
|
||||||
return resolveUp(possibleParent, name);
|
return resolveUp(possibleParent, name);
|
||||||
}
|
}
|
||||||
|
@ -180,6 +217,15 @@ public final class Resolver
|
||||||
*/
|
*/
|
||||||
public Entity resolveBest(Container c, string name)
|
public Entity resolveBest(Container c, string name)
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* TODO: Always make sure this holds
|
||||||
|
*
|
||||||
|
* All objects that implement Container so far
|
||||||
|
* are also Entities (hence they have a name)
|
||||||
|
*/
|
||||||
|
Entity containerEntity = cast(Entity) c;
|
||||||
|
assert(containerEntity);
|
||||||
|
|
||||||
string[] path = split(name, '.');
|
string[] path = split(name, '.');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -189,13 +235,13 @@ public final class Resolver
|
||||||
*
|
*
|
||||||
* TODO: WOn't resolve a module
|
* TODO: WOn't resolve a module
|
||||||
*/
|
*/
|
||||||
if(path.length == 1)
|
if (path.length == 1)
|
||||||
{
|
{
|
||||||
/* TODO: Add path[0], c.getName()) == modulle */
|
/* TODO: Add path[0], c.getName()) == modulle */
|
||||||
|
|
||||||
/* TODO: This is for getting module entity */
|
/* TODO: This is for getting module entity */
|
||||||
/* Check if the name, regardless of container, is root (Module) */
|
/* Check if the name, regardless of container, is root (Module) */
|
||||||
if(cmp(name, typeChecker.getModule().getName()) == 0)
|
if (cmp(name, typeChecker.getModule().getName()) == 0)
|
||||||
{
|
{
|
||||||
return typeChecker.getModule();
|
return typeChecker.getModule();
|
||||||
}
|
}
|
||||||
|
@ -203,14 +249,14 @@ public final class Resolver
|
||||||
Entity entityWithin = resolveUp(c, name);
|
Entity entityWithin = resolveUp(c, name);
|
||||||
|
|
||||||
/* If `name` was in container `c` or above it */
|
/* If `name` was in container `c` or above it */
|
||||||
if(entityWithin)
|
if (entityWithin)
|
||||||
{
|
{
|
||||||
return entityWithin;
|
return entityWithin;
|
||||||
}
|
}
|
||||||
/* If `name` was NOT found within container `c` or above it */
|
/* If `name` was NOT found within container `c` or above it */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -218,27 +264,27 @@ public final class Resolver
|
||||||
/* TODO: Add module name check here */
|
/* TODO: Add module name check here */
|
||||||
|
|
||||||
/* If the root is the current container */
|
/* If the root is the current container */
|
||||||
if(cmp(path[0], c.getName()) == 0)
|
if (cmp(path[0], containerEntity.getName()) == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* If only 1 left then just grab it */
|
/* If only 1 left then just grab it */
|
||||||
if(path.length == 2)
|
if (path.length == 2)
|
||||||
{
|
{
|
||||||
Entity entityNext = resolveWithin(c, path[1]);
|
Entity entityNext = resolveWithin(c, path[1]);
|
||||||
return entityNext;
|
return entityNext;
|
||||||
}
|
}
|
||||||
/* Go deeper */
|
/* Go deeper */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string newPath = name[indexOf(name, '.')+1..name.length];
|
string newPath = name[indexOf(name, '.') + 1 .. name.length];
|
||||||
Entity entityNext = resolveWithin(c, path[1]);
|
Entity entityNext = resolveWithin(c, path[1]);
|
||||||
|
|
||||||
/* If null then not found */
|
/* If null then not found */
|
||||||
if(entityNext)
|
if (entityNext)
|
||||||
{
|
{
|
||||||
Container containerWithin = cast(Container)entityNext;
|
Container containerWithin = cast(Container) entityNext;
|
||||||
|
|
||||||
if(entityNext)
|
if (entityNext)
|
||||||
{
|
{
|
||||||
/* TODO: Technically I could strip new root as we have the container */
|
/* TODO: Technically I could strip new root as we have the container */
|
||||||
/* TODO: The only reason I don't want to do that is the condition */
|
/* TODO: The only reason I don't want to do that is the condition */
|
||||||
|
@ -257,11 +303,11 @@ public final class Resolver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* We need to search higher */
|
/* We need to search higher */
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* TODO: Bug is we will never find top container */
|
/* TODO: Bug is we will never find top container */
|
||||||
/* Check if the name of root is that of Module */
|
/* Check if the name of root is that of Module */
|
||||||
if(cmp(typeChecker.getModule().getName(), path[0]) == 0)
|
if (cmp(typeChecker.getModule().getName(), path[0]) == 0)
|
||||||
{
|
{
|
||||||
/* Root ourselves relative to the Module */
|
/* Root ourselves relative to the Module */
|
||||||
/* TODO: Don't serch for myModule class and ooga within */
|
/* TODO: Don't serch for myModule class and ooga within */
|
||||||
|
@ -276,11 +322,11 @@ public final class Resolver
|
||||||
|
|
||||||
Entity entityFound = resolveUp(c, path[0]);
|
Entity entityFound = resolveUp(c, path[0]);
|
||||||
|
|
||||||
if(entityFound)
|
if (entityFound)
|
||||||
{
|
{
|
||||||
Container con = cast(Container)entityFound;
|
Container con = cast(Container) entityFound;
|
||||||
|
|
||||||
if(con)
|
if (con)
|
||||||
{
|
{
|
||||||
gprintln("fooook");
|
gprintln("fooook");
|
||||||
return resolveBest(con, name);
|
return resolveBest(con, name);
|
||||||
|
@ -301,4 +347,4 @@ public final class Resolver
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue