Browse Source

Add a mechanism to the FastSerializer that allows us to invalidate cached project contents when fixing a bug in one of the type system loaders.

newNRvisualizers
Daniel Grunwald 13 years ago
parent
commit
d0bed831ae
  1. 5
      ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpUnresolvedFile.cs
  2. 3
      ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpUnresolvedTypeDefinition.cs
  3. 7
      ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs
  4. 18
      ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs
  5. 42
      ICSharpCode.NRefactory/Utils/FastSerializer.cs

5
ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpUnresolvedFile.cs

@ -22,6 +22,7 @@ using ICSharpCode.NRefactory.Documentation; @@ -22,6 +22,7 @@ using ICSharpCode.NRefactory.Documentation;
using ICSharpCode.NRefactory.Editor;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.NRefactory.Utils;
using System.Linq;
namespace ICSharpCode.NRefactory.CSharp.TypeSystem
@ -29,9 +30,11 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -29,9 +30,11 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
/// <summary>
/// Represents a file that was parsed and converted for the type system.
/// </summary>
[Serializable]
[Serializable, FastSerializerVersion(TypeSystemConvertVisitor.version)]
public sealed class CSharpUnresolvedFile : AbstractFreezable, IUnresolvedFile, IUnresolvedDocumentationProvider
{
// The 'FastSerializerVersion' on CSharpUnresolvedFile must be incremented when fixing
readonly string fileName;
readonly UsingScope rootUsingScope;
IList<IUnresolvedTypeDefinition> topLevelTypeDefinitions = new List<IUnresolvedTypeDefinition>();

3
ICSharpCode.NRefactory.CSharp/TypeSystem/CSharpUnresolvedTypeDefinition.cs

@ -19,10 +19,11 @@ @@ -19,10 +19,11 @@
using System;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
using ICSharpCode.NRefactory.Utils;
namespace ICSharpCode.NRefactory.CSharp.TypeSystem
{
[Serializable]
[Serializable, FastSerializerVersion(TypeSystemConvertVisitor.version)]
public class CSharpUnresolvedTypeDefinition : DefaultUnresolvedTypeDefinition
{
readonly UsingScope usingScope;

7
ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs

@ -34,6 +34,13 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem @@ -34,6 +34,13 @@ namespace ICSharpCode.NRefactory.CSharp.TypeSystem
/// </summary>
public class TypeSystemConvertVisitor : DepthFirstAstVisitor<IUnresolvedEntity>
{
/// <summary>
/// Version of the C# type system loader.
/// Should be incremented when fixing bugs so that project contents cached on disk
/// (which might be incorrect due to the bug) are re-created.
/// </summary>
internal const int version = 1;
readonly CSharpUnresolvedFile unresolvedFile;
UsingScope usingScope;
CSharpUnresolvedTypeDefinition currentTypeDefinition;

18
ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs

@ -18,13 +18,10 @@ @@ -18,13 +18,10 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Threading;
using ICSharpCode.NRefactory.Documentation;
using ICSharpCode.NRefactory.Semantics;
@ -41,6 +38,13 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -41,6 +38,13 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// if you want to load multiple project contents in parallel.</remarks>
public class CecilLoader
{
/// <summary>
/// Version number of the cecil loader.
/// Should be incremented when fixing bugs in the cecil loader so that project contents cached on disk
/// (which might be incorrect due to the bug) are re-created.
/// </summary>
const int cecilLoaderVersion = 1;
#region Options
/// <summary>
/// Specifies whether to include internal members. The default is false.
@ -248,7 +252,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -248,7 +252,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
#endregion
#region IUnresolvedAssembly implementation
[Serializable]
[Serializable, FastSerializerVersion(cecilLoaderVersion)]
sealed class CecilUnresolvedAssembly : DefaultUnresolvedAssembly, IDocumentationProvider
{
readonly IDocumentationProvider documentationProvider;
@ -810,7 +814,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -810,7 +814,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
return true;
}
[Serializable]
[Serializable, FastSerializerVersion(cecilLoaderVersion)]
sealed class CecilUnresolvedAttribute : IUnresolvedAttribute, ISupportsInterning
{
internal readonly ITypeReference attributeType;
@ -1370,7 +1374,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1370,7 +1374,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
}
}
[Serializable]
[Serializable, FastSerializerVersion(cecilLoaderVersion)]
sealed class UnresolvedSecurityDeclaration : ISupportsInterning
{
IConstantValue securityAction;
@ -1457,7 +1461,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -1457,7 +1461,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
}
}
[Serializable]
[Serializable, FastSerializerVersion(cecilLoaderVersion)]
sealed class UnresolvedSecurityAttribute : IUnresolvedAttribute
{
readonly UnresolvedSecurityDeclaration secDecl;

42
ICSharpCode.NRefactory/Utils/FastSerializer.cs

@ -47,7 +47,7 @@ namespace ICSharpCode.NRefactory.Utils @@ -47,7 +47,7 @@ namespace ICSharpCode.NRefactory.Utils
#endregion
#region Constants
const int magic = 0x71D28A5D;
const int magic = 0x71D28A5E;
const byte Type_ReferenceType = 1;
const byte Type_ValueType = 2;
@ -289,6 +289,7 @@ namespace ICSharpCode.NRefactory.Utils @@ -289,6 +289,7 @@ namespace ICSharpCode.NRefactory.Utils
Type type = sType.Type;
if (type.IsGenericTypeDefinition || type.HasElementType)
continue;
writer.Write(FastSerializerVersionAttribute.GetVersionNumber(type));
if (type.IsPrimitive || typeof(ISerializable).IsAssignableFrom(type)) {
writer.Write(byte.MaxValue);
} else {
@ -812,6 +813,10 @@ namespace ICSharpCode.NRefactory.Utils @@ -812,6 +813,10 @@ namespace ICSharpCode.NRefactory.Utils
Type type = this.Types[i];
if (type.IsGenericTypeDefinition || type.HasElementType)
continue;
int versionNumber = Reader.ReadInt32();
if (versionNumber != FastSerializerVersionAttribute.GetVersionNumber(type))
throw new SerializationException("Type '" + type.FullName + "' was serialized with version " + versionNumber + ", but is version " + FastSerializerVersionAttribute.GetVersionNumber(type));
bool isCustomSerialization = typeof(ISerializable).IsAssignableFrom(type);
bool typeIsSpecial = type.IsPrimitive || isCustomSerialization;
@ -819,10 +824,10 @@ namespace ICSharpCode.NRefactory.Utils @@ -819,10 +824,10 @@ namespace ICSharpCode.NRefactory.Utils
if (serializedFieldCount == byte.MaxValue) {
// special type
if (!typeIsSpecial)
throw new SerializationException("Type " + type + " was serialized as special type, but isn't special now.");
throw new SerializationException("Type '" + type.FullName + "' was serialized as special type, but isn't special now.");
} else {
if (typeIsSpecial)
throw new SerializationException("Type " + type.FullName + " wasn't serialized as special type, but is special now.");
throw new SerializationException("Type '" + type.FullName + "' wasn't serialized as special type, but is special now.");
var availableFields = GetSerializableFields(this.Types[i]);
if (availableFields.Count != serializedFieldCount)
@ -1332,4 +1337,35 @@ namespace ICSharpCode.NRefactory.Utils @@ -1332,4 +1337,35 @@ namespace ICSharpCode.NRefactory.Utils
Debug.WriteLine(format, args);
}
}
/// <summary>
/// Specifies the version of the class.
/// The <see cref="FastSerializer"/> will refuse to deserialize an instance that was stored by
/// a different version of the class than the current one.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum)]
public class FastSerializerVersionAttribute : Attribute
{
readonly int versionNumber;
public FastSerializerVersionAttribute(int versionNumber)
{
this.versionNumber = versionNumber;
}
public int VersionNumber {
get {
return versionNumber;
}
}
internal static int GetVersionNumber(Type type)
{
var arr = type.GetCustomAttributes(typeof(FastSerializerVersionAttribute), false);
if (arr.Length == 0)
return 0;
else
return ((FastSerializerVersionAttribute)arr[0]).VersionNumber;
}
}
}

Loading…
Cancel
Save