Browse Source

Fixed SD2-1581 - GetterModifiers/SetterModifiers not loaded in ReflectionProperty and CecilReader

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/3.0@4736 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 16 years ago
parent
commit
1915a2c328
  1. 54
      src/Main/Base/Test/ReflectionLayerTests.cs
  2. 58
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CecilReader.cs
  3. 10
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DefaultProjectContent.cs
  4. 4
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/IProjectContent.cs
  5. 2
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/DomPersistence.cs
  6. 40
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionProperty.cs
  7. 2
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/XmlDoc.cs

54
src/Main/Base/Test/ReflectionLayerTests.cs

@ -259,27 +259,34 @@ namespace ICSharpCode.SharpDevelop.Tests
public void TestMethod<K, V>(string param) where V: K where K: IComparable {} public void TestMethod<K, V>(string param) where V: K where K: IComparable {}
public void GetIndex<T>(T element) where T: IEquatable<T> {} public void GetIndex<T>(T element) where T: IEquatable<T> {}
public int Property { get; protected set; }
public int ReadOnlyPropertyWithPrivateSetter { get; private set; }
} }
protected abstract IClass GetClass(Type type); protected abstract IClass GetClass(Type type);
protected abstract IEnumerable<IAttribute> GetAssemblyAttributes(Assembly assembly); protected abstract IEnumerable<IAttribute> GetAssemblyAttributes(Assembly assembly);
[Test] IClass testClass;
public void ReflectionParserTest()
{
IClass c = GetClass(typeof(TestClass<,>));
CheckClass(c); [TestFixtureSetUp]
public void FixtureSetUp()
{
testClass = GetClass(typeof(TestClass<,>));
} }
void CheckClass(IClass c) [Test]
public void TestClassTypeParameters()
{ {
Assert.AreSame(c, c.TypeParameters[0].Class); Assert.AreSame(testClass, testClass.TypeParameters[0].Class);
Assert.AreSame(c, c.TypeParameters[1].Class); Assert.AreSame(testClass, testClass.TypeParameters[1].Class);
Assert.AreSame(c.TypeParameters[1], ((GenericReturnType)c.TypeParameters[0].Constraints[0]).TypeParameter); Assert.AreSame(testClass.TypeParameters[1], ((GenericReturnType)testClass.TypeParameters[0].Constraints[0]).TypeParameter);
}
IMethod m = c.Methods.First(delegate(IMethod me) { return me.Name == "TestMethod"; }); [Test]
Assert.IsNotNull(m); public void TestMethod()
{
IMethod m = testClass.Methods.Single(me => me.Name == "TestMethod");
Assert.AreEqual("K", m.TypeParameters[0].Name); Assert.AreEqual("K", m.TypeParameters[0].Name);
Assert.AreEqual("V", m.TypeParameters[1].Name); Assert.AreEqual("V", m.TypeParameters[1].Name);
Assert.AreSame(m, m.TypeParameters[0].Method); Assert.AreSame(m, m.TypeParameters[0].Method);
@ -288,9 +295,12 @@ namespace ICSharpCode.SharpDevelop.Tests
Assert.AreEqual("IComparable", m.TypeParameters[0].Constraints[0].Name); Assert.AreEqual("IComparable", m.TypeParameters[0].Constraints[0].Name);
GenericReturnType kConst = (GenericReturnType)m.TypeParameters[1].Constraints[0]; GenericReturnType kConst = (GenericReturnType)m.TypeParameters[1].Constraints[0];
Assert.AreSame(m.TypeParameters[0], kConst.TypeParameter); Assert.AreSame(m.TypeParameters[0], kConst.TypeParameter);
}
m = c.Methods.First(delegate(IMethod me) { return me.Name == "GetIndex"; }); [Test]
Assert.IsNotNull(m); public void GetIndex()
{
IMethod m = testClass.Methods.Single(me => me.Name == "GetIndex");
Assert.AreEqual("T", m.TypeParameters[0].Name); Assert.AreEqual("T", m.TypeParameters[0].Name);
Assert.AreSame(m, m.TypeParameters[0].Method); Assert.AreSame(m, m.TypeParameters[0].Method);
@ -301,6 +311,24 @@ namespace ICSharpCode.SharpDevelop.Tests
Assert.AreSame(m.TypeParameters[0], grt.TypeParameter); Assert.AreSame(m.TypeParameters[0], grt.TypeParameter);
} }
[Test]
public void Property()
{
IProperty p = testClass.Properties.Single(pr => pr.Name == "Property");
Assert.AreEqual(ModifierEnum.Public, p.Modifiers);
Assert.AreEqual(ModifierEnum.None, p.GetterModifiers);
Assert.AreEqual(ModifierEnum.Protected, p.SetterModifiers);
}
[Test]
public void CannotSetReadOnlyProperty()
{
IProperty p = testClass.Properties.Single(pr => pr.Name == "ReadOnlyPropertyWithPrivateSetter");
Assert.AreEqual(ModifierEnum.Public, p.Modifiers);
Assert.AreEqual(ModifierEnum.None, p.GetterModifiers);
Assert.IsFalse(p.CanSet);
}
[Test] [Test]
public void AssemblyAttribute() public void AssemblyAttribute()
{ {

58
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CecilReader.cs

@ -46,7 +46,7 @@ namespace ICSharpCode.SharpDevelop.Dom
try { try {
a.PositionalArguments.Add(ReflectionReturnType.Parse(pc, (string)o)); a.PositionalArguments.Add(ReflectionReturnType.Parse(pc, (string)o));
} catch (ReflectionTypeNameSyntaxError ex) { } catch (ReflectionTypeNameSyntaxError ex) {
LoggingService.Warn(ex); LoggingService.Warn("parsing '" + o + "'", ex);
a.PositionalArguments.Add(o); a.PositionalArguments.Add(o);
} }
} else { } else {
@ -304,25 +304,7 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
foreach (PropertyDefinition property in type.Properties) { foreach (PropertyDefinition property in type.Properties) {
if ((property.GetMethod != null && IsVisible(property.GetMethod.Attributes)) AddProperty(defaultMemberName, property);
|| (property.SetMethod != null && IsVisible(property.SetMethod.Attributes)))
{
DefaultProperty p = new DefaultProperty(this, property.Name);
if (this.ClassType == ClassType.Interface) {
p.Modifiers = ModifierEnum.Public | ModifierEnum.Abstract;
} else {
p.Modifiers = TranslateModifiers(property);
}
p.ReturnType = CreateType(this.ProjectContent, this, property.PropertyType);
p.CanGet = property.GetMethod != null;
p.CanSet = property.SetMethod != null;
if (p.Name == defaultMemberName) {
p.IsIndexer = true;
}
AddParameters(p, property.Parameters);
AddAttributes(CompilationUnit.ProjectContent, p.Attributes, property.CustomAttributes);
Properties.Add(p);
}
} }
foreach (EventDefinition eventDef in type.Events) { foreach (EventDefinition eventDef in type.Events) {
@ -349,6 +331,42 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
void AddProperty(string defaultMemberName, PropertyDefinition property)
{
if ((property.GetMethod != null && IsVisible(property.GetMethod.Attributes))
|| (property.SetMethod != null && IsVisible(property.SetMethod.Attributes)))
{
DefaultProperty p = new DefaultProperty(this, property.Name);
if (this.ClassType == ClassType.Interface) {
p.Modifiers = ModifierEnum.Public | ModifierEnum.Abstract;
} else {
p.Modifiers = TranslateModifiers(property);
}
p.ReturnType = CreateType(this.ProjectContent, this, property.PropertyType);
p.CanGet = property.GetMethod != null && IsVisible(property.GetMethod.Attributes);
p.CanSet = property.SetMethod != null && IsVisible(property.SetMethod.Attributes);
if (p.CanGet)
p.GetterModifiers = GetAccessorVisibility(p, property.GetMethod);
if (p.CanSet)
p.SetterModifiers = GetAccessorVisibility(p, property.SetMethod);
if (p.Name == defaultMemberName) {
p.IsIndexer = true;
}
AddParameters(p, property.Parameters);
AddAttributes(CompilationUnit.ProjectContent, p.Attributes, property.CustomAttributes);
Properties.Add(p);
}
}
static ModifierEnum GetAccessorVisibility(IProperty p, MethodDefinition accessor)
{
ModifierEnum visibility = ModifierEnum.VisibilityMask & TranslateModifiers(accessor);
if (visibility == (p.Modifiers & ModifierEnum.VisibilityMask))
return ModifierEnum.None;
else
return visibility;
}
void AddMethod(MethodDefinition method) void AddMethod(MethodDefinition method)
{ {
if (IsVisible(method.Attributes)) { if (IsVisible(method.Attributes)) {

10
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DefaultProjectContent.cs

@ -28,6 +28,7 @@ namespace ICSharpCode.SharpDevelop.Dom
XmlDoc xmlDoc = new XmlDoc(); XmlDoc xmlDoc = new XmlDoc();
IUsing defaultImports; IUsing defaultImports;
bool isDisposed;
public IUsing DefaultImports { public IUsing DefaultImports {
get { get {
@ -223,6 +224,7 @@ namespace ICSharpCode.SharpDevelop.Dom
public string GetXmlDocumentation(string memberTag) public string GetXmlDocumentation(string memberTag)
{ {
CheckNotDisposed();
string desc = xmlDoc.GetDocumentation(memberTag); string desc = xmlDoc.GetDocumentation(memberTag);
if (desc != null) { if (desc != null) {
return desc; return desc;
@ -241,6 +243,13 @@ namespace ICSharpCode.SharpDevelop.Dom
public virtual void Dispose() public virtual void Dispose()
{ {
xmlDoc.Dispose(); xmlDoc.Dispose();
isDisposed = true;
}
[Conditional("DEBUG")]
void CheckNotDisposed()
{
Debug.Assert(!isDisposed);
} }
public void AddClassToNamespaceList(IClass addClass) public void AddClassToNamespaceList(IClass addClass)
@ -588,6 +597,7 @@ namespace ICSharpCode.SharpDevelop.Dom
protected IClass GetClassInternal(string typeName, int typeParameterCount, LanguageProperties language) protected IClass GetClassInternal(string typeName, int typeParameterCount, LanguageProperties language)
{ {
CheckNotDisposed();
#if DEBUG #if DEBUG
if (System.Text.RegularExpressions.Regex.IsMatch (typeName, "`[0-9]+$")) if (System.Text.RegularExpressions.Regex.IsMatch (typeName, "`[0-9]+$"))
Debug.Assert(false, "how did a Reflection type name get here?"); Debug.Assert(false, "how did a Reflection type name get here?");

4
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/IProjectContent.cs

@ -11,8 +11,10 @@ using System.Collections.Generic;
namespace ICSharpCode.SharpDevelop.Dom namespace ICSharpCode.SharpDevelop.Dom
{ {
public interface IProjectContent : IDisposable public interface IProjectContent
{ {
void Dispose();
XmlDoc XmlDoc { XmlDoc XmlDoc {
get; get;
} }

2
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/DomPersistence.cs

@ -20,7 +20,7 @@ namespace ICSharpCode.SharpDevelop.Dom
{ {
public const long FileMagic = 0x11635233ED2F428C; public const long FileMagic = 0x11635233ED2F428C;
public const long IndexFileMagic = 0x11635233ED2F427D; public const long IndexFileMagic = 0x11635233ED2F427D;
public const short FileVersion = 22; public const short FileVersion = 23;
ProjectContentRegistry registry; ProjectContentRegistry registry;
string cacheDirectory; string cacheDirectory;

40
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/ReflectionProperty.cs

@ -34,16 +34,17 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
} }
} }
MethodInfo methodBase = null; MethodInfo getterMethod = null;
try { try {
methodBase = propertyInfo.GetGetMethod(true); getterMethod = propertyInfo.GetGetMethod(true);
} catch (Exception) {} } catch (Exception) {}
if (methodBase == null) { MethodInfo setterMethod = null;
try { try {
methodBase = propertyInfo.GetSetMethod(true); setterMethod = propertyInfo.GetSetMethod(true);
} catch (Exception) {} } catch (Exception) {}
}
MethodInfo methodBase = getterMethod ?? setterMethod;
ModifierEnum modifiers = ModifierEnum.None; ModifierEnum modifiers = ModifierEnum.None;
if (methodBase != null) { if (methodBase != null) {
@ -78,6 +79,35 @@ namespace ICSharpCode.SharpDevelop.Dom.ReflectionLayer
modifiers = ModifierEnum.Public; modifiers = ModifierEnum.Public;
} }
this.Modifiers = modifiers; this.Modifiers = modifiers;
if (getterMethod != null) {
ModifierEnum getterModifier = GetAccessorModifier(getterMethod);
if (getterModifier == ModifierEnum.Private) {
this.CanGet = false;
} else {
if (getterModifier != (modifiers & ModifierEnum.VisibilityMask))
this.GetterModifiers = getterModifier;
}
}
if (setterMethod != null) {
ModifierEnum setterModifier = GetAccessorModifier(setterMethod);
if (setterModifier == ModifierEnum.Private) {
this.CanSet = false;
} else {
if (setterModifier != (modifiers & ModifierEnum.VisibilityMask))
this.SetterModifiers = setterModifier;
}
}
}
static ModifierEnum GetAccessorModifier(MethodInfo accessor)
{
if (accessor.IsPublic) {
return ModifierEnum.Public;
} else if (accessor.IsFamily || accessor.IsFamilyOrAssembly) {
return ModifierEnum.Protected;
} else {
return ModifierEnum.Private; // or internal, we don't care about that difference
}
} }
} }
} }

2
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/XmlDoc.cs

@ -254,7 +254,7 @@ namespace ICSharpCode.SharpDevelop.Dom
static XmlDoc Load(string fileName, string cachePath, bool allowRedirect) static XmlDoc Load(string fileName, string cachePath, bool allowRedirect)
{ {
//LoggingService.Debug("Loading XmlDoc for " + fileName); LoggingService.Debug("Loading XmlDoc for " + fileName);
XmlDoc doc; XmlDoc doc;
string cacheName = null; string cacheName = null;
if (cachePath != null) { if (cachePath != null) {

Loading…
Cancel
Save