`MoveLooseDeclarationsIntoTypesTransformation`
===================================================================================================
<small>\[[Transformation Source](../../Biohazrd.CSharp/#Transformations/MoveLooseDeclarationsIntoTypesTransformation.cs)\]</small>
For the most part, C# doesn't allow fields and methods to exist outside of containing types. This transformation moves loose declarations into dedicated containing types.
## When this transformation is applicable
This transformation should almost always be used unless you implement similar functionality yourself.
This is especially true for C or C-style libraries where all functions are loose by default.
## Details
This transformation looks for [`TranslatedFunction`](../BuiltInDeclarations/TranslatedFunction.md), [`TranslatedField`](../BuiltInDeclarations/TranslatedField.md), or [`TranslatedStaticField`](../BuiltInDeclarations/TranslatedStaticField.md) declarations which are not contained within a [`TranslatedRecord`](../BuiltInDeclarations/TranslatedRecord.md) or [`SynthesizedLooseDeclarationsTypeDeclaration`](../BuiltInDeclarations/SynthesizedLooseDeclarationsTypeDeclaration.md) and moves them into one.
The transformation will move the loose declarations into a type with the same name as the file which declares it. So if the file `MyHeader.h` declares a function `MyFunction` and contains a struct named `MyHeader`, then `MyFunction` becomes a static function of `MyHeader`. (See below for an example.)
If no such type exists, it will create a new [`SynthesizedLooseDeclarationsTypeDeclaration`](../BuiltInDeclarations/SynthesizedLooseDeclarationsTypeDeclaration.md) to contain the type.
If the loose declaration has the same name as its containing type (IE: the file `MyHeader.h` declares a function named `MyHeader`) the loose declaration will be renamed with a `__` suffix and a warning will be issued. This is done to avoid a [CS0542](https://docs.microsoft.com/en-us/dotnet/csharp/misc/cs0542) error in the generated output.
### Example with no existing type
Given the following C++ code in a file named `MyHeader.h`:
```cpp
int SomeGlobalVariable;
void MyLooseFunction();
```
Biohazrd's translation stage will output the following declaration tree:
```
TranslatedStaticField SomeGlobalVariable
TranslatedFunction MyLooseFunction
```
If you attempted to output the C# for this declaration tree (skipping verification), you would get the following invalid output:
```csharp
// This file was automatically generated by Biohazrd and should not be modified by hand!
using System.Runtime.InteropServices;
public static readonly int* SomeGlobalVariable = (int*)NativeLibrary.GetExport(NativeLibrary.Load("TODO.dll"), "?SomeGlobalVariable@@3HA");
[DllImport("Example.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "?MyLooseFunction@@YAXXZ", ExactSpelling = true)]
public static extern void MyLooseFunction();
```
> ℹ Note: The way global and static variables are emitted is considered subpar. See [#15](https://github.com/InfectedLibraries/Biohazrd/issues/15).
After applying this transformation, a new sytnehsized type is added to contain the loose declarations:
```
SynthesizedLooseDeclarationsTypeDeclaration MyHeader
    TranslatedStaticField SomeGlobalVariable
    TranslatedFunction MyLooseFunction
```
and the C# output is now usable:
```csharp
// This file was automatically generated by Biohazrd and should not be modified by hand!
using System.Runtime.InteropServices;
public unsafe static partial class MyHeader
{
    public static readonly int* SomeGlobalVariable = (int*)NativeLibrary.GetExport(NativeLibrary.Load("Example.dll"), "?SomeGlobalVariable@@3HA");
    [DllImport("Example.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "?MyLooseFunction@@YAXXZ", ExactSpelling = true)]
    public static extern void MyLooseFunction();
}
```
### Example with an existing type
Consider a similar file named `AssociateAutomatically.h`:
```cpp
int SomeGlobalVariable;
void MyLooseFunction();
void AssociateAutomatically();
class AssociateAutomatically
{
    void SomeInstanceMethod();
};
```
Biohazrd's translation stage will output the following declaration tree:
```
TranslatedStaticField SomeGlobalVariable
TranslatedFunction MyLooseFunction
TranslatedFunction AssociateAutomatically
TranslatedRecord AssociateAutomatically
    TranslatedFunction SomeInstanceMethod
```
This time, the transformation doesn't synthesize a new type to contain the loose declarations and instead uses the already-existing `AssociateAutomatically` class:
```
TranslatedRecord AssociateAutomatically
    TranslatedFunction SomeInstanceMethod
    TranslatedStaticField SomeGlobalVariable
    TranslatedFunction MyLooseFunction
    TranslatedFunction AssociateAutomatically__ ☣
```
One thing to note is the function named `AssociateAutomatically` (marked with a ☣ above) was renamed to `AssociateAutomatically__` in order to disambiguate it from the containing struct when the C# output is generated:
```csharp
// This file was automatically generated by Biohazrd and should not be modified by hand!
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit, Size = 1)]
public unsafe partial struct AssociateAutomatically
{
    [DllImport("Example.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "?SomeInstanceMethod@AssociateAutomatically@@AEAAXXZ", ExactSpelling = true)]
    private static extern void SomeInstanceMethod_PInvoke(AssociateAutomatically* @this);
    private unsafe void SomeInstanceMethod()
    {
        fixed (AssociateAutomatically* @this = &this)
        { SomeInstanceMethod_PInvoke(@this); }
    }
    public static readonly int* SomeGlobalVariable = (int*)NativeLibrary.GetExport(NativeLibrary.Load("Example.dll"), "?SomeGlobalVariable@@3HA");
    [DllImport("Example.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "?MyLooseFunction@@YAXXZ", ExactSpelling = true)]
    public static extern void MyLooseFunction();
    [DllImport("Example.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "?AssociateAutomatically@@YAXXZ", ExactSpelling = true)]
    public static extern void AssociateAutomatically__(); // ☣
}
```
Additionally, a warning was issued:
```
⚠ Warning: Function AssociateAutomatically automatically renamed to avoid collision with containing type.
```