This repository has been archived by the owner on Dec 13, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 11
/
ClrImporter.cs
105 lines (90 loc) · 5.18 KB
/
ClrImporter.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
using FogCreek.Wasabi.AST;
using Mono.Cecil;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CustomAttributeCollection = Mono.Collections.Generic.Collection<Mono.Cecil.CustomAttribute>;
namespace FogCreek.Wasabi
{
/// <summary>
/// Just enough to be able to declare return types! Very incomplete!
/// </summary>
public class ClrImporter
{
public static void LoadBuiltins(CProgram program)
{
ImportType(program, SearchAssembliesForType(program, "System.Object"), BuiltIns.Variant);
ImportType(program, SearchAssembliesForType(program, "System.String"), BuiltIns.String);
CClass vtype = program.FindClass("System.ValueType");
ImportType(program, SearchAssembliesForType(program, "System.Byte"), BuiltIns.Byte);
BuiltIns.Byte.ForceSetBaseClass(vtype);
ImportType(program, SearchAssembliesForType(program, "System.Int32"), BuiltIns.Int32);
BuiltIns.Int32.ForceSetBaseClass(vtype);
ImportType(program, SearchAssembliesForType(program, "System.Int64"), BuiltIns.Int64);
BuiltIns.Int64.ForceSetBaseClass(vtype);
ImportType(program, SearchAssembliesForType(program, "System.Char"), BuiltIns.Character);
BuiltIns.Character.ForceSetBaseClass(vtype);
ImportType(program, SearchAssembliesForType(program, "System.Boolean"), BuiltIns.Boolean);
BuiltIns.Boolean.ForceSetBaseClass(vtype);
ImportType(program, SearchAssembliesForType(program, "System.DateTime"), BuiltIns.Date);
BuiltIns.Date.ForceSetBaseClass(vtype);
ImportType(program, SearchAssembliesForType(program, "System.Double"), BuiltIns.Double);
BuiltIns.Double.ForceSetBaseClass(vtype);
BuiltIns.Variant.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.Variant, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
BuiltIns.Object.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.Object, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
BuiltIns.String.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.String, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
BuiltIns.Byte.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.Byte, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
BuiltIns.Int32.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.Int32, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
BuiltIns.Int64.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.Int64, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
BuiltIns.Character.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.Character, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
BuiltIns.Boolean.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.Boolean, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
BuiltIns.Date.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.Date, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
BuiltIns.Double.Attributes.Add(CToken.Identifer(null, "ExecuteAnywhere"), new CTypeRef(BuiltIns.Double, CToken.Identifer(null, "ExecuteAnywhereAttribute")));
}
private static TypeDefinition SearchAssembliesForType(CProgram program, string name)
{
foreach (var asm in program.Assemblies)
{
var typed = asm.MainModule.Types.FirstOrDefault(td => td.FullName == name);
if (typed != null)
return typed;
}
return null;
}
private static bool IsClsCompliant(CustomAttributeCollection customAttributeCollection)
{
foreach (CustomAttribute attr in FindAttributes(customAttributeCollection, "System.CLSCompliantAttribute"))
{
if (attr.ConstructorArguments.Count > 0)
return (bool)attr.ConstructorArguments[0].Value;
}
return true;
}
private static IEnumerable<CustomAttribute> FindAttributes(CustomAttributeCollection attrs, string name)
{
if (attrs != null)
foreach (CustomAttribute attr in attrs)
{
if (attr.Constructor.DeclaringType.FullName == name)
yield return attr;
}
}
private static void ImportType(CProgram program, TypeDefinition typed, CClass type)
{
if (type.CecilType != null)
return;
type.CecilType = typed;
if (typed.GenericParameters.Count > 0 || !IsClsCompliant(typed.CustomAttributes))
return;
if (typed.IsEnum)
{
type.IsObject = false;
type.IsNumeric = true;
}
type.IsObject = !typed.IsValueType;
type.SetSemanticallyComplete();
}
}
}