diff --git a/data/options/TextLib/Licenses.xml b/data/options/TextLib/Licenses.xml index 91b985b1bc..b2f869517f 100644 --- a/data/options/TextLib/Licenses.xml +++ b/data/options/TextLib/Licenses.xml @@ -1,4 +1,206 @@ + (program, "C.D", 7); Assert.AreEqual("A.B.C.D", trr.ResolvedClass.FullyQualifiedName, "trr.ResolvedClass.FullyQualifiedName"); } + + [Test] + public void ResolveTypeSD2_863() + { + string program = @"using System; +namespace A { class C {} } +namespace A.B { + class C {} + class TestClass { + void Test() { + + } + } +} +"; + TypeResolveResult trr = Resolve(program, "C", 7); + Assert.AreEqual("A.B.C", trr.ResolvedClass.FullyQualifiedName, "trr.ResolvedClass.FullyQualifiedName"); + } #endregion #region Import class tests diff --git a/src/Main/Base/Test/ReflectionLayerTests.cs b/src/Main/Base/Test/ReflectionLayerTests.cs index e7ffe9f22d..da6b0220bc 100644 --- a/src/Main/Base/Test/ReflectionLayerTests.cs +++ b/src/Main/Base/Test/ReflectionLayerTests.cs @@ -122,7 +122,7 @@ namespace ICSharpCode.SharpDevelop.Tests [Test] public void ReflectionParserTest() { - ICompilationUnit cu = new ReflectionProjectContent("TestName", "testlocation", new AssemblyName[0], ParserService.DefaultProjectContentRegistry).AssemblyCompilationUnit; + ICompilationUnit cu = new ReflectionProjectContent("TestName", "testlocation", new DomAssemblyName[0], ParserService.DefaultProjectContentRegistry).AssemblyCompilationUnit; IClass c = new ReflectionClass(cu, typeof(TestClass<,>), typeof(TestClass<,>).FullName, null); cu.ProjectContent.AddClassToNamespaceList(c); diff --git a/src/Main/Core/Project/Src/Util/ClipboardWrapper.cs b/src/Main/Core/Project/Src/Util/ClipboardWrapper.cs index f7c5d1422b..3d7d2acbc9 100644 --- a/src/Main/Core/Project/Src/Util/ClipboardWrapper.cs +++ b/src/Main/Core/Project/Src/Util/ClipboardWrapper.cs @@ -60,13 +60,32 @@ namespace ICSharpCode.Core public static void SetDataObject(object data) { + SafeSetClipboard(data); + } + + // Code duplication: TextAreaClipboardHandler.cs also has SafeSetClipboard + [ThreadStatic] static int SafeSetClipboardDataVersion; + + static void SafeSetClipboard(object dataObject) + { + // Work around ExternalException bug. (SD2-426) + // Best reproducable inside Virtual PC. + int version = unchecked(++SafeSetClipboardDataVersion); try { - Clipboard.SetDataObject(data, true, 10, 50); + Clipboard.SetDataObject(dataObject, true); } catch (ExternalException) { - Application.DoEvents(); - try { - Clipboard.SetDataObject(data, true, 10, 50); - } catch (ExternalException) { } + Timer timer = new Timer(); + timer.Interval = 100; + timer.Tick += delegate { + timer.Stop(); + timer.Dispose(); + if (SafeSetClipboardDataVersion == version) { + try { + Clipboard.SetDataObject(dataObject, true, 10, 50); + } catch (ExternalException) { } + } + }; + timer.Start(); } } } diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj index cc5a98572b..f2c908d4ba 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/ICSharpCode.SharpDevelop.Dom.csproj @@ -93,6 +93,7 @@ + @@ -174,4 +175,4 @@ - \ No newline at end of file + diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CecilReader.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CecilReader.cs index a299d4e047..1a4b477240 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CecilReader.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CecilReader.cs @@ -24,11 +24,13 @@ namespace ICSharpCode.SharpDevelop.Dom throw new ArgumentNullException("registry"); LoggingService.Info("Cecil: Load from " + fileName); AssemblyDefinition asm = AssemblyFactory.GetAssembly(fileName); - List referencedAssemblies = new List(); - foreach (AssemblyNameReference anr in asm.MainModule.AssemblyReferences) { - referencedAssemblies.Add(new AssemblyName(anr.FullName)); + List referencedAssemblies = new List(); + foreach (ModuleDefinition module in asm.Modules) { + foreach (AssemblyNameReference anr in module.AssemblyReferences) { + referencedAssemblies.Add(new DomAssemblyName(anr.FullName)); + } } - return new CecilProjectContent(asm.Name.FullName, fileName, referencedAssemblies.ToArray(), asm.MainModule.Types, registry); + return new CecilProjectContent(asm.Name.FullName, fileName, referencedAssemblies.ToArray(), asm, registry); } static void AddAttributes(IProjectContent pc, IList list, CustomAttributeCollection attributes) @@ -121,9 +123,17 @@ namespace ICSharpCode.SharpDevelop.Dom private sealed class CecilProjectContent : ReflectionProjectContent { - public CecilProjectContent(string fullName, string fileName, AssemblyName[] referencedAssemblies, - TypeDefinitionCollection types, ProjectContentRegistry registry) + public CecilProjectContent(string fullName, string fileName, DomAssemblyName[] referencedAssemblies, + AssemblyDefinition assembly, ProjectContentRegistry registry) : base(fullName, fileName, referencedAssemblies, registry) + { + foreach (ModuleDefinition module in assembly.Modules) { + AddTypes(module.Types); + } + InitializeSpecialClasses(); + } + + void AddTypes(TypeDefinitionCollection types) { foreach (TypeDefinition td in types) { if ((td.Attributes & TypeAttributes.Public) == TypeAttributes.Public) { @@ -141,7 +151,6 @@ namespace ICSharpCode.SharpDevelop.Dom AddClassToNamespaceListInternal(new CecilClass(this.AssemblyCompilationUnit, null, td, name)); } } - InitializeSpecialClasses(); } } diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DefaultProjectContent.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DefaultProjectContent.cs index 1126b346c8..0526da5892 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DefaultProjectContent.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DefaultProjectContent.cs @@ -783,23 +783,24 @@ namespace ICSharpCode.SharpDevelop.Dom SearchTypeResult fallbackResult = SearchTypeResult.Empty; if (request.CurrentType != null) { // Try parent namespaces of the current class - string fullname = request.CurrentType.FullyQualifiedName; - string[] namespaces = fullname.Split('.'); - StringBuilder curnamespace = new StringBuilder(); - for (int i = 0; i < namespaces.Length; ++i) { - curnamespace.Append(namespaces[i]); - curnamespace.Append('.'); + string fullname = request.CurrentType.Namespace; + while (fullname != null && fullname.Length > 0) { + string nameSpace = fullname + '.' + name; - curnamespace.Append(name); - c = GetClass(curnamespace.ToString(), request.TypeParameterCount); + c = GetClass(nameSpace, request.TypeParameterCount); if (c != null) { if (c.TypeParameters.Count == request.TypeParameterCount) return new SearchTypeResult(c.DefaultReturnType); else fallbackResult = new SearchTypeResult(c.DefaultReturnType); } - // remove class name again to try next namespace - curnamespace.Length -= name.Length; + + int pos = fullname.LastIndexOf('.'); + if (pos < 0) { + fullname = null; + } else { + fullname = fullname.Substring(0, pos); + } } if (name.IndexOf('.') < 0) { diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DomAssemblyName.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DomAssemblyName.cs new file mode 100644 index 0000000000..d1ddb78dea --- /dev/null +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/DomAssemblyName.cs @@ -0,0 +1,39 @@ +// +// +// +// +// $Revision$ +// + +using System; + +namespace ICSharpCode.SharpDevelop.Dom +{ + /// + /// Similar to System.Reflection.AssemblyName, but does not raise an exception + /// on invalid assembly names. (See SD2-1307) + /// + public sealed class DomAssemblyName + { + readonly string fullAssemblyName; + + public DomAssemblyName(string fullAssemblyName) + { + this.fullAssemblyName = fullAssemblyName; + } + + public string FullName { + get { return fullAssemblyName; } + } + + internal static DomAssemblyName[] Convert(System.Reflection.AssemblyName[] names) + { + if (names == null) return null; + DomAssemblyName[] n = new DomAssemblyName[names.Length]; + for (int i = 0; i < names.Length; i++) { + n[i] = new DomAssemblyName(names[i].FullName); + } + return n; + } + } +} diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/ProjectContentRegistry.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/ProjectContentRegistry.cs index e296c82dcd..049ebbf43d 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/ProjectContentRegistry.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/ProjectContentRegistry.cs @@ -216,11 +216,17 @@ namespace ICSharpCode.SharpDevelop.Dom pc.Dispose(); } + [Obsolete("Use DomAssemblyName instead of AssemblyName")] public IProjectContent GetExistingProjectContent(AssemblyName assembly) { return GetExistingProjectContent(assembly.FullName, assembly.FullName); } + public IProjectContent GetExistingProjectContent(DomAssemblyName assembly) + { + return GetExistingProjectContent(assembly.FullName, assembly.FullName); + } + public virtual IProjectContent GetExistingProjectContent(string itemInclude, string itemFileName) { if (itemFileName == itemInclude) { diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/ReflectionProjectContent.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/ReflectionProjectContent.cs index 87d9b39fb9..661691f47d 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/ReflectionProjectContent.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ProjectContent/ReflectionProjectContent.cs @@ -18,7 +18,7 @@ namespace ICSharpCode.SharpDevelop.Dom public class ReflectionProjectContent : DefaultProjectContent { string assemblyFullName; - AssemblyName[] referencedAssemblies; + DomAssemblyName[] referencedAssemblyNames; ICompilationUnit assemblyCompilationUnit; string assemblyLocation; ProjectContentRegistry registry; @@ -35,16 +35,20 @@ namespace ICSharpCode.SharpDevelop.Dom } } + [Obsolete("This property always returns an empty array! Use ReferencedAssemblyNames instead!")] public AssemblyName[] ReferencedAssemblies { - get { - return referencedAssemblies; - } + get { return new AssemblyName[0]; } + } + + /// + /// Gets the list of assembly names referenced by this project content. + /// + public IList ReferencedAssemblyNames { + get { return Array.AsReadOnly(referencedAssemblyNames); } } public ICompilationUnit AssemblyCompilationUnit { - get { - return assemblyCompilationUnit; - } + get { return assemblyCompilationUnit; } } DateTime assemblyFileLastWriteTime; @@ -73,7 +77,7 @@ namespace ICSharpCode.SharpDevelop.Dom } public ReflectionProjectContent(Assembly assembly, string assemblyLocation, ProjectContentRegistry registry) - : this(assembly.FullName, assemblyLocation, assembly.GetReferencedAssemblies(), registry) + : this(assembly.FullName, assemblyLocation, DomAssemblyName.Convert(assembly.GetReferencedAssemblies()), registry) { foreach (Type type in assembly.GetExportedTypes()) { string name = type.FullName; @@ -84,7 +88,13 @@ namespace ICSharpCode.SharpDevelop.Dom InitializeSpecialClasses(); } + [Obsolete("Use DomAssemblyName instead of AssemblyName!")] public ReflectionProjectContent(string assemblyFullName, string assemblyLocation, AssemblyName[] referencedAssemblies, ProjectContentRegistry registry) + : this(assemblyFullName, assemblyLocation, DomAssemblyName.Convert(referencedAssemblies), registry) + { + } + + public ReflectionProjectContent(string assemblyFullName, string assemblyLocation, DomAssemblyName[] referencedAssemblies, ProjectContentRegistry registry) { if (assemblyFullName == null) throw new ArgumentNullException("assemblyFullName"); @@ -95,7 +105,7 @@ namespace ICSharpCode.SharpDevelop.Dom this.registry = registry; this.assemblyFullName = assemblyFullName; - this.referencedAssemblies = referencedAssemblies; + this.referencedAssemblyNames = referencedAssemblies; this.assemblyLocation = assemblyLocation; this.assemblyCompilationUnit = new DefaultCompilationUnit(this); @@ -146,7 +156,7 @@ namespace ICSharpCode.SharpDevelop.Dom } bool initialized = false; - List missingNames; + List missingNames; public void InitializeReferences() { @@ -169,7 +179,7 @@ namespace ICSharpCode.SharpDevelop.Dom } } else { initialized = true; - foreach (AssemblyName name in referencedAssemblies) { + foreach (DomAssemblyName name in referencedAssemblyNames) { IProjectContent content = registry.GetExistingProjectContent(name); if (content != null) { changed = true; @@ -178,7 +188,7 @@ namespace ICSharpCode.SharpDevelop.Dom } } else { if (missingNames == null) - missingNames = new List(); + missingNames = new List(); missingNames.Add(name); } } diff --git a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/DomPersistence.cs b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/DomPersistence.cs index 87e3d0b471..f5c1aa44c6 100644 --- a/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/DomPersistence.cs +++ b/src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/ReflectionLayer/DomPersistence.cs @@ -249,8 +249,8 @@ namespace ICSharpCode.SharpDevelop.Dom time = File.GetLastWriteTimeUtc(pc.AssemblyLocation).ToFileTime(); } catch {} writer.Write(time); - writer.Write(pc.ReferencedAssemblies.Length); - foreach (AssemblyName name in pc.ReferencedAssemblies) { + writer.Write(pc.ReferencedAssemblyNames.Count); + foreach (DomAssemblyName name in pc.ReferencedAssemblyNames) { writer.Write(name.FullName); } WriteClasses(); @@ -281,9 +281,9 @@ namespace ICSharpCode.SharpDevelop.Dom LoggingService.Warn("Read dom: assembly changed since cache was created"); return null; } - AssemblyName[] referencedAssemblies = new AssemblyName[reader.ReadInt32()]; + DomAssemblyName[] referencedAssemblies = new DomAssemblyName[reader.ReadInt32()]; for (int i = 0; i < referencedAssemblies.Length; i++) { - referencedAssemblies[i] = new AssemblyName(reader.ReadString()); + referencedAssemblies[i] = new DomAssemblyName(reader.ReadString()); } this.pc = new ReflectionProjectContent(assemblyName, assemblyLocation, referencedAssemblies, registry); if (ReadClasses()) {