forked from MochiLibraries/Biohazrd
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathBiohzardExtensions.cs
91 lines (79 loc) · 4.4 KB
/
BiohzardExtensions.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
using Biohazrd.CSharp.Trampolines;
using Biohazrd.Expressions;
using Biohazrd.Transformation;
using System;
using System.Collections.Generic;
namespace Biohazrd.CSharp
{
public static class BiohzardExtensions
{
public static string ToCSharpKeyword(this AccessModifier modifier)
=> modifier switch
{
AccessModifier.Private => "private",
AccessModifier.Protected => "protected",
AccessModifier.Internal => "internal",
AccessModifier.ProtectedOrInternal => "protected internal",
AccessModifier.ProtectedAndInternal => "private protected",
AccessModifier.Public => "public",
_ => throw new ArgumentException("Invalid access modifier specified.", nameof(modifier))
};
/// <remarks>
/// This method helps avoid CS1527: Elements defined in a namespace cannot be explicitly declared as private, protected, protected internal, or private protected.
///
/// It also applies to elements defined at file scope.
/// </remarks>
public static bool IsAllowedInNamespaceScope(this AccessModifier modifier)
=> modifier == AccessModifier.Internal || modifier == AccessModifier.Public;
private static bool IsValidFieldOrMethodParent(this IEnumerable<TranslatedDeclaration> declaration)
=> declaration is TranslatedRecord or SynthesizedLooseDeclarationsTypeDeclaration;
public static bool IsValidFieldOrMethodContext(this TransformationContext context)
=> context.Parent.IsValidFieldOrMethodParent();
public static bool IsValidFieldOrMethodContext(this VisitorContext context)
=> context.Parent.IsValidFieldOrMethodParent();
// On the fence about this being built-in, so it's an extension method for now
internal static TDeclaration WithError<TDeclaration>(this TDeclaration declaration, string errorMessage)
where TDeclaration : TranslatedDeclaration
=> declaration with
{
Diagnostics = declaration.Diagnostics.Add(Severity.Error, errorMessage)
};
internal static TDeclaration WithWarning<TDeclaration>(this TDeclaration declaration, string warningMessage)
where TDeclaration : TranslatedDeclaration
=> declaration with
{
Diagnostics = declaration.Diagnostics.Add(Severity.Warning, warningMessage)
};
public static TypeReference? InferType(this ConstantValue value)
=> value switch
{
IntegerConstant integer => integer.SizeBits switch
{
8 => integer.IsSigned ? CSharpBuiltinType.SByte : CSharpBuiltinType.Byte,
16 => integer.IsSigned ? CSharpBuiltinType.Short : CSharpBuiltinType.UShort,
32 => integer.IsSigned ? CSharpBuiltinType.Int : CSharpBuiltinType.UInt,
64 => integer.IsSigned ? CSharpBuiltinType.Long : CSharpBuiltinType.ULong,
_ => (TypeReference?)null
},
FloatConstant => CSharpBuiltinType.Float,
DoubleConstant => CSharpBuiltinType.Double,
StringConstant => CSharpBuiltinType.String,
NullPointerConstant => CSharpBuiltinType.NativeInt,
_ => null
};
public static Trampoline? TryGetPrimaryTrampoline(this TranslatedFunction function)
=> function.Metadata.TryGet(out TrampolineCollection trampolines) ? trampolines.PrimaryTrampoline : null;
public static Trampoline GetPrimaryTrampoline(this TranslatedFunction function)
=> function.TryGetPrimaryTrampoline() ?? throw new InvalidOperationException("Tried to get the primary trampoline of a function with no trampoline metadata.");
public static TranslatedFunction WithSecondaryTrampoline(this TranslatedFunction function, Trampoline secondaryTrampoline)
{
if (!function.Metadata.TryGet(out TrampolineCollection trampolines))
{ throw new InvalidOperationException("Cannot add a secondary trampoline to a function which has no trampolines."); }
trampolines = trampolines.WithTrampoline(secondaryTrampoline);
return function with
{
Metadata = function.Metadata.Set(trampolines)
};
}
}
}