public virtual void RawDefineTemplate(string name, CompiledTemplate code, IToken defT)
{
CompiledTemplate prev;
templates.TryGetValue(name, out prev);
if (prev != null)
{
if (!prev.IsRegion)
{
ErrorManager.CompiletimeError(ErrorType.TEMPLATE_REDEFINITION, null, defT);
return;
}
/* If this region was previously defined, the following actions should be taken:
*
* Previous type Current type Result Applied Reason
* ------------- ------------ ------ ------- ------
* Implicit Implicit Success Previous A rule may make multiple implicit references to the same region.
* Keeping either has the same semantics, so the existing one is
* used for slightly less overhead.
* Implicit Explicit Success Current A region with previous implicit references is now being explicitly
* defined.
* Implicit Embedded Success Current A region with previous implicit references is now being defined
* with an embedded region.
* Explicit Implicit Success Previous An explicitly defined region is now being implicitly referenced.
* Make sure to keep the previous explicit definition as the actual
* definition.
* Explicit Explicit Error Previous Multiple explicit definitions exist for the same region (template
* redefinition error). Give an error and use the previous one.
* Explicit Embedded Warning Previous An explicit region definition already exists for the current
* embedded region definition. The explicit definition overrides the
* embedded definition and a warning is given since the embedded
* definition is hidden.
* Embedded Implicit Success Previous A region with an embedded definition is now being implicitly
* referenced. The embedded definition should be used.
* Embedded Explicit Warning Current A region with an embedded definition is now being explicitly
* defined. The explicit definition overrides the embedded
* definition and a warning is given since the embedded definition
* is hidden.
* Embedded Embedded Error Previous Multiple embedded definitions of the same region were given in a
* template. Give an error and use the previous one.
*/
// handle the Explicit/Explicit and Embedded/Embedded error cases
if (code.RegionDefType != Template.RegionType.Implicit && code.RegionDefType == prev.RegionDefType)
{
if (code.RegionDefType == Template.RegionType.Embedded)
ErrorManager.CompiletimeError(ErrorType.EMBEDDED_REGION_REDEFINITION, null, defT, GetUnmangledTemplateName(name));
else
ErrorManager.CompiletimeError(ErrorType.REGION_REDEFINITION, null, defT, GetUnmangledTemplateName(name));
// keep the previous one
return;
}
// handle the Explicit/Embedded and Embedded/Explicit warning cases
else if ((code.RegionDefType == Template.RegionType.Embedded && prev.RegionDefType == Template.RegionType.Explicit)
|| (code.RegionDefType == Template.RegionType.Explicit && prev.RegionDefType == Template.RegionType.Embedded))
{
// TODO: can we make this a warning?
ErrorManager.CompiletimeError(ErrorType.HIDDEN_EMBEDDED_REGION_DEFINITION, null, defT, GetUnmangledTemplateName(name));
// keep the previous one only if that's the explicit definition
if (prev.RegionDefType == Template.RegionType.Explicit)
return;
}
// else if the current definition type is implicit, keep the previous one
else if (code.RegionDefType == Template.RegionType.Implicit)
{
return;
}
}
code.NativeGroup = this;
code.TemplateDefStartToken = defT;
templates[name] = code;
}