Skip to content

Commit

Permalink
Merge pull request #121 from MrJul/feature/nullable-enable
Browse files Browse the repository at this point in the history
Nullable reference types
  • Loading branch information
maxkatz6 authored Jun 5, 2024
2 parents 941dafc + f5aa2e3 commit 14fed0c
Show file tree
Hide file tree
Showing 108 changed files with 1,257 additions and 1,252 deletions.
2 changes: 2 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

<PropertyGroup>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<WarningsAsErrors>$(WarningsAsErrors);nullable</WarningsAsErrors>
</PropertyGroup>

<ItemGroup>
Expand Down
5 changes: 2 additions & 3 deletions src/BenchmarksCompiler/Program.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
Expand All @@ -8,7 +7,6 @@
using Mono.Cecil.Rocks;
using XamlX.Emit;
using XamlX.IL;
using XamlX.Transform;
using XamlX.TypeSystem;

namespace BenchmarksCompiler
Expand All @@ -21,7 +19,8 @@ static void Main(string[] args)
var refsPath = target + ".refs";
var refs = File.ReadAllLines(refsPath).Concat(new[] {target});
var typeSystem = new CecilTypeSystem(refs, target);
var asm = typeSystem.GetAssembly(typeSystem.FindAssembly("Benchmarks"));
var xamlAssembly = typeSystem.FindAssembly("Benchmarks") ?? throw new InvalidOperationException("Benchmarks assembly not found");
var asm = typeSystem.GetAssembly(xamlAssembly);
var config = Benchmarks.BenchmarksXamlXConfiguration.Configure(typeSystem);
var loadBench = asm.MainModule.Types.First(t => t.Name == "LoadBenchmark");
var baseMethod = loadBench.Methods.First(m => m.Name == "LoadXamlPrecompiled");
Expand Down
8 changes: 4 additions & 4 deletions src/XamlX.IL.Cecil/CecilAssembly.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ partial class CecilTypeSystem
{
internal class CecilAssembly : IXamlAssembly
{
private Dictionary<string, IXamlType> _typeCache = new();
private readonly Dictionary<string, IXamlType> _typeCache = new();

public CecilTypeSystem TypeSystem { get; }
public AssemblyDefinition Assembly { get; }
Expand All @@ -20,15 +20,15 @@ public CecilAssembly(CecilTypeSystem typeSystem, AssemblyDefinition assembly)
Assembly = assembly;
}

public bool Equals(IXamlAssembly other) => other == this;
public bool Equals(IXamlAssembly? other) => other == this;

public string Name => Assembly.Name.Name;
private IReadOnlyList<IXamlCustomAttribute> _attributes;
private IReadOnlyList<IXamlCustomAttribute>? _attributes;

public IReadOnlyList<IXamlCustomAttribute> CustomAttributes =>
_attributes ??= Assembly.CustomAttributes.Select(ca => new CecilCustomAttribute(TypeSystem.RootTypeResolveContext, ca)).ToList();

public IXamlType FindType(string fullName)
public IXamlType? FindType(string fullName)
{
if (_typeCache.TryGetValue(fullName, out var rv))
return rv;
Expand Down
16 changes: 8 additions & 8 deletions src/XamlX.IL.Cecil/CecilCustomAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,14 @@ public CecilCustomAttribute(CecilTypeResolveContext typeResolveContext, CustomAt
Data = data;
}

public bool Equals(IXamlCustomAttribute other) => other is CecilCustomAttribute ca && ca.Data == Data;
public bool Equals(IXamlCustomAttribute? other) => other is CecilCustomAttribute ca && ca.Data == Data;

private IXamlType _type;
private IXamlType? _type;
public IXamlType Type => _type ??= _typeResolveContext.Resolve(Data.AttributeType);

private List<object> _parameters;
private List<object?>? _parameters;

object ConvertValue(object value)
object? ConvertValue(object? value)
{
if (value is TypeReference tr)
return _typeResolveContext.Resolve(tr);
Expand All @@ -36,18 +36,18 @@ object ConvertValue(object value)
return value;
}

public List<object> Parameters =>
public List<object?> Parameters =>
_parameters ??= Data.ConstructorArguments.Select(d => ConvertValue(d.Value)).ToList();

private Dictionary<string, object> _properties;
private Dictionary<string, object?>? _properties;

public Dictionary<string, object> Properties
public Dictionary<string, object?> Properties
{
get
{
if (_properties is null)
{
Dictionary<string, object> properties = new Dictionary<string, object>();
var properties = new Dictionary<string, object?>();
foreach (var prop in Data.Properties)
{
properties.Add(prop.Name, ConvertValue(prop.Argument.Value));
Expand Down
21 changes: 11 additions & 10 deletions src/XamlX.IL.Cecil/CecilEmitter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using System.Security.Cryptography;
using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;
using XamlX.IL;
using MethodBody = Mono.Cecil.Cil.MethodBody;
using SreOpCode = System.Reflection.Emit.OpCode;
Expand Down Expand Up @@ -68,7 +67,7 @@ static CecilEmitter()
.Where(f=>f.FieldType == typeof(SreOpCode)))

{
var sre = (SreOpCode) sreField.GetValue(null);
var sre = (SreOpCode) sreField.GetValue(null)!;

var cecil = sreField.Name switch
{
Expand All @@ -87,8 +86,9 @@ static CecilEmitter()

private readonly MethodBody _body;
private readonly MethodDefinition _method;
private CecilDebugPoint _pendingDebugPoint;
private CecilDebugPoint _lastDebugPoint;
private CecilDebugPoint? _pendingDebugPoint;
private CecilDebugPoint? _lastDebugPoint;

public CecilEmitter(IXamlTypeSystem typeSystem, MethodDefinition method)
{
_method = method;
Expand Down Expand Up @@ -175,17 +175,18 @@ public IXamlILEmitter Emit(SreOpCode code, float arg)
public IXamlILEmitter Emit(SreOpCode code, double arg)
=> Emit(Instruction.Create(Dic[code], arg));

class CecilLocal : IXamlILLocal
class CecilLocal(VariableDefinition variable) : IXamlILLocal
{
public VariableDefinition Variable { get; set; }
public VariableDefinition Variable { get; } = variable;

public int Index => Variable.Index;
}

class CecilLabel : IXamlLabel
{
private List<Instruction> _pendingConsumers;
private Instruction _target;
private List<Instruction>? _pendingConsumers;
private Instruction? _target;

public Instruction CreateInstruction(OpCode opcode)
{
if (_target != null)
Expand Down Expand Up @@ -215,7 +216,7 @@ public IXamlLocal DefineLocal(IXamlType type)
var r = Import(((ITypeReference) type).Reference);
var def = new VariableDefinition(r);
_body.Variables.Add(def);
return new CecilLocal {Variable = def};
return new CecilLocal(def);
}

public IXamlLabel DefineLabel() => new CecilLabel();
Expand Down Expand Up @@ -318,7 +319,7 @@ public DocumentHelper(IFileSource file)
Hash = hash,
};
var r = new StreamReader(new MemoryStream(data));
string l;
string? l;
while ((l = r.ReadLine()) != null)
Lines.Add(l);
}
Expand Down
15 changes: 10 additions & 5 deletions src/XamlX.IL.Cecil/CecilEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,23 @@ public CecilEvent(CecilTypeResolveContext typeResolveContext, EventDefinition ev

public string Name => Event.Name;

private IXamlMethod _getter;
private IXamlMethod? _add;

public IXamlMethod Add => Event.AddMethod == null
public IXamlMethod? Add => Event.AddMethod == null
? null
: _getter ??= new CecilMethod(_typeResolveContext, Event.AddMethod);
: _add ??= new CecilMethod(_typeResolveContext, Event.AddMethod);

public bool Equals(IXamlEventInfo other) =>
private IXamlType? _declaringType;

public IXamlType DeclaringType
=> _declaringType ??= _typeResolveContext.Resolve(Event.DeclaringType);

public bool Equals(IXamlEventInfo? other) =>
other is CecilEvent cf
&& TypeReferenceEqualityComparer.AreEqual(Event.DeclaringType, cf.Event.DeclaringType, CecilTypeComparisonMode.Exact)
&& cf.Event.FullName == Event.FullName;

public override bool Equals(object other) => Equals(other as IXamlEventInfo);
public override bool Equals(object? other) => Equals(other as IXamlEventInfo);

public override int GetHashCode() =>
(TypeReferenceEqualityComparer.GetHashCodeFor(Event.DeclaringType, CecilTypeComparisonMode.Exact), Event.FullName).GetHashCode();
Expand Down
17 changes: 12 additions & 5 deletions src/XamlX.IL.Cecil/CecilField.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Mono.Cecil;
Expand All @@ -22,29 +23,35 @@ public CecilField(CecilTypeResolveContext typeResolveContext, FieldDefinition de
}

public string Name => Field.Name;
private IXamlType _type;
private IXamlType? _type;
public IXamlType FieldType => _type ??= _typeResolveContext.ResolveFieldType(Field);
public bool IsPublic => _def.IsPublic;
public bool IsStatic => _def.IsStatic;
public bool IsLiteral => _def.IsLiteral;

private IReadOnlyList<IXamlCustomAttribute> _attributes;
private IReadOnlyList<IXamlCustomAttribute>? _attributes;

public IReadOnlyList<IXamlCustomAttribute> CustomAttributes =>
_attributes ??= _def.CustomAttributes.Select(ca => new CecilCustomAttribute(_typeResolveContext, ca)).ToList();

private IXamlType? _declaringType;

public IXamlType DeclaringType
=> _declaringType ??= _typeResolveContext.Resolve(Field.DeclaringType);

public object GetLiteralValue()
{
if (IsLiteral && _def.HasConstant)
return _def.Constant;
return null;
throw new InvalidOperationException($"{this} isn't a literal");
}

public bool Equals(IXamlField other) =>
public bool Equals(IXamlField? other) =>
other is CecilField cf
&& TypeReferenceEqualityComparer.AreEqual(Field.DeclaringType, cf.Field.DeclaringType, CecilTypeComparisonMode.Exact)
&& cf.Field.FullName == Field.FullName;

public override bool Equals(object other) => Equals(other as IXamlField);
public override bool Equals(object? other) => Equals(other as IXamlField);

public override int GetHashCode() =>
(TypeReferenceEqualityComparer.GetHashCodeFor(Field.DeclaringType, CecilTypeComparisonMode.Exact), Field.FullName).GetHashCode();
Expand Down
14 changes: 7 additions & 7 deletions src/XamlX.IL.Cecil/CecilFunctionPointer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal class CecilFunctionPointerType : IXamlType, ITypeReference
public string Namespace => _reference.Namespace;
public bool IsPublic => true;
public bool IsNestedPrivate => false;
public IXamlAssembly Assembly => null;
public IXamlAssembly? Assembly => null;
public IReadOnlyList<IXamlProperty> Properties => Array.Empty<IXamlProperty>();
public IReadOnlyList<IXamlEventInfo> Events => Array.Empty<IXamlEventInfo>();
public IReadOnlyList<IXamlField> Fields => Array.Empty<IXamlField>();
Expand All @@ -34,20 +34,20 @@ internal class CecilFunctionPointerType : IXamlType, ITypeReference
public bool IsEnum => false;
public bool IsInterface => false;
public bool IsFunctionPointer => true;
public IXamlType GenericTypeDefinition => null;
public IXamlType ArrayElementType => null;
public IXamlType BaseType => null;
public IXamlType DeclaringType => null;
public IXamlType? GenericTypeDefinition => null;
public IXamlType? ArrayElementType => null;
public IXamlType? BaseType => null;
public IXamlType? DeclaringType => null;

public IXamlType MakeGenericType(IReadOnlyList<IXamlType> typeArguments) => throw new InvalidOperationException();
public IXamlType MakeArrayType(int dimensions) => throw new InvalidOperationException();
public IXamlType GetEnumUnderlyingType() => throw new InvalidOperationException();

public bool Equals(IXamlType other)
public bool Equals(IXamlType? other)
=> other is CecilFunctionPointerType typedOther &&
TypeReferenceEqualityComparer.AreEqual(Reference, typedOther.Reference, CecilTypeComparisonMode.Exact);

public override bool Equals(object obj) => Equals(obj as IXamlType);
public override bool Equals(object? obj) => Equals(obj as IXamlType);
public override int GetHashCode() => TypeReferenceEqualityComparer.GetHashCodeFor(Reference, CecilTypeComparisonMode.Exact);
public bool IsAssignableFrom(IXamlType type) => Equals(type);
}
Expand Down
20 changes: 10 additions & 10 deletions src/XamlX.IL.Cecil/CecilMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public CecilParameterInfo(CecilTypeResolveContext typeResolveContext, ParameterR

public string Name => _parameterReference.Name;

private IXamlType _parameterType;
private IXamlType? _parameterType;
public IXamlType ParameterType => _parameterType ??= _typeResolveContext.Resolve(_parameterReference.ParameterType);
public IReadOnlyList<IXamlCustomAttribute> CustomAttributes => _parameterReference.Resolve().CustomAttributes
.Select(ca => new CecilCustomAttribute(_typeResolveContext, ca)).ToList();
Expand All @@ -48,31 +48,31 @@ public CecilMethodBase(CecilTypeResolveContext typeResolveContext, MethodReferen
public bool IsFamily => Definition.IsFamily;
public bool IsStatic => Definition.IsStatic;

private IXamlType _returnType;
private IXamlType? _returnType;

public IXamlType ReturnType =>
_returnType ??= TypeResolveContext.ResolveReturnType(Reference);

private IXamlType _declaringType;
private IXamlType? _declaringType;

public IXamlType DeclaringType =>
_declaringType ??= TypeResolveContext.Resolve(Reference.DeclaringType);

public IReadOnlyList<IXamlType> Parameters => ParameterInfos.Select(p => p.ParameterType).ToList();

private IReadOnlyList<IXamlCustomAttribute> _attributes;
private IReadOnlyList<IXamlCustomAttribute>? _attributes;

public IReadOnlyList<IXamlCustomAttribute> CustomAttributes =>
_attributes ??= Definition.CustomAttributes.Select(ca => new CecilCustomAttribute(TypeResolveContext, ca)).ToList();

private IXamlILEmitter _generator;
private IXamlILEmitter? _generator;

public IXamlILEmitter Generator =>
_generator ??= new CecilEmitter(TypeResolveContext.TypeSystem, Definition);

public IXamlParameterInfo GetParameterInfo(int index) => ParameterInfos[index];

private IReadOnlyList<IXamlParameterInfo> _parameterInfos;
private IReadOnlyList<IXamlParameterInfo>? _parameterInfos;
private IReadOnlyList<IXamlParameterInfo> ParameterInfos =>
_parameterInfos ??= Reference.Parameters.Select(p => new CecilParameterInfo(TypeResolveContext, p)).ToList();

Expand All @@ -99,11 +99,11 @@ public IXamlMethod MakeGenericMethod(IReadOnlyList<IXamlType> typeArguments)
return new CecilMethod(TypeResolveContext, instantiation);
}

public bool Equals(IXamlMethod other) =>
public bool Equals(IXamlMethod? other) =>
other is CecilMethod cm
&& MethodReferenceEqualityComparer.AreEqual(Reference, cm.Reference, CecilTypeComparisonMode.Exact);

public override bool Equals(object other) => Equals(other as IXamlMethod);
public override bool Equals(object? other) => Equals(other as IXamlMethod);

public override int GetHashCode()
=> MethodReferenceEqualityComparer.GetHashCodeFor(Reference, CecilTypeComparisonMode.Exact);
Expand All @@ -117,11 +117,11 @@ public CecilConstructor(CecilTypeResolveContext typeResolveContext, MethodDefini
{
}

public bool Equals(IXamlConstructor other) =>
public bool Equals(IXamlConstructor? other) =>
other is CecilConstructor cm
&& MethodReferenceEqualityComparer.AreEqual(Reference, cm.Reference, CecilTypeComparisonMode.Exact);

public override bool Equals(object other) => Equals(other as IXamlConstructor);
public override bool Equals(object? other) => Equals(other as IXamlConstructor);

public override int GetHashCode()
=> MethodReferenceEqualityComparer.GetHashCodeFor(Reference, CecilTypeComparisonMode.Exact);
Expand Down
Loading

0 comments on commit 14fed0c

Please sign in to comment.