Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions polymod/hscript/_internal/Expr.hx
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ enum Error
EClassInvalidSuper; // Accessing "super" in a parentless class
EScriptThrow(v:Dynamic); // Script called "throw"
EScriptCallThrow(v:Dynamic); // Script called a function which threw
EInvalidAccessorCombination(accessors:Array<String>);
// Fallback error type.
ECustom(msg:String);
}
Expand Down
24 changes: 22 additions & 2 deletions polymod/hscript/_internal/Parser.hx
Original file line number Diff line number Diff line change
Expand Up @@ -1663,16 +1663,29 @@ class Parser
case "override":
access.push(AOverride);
case "public":
access.push(APublic);
// Throw an error if the user tries declaring a variable as public when it's already been declared private.
if (access.contains(APrivate))
error(ECustom("Conflicting access modifier public"), currentPos, currentPos);
else if (!access.contains(APublic))
access.push(APublic);
case "private":
access.push(APrivate);
// Throw an error if the user tries declaring a variable as private when it's already been declared public.
if (access.contains(APublic))
error(ECustom("Conflicting access modifier private"), currentPos, currentPos);
else if (!access.contains(APrivate))
access.push(APrivate);
case "inline":
access.push(AInline);
case "static":
access.push(AStatic);
case "macro":
access.push(AMacro);
case "function":
if (access.contains(AOverride) && access.contains(AStatic))
{
error(EInvalidAccessorCombination(['override', 'static']), currentPos, currentPos);
}

var name = getIdent();
var inf = parseFunctionDecl();
maybe(TSemicolon);
Expand Down Expand Up @@ -1713,6 +1726,13 @@ class Parser
else
ensure(TSemicolon);

#if POLYMOD_STRICT_SYNTAX
if (access.contains(AInline) && !access.contains(AStatic))
{
error(ECustom('Invalid modifier: inline on non-static variable'), currentPos, currentPos);
}
#end

return {
name: name,
meta: meta,
Expand Down
39 changes: 36 additions & 3 deletions polymod/hscript/_internal/PolymodScriptClass.hx
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ class PolymodScriptClass
Polymod.error(SCRIPT_PARSE_FAILED,
'Error while parsing class ${path}#${errLine}: EClassUnresolvedSuperclass' + '\n' + 'Unresolved superclass "${cls}", ${reason}', SCRIPT_RUNTIME);
return false;
case EInvalidAccessorCombination(accessors):
Polymod.error(
SCRIPT_PARSE_FAILED,
'Error while parsing function ${path}#${errLine}: EInvalidAccessorCombination' + '\n' + 'Invalid modifier combination: ${accessors.join(' + ')}', SCRIPT_RUNTIME);
return false;
default:
Polymod.error(SCRIPT_PARSE_FAILED, 'Error while parsing script ${path}#${errLine}: ' + '\n' + 'An unknown error occurred: ${err}', SCRIPT_RUNTIME);
return false;
Expand Down Expand Up @@ -568,18 +573,46 @@ class PolymodScriptClass
superClass = Type.createInstance(clsToCreate, args);
}

// Throw an error if the script class has an instance field with the same name as one from the super class.
for (f in _c.fields)
{
switch (f.kind)
{
case KVar(v):
if (!f.access.contains(AStatic) && superHasField(f.name))
{
throw 'Redefinition of variable "${f.name}" from superclass not allowed';
// Throw an error if the script class has an instance field with the same name as one from the super class.
throw 'Redefinition of variable "${f.name}" from superclass not allowed.';
}
case KFunction(fn):
#if POLYMOD_STRICT_SYNTAX
if (f.access.contains(AOverride) && !superHasField(f.name))
{
// Throw an error if a function is declared overwritten but isn't overriding anything.
throw "Field " + f.name + " is declared 'override' but doesn't override any field.";
}
else if (!f.access.contains(AOverride) && superHasField(f.name))
{
var superClassPackage:String = '';
if (superClass is PolymodScriptClass)
{
superClassPackage = Util.getFullClassName((cast superClass : PolymodScriptClass)._c);
}
else
{
// TODO: Fetch entire package name?
superClassPackage = Util.getTypeNameOf(superClass);
}

case _:
// Throw an error if a function is overriden but doesn't have the override accessor.
throw "Field " + f.name + " should be declared with 'override' since it is inherited from superclass " + superClassPackage + '.';
}
else if (f.access.contains(AOverride) && superClass == null)
{
// Throw an error if the override accessor is used with no super class.
throw "Invalid modifier: override on field" + f.name + " of class that has no parent.";
}
#end
default:
}
}
}
Expand Down
1 change: 1 addition & 0 deletions polymod/hscript/_internal/Printer.hx
Original file line number Diff line number Diff line change
Expand Up @@ -746,6 +746,7 @@ class Printer
// TODO: Do we need to distinguish these?
case EScriptCallThrow(v): 'Script threw an exception:\n$v';
case EScriptThrow(v): 'User script threw an exception:\n$v';
case EInvalidAccessorCombination(accessors): 'Invalid modifier combination: ${accessors.join(' + ')}';
case ECustom(msg): msg;
};
#if hscriptPos
Expand Down