Browse Source

Merge remote-tracking branch 'remotes/origin/master' into classbrowser

Conflicts:
	src/Main/SharpDevelop/Parser/AssemblyParserService.cs
pull/80/head
Andreas Weizel 12 years ago
parent
commit
1316bdcebd
  1. 3
      src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin
  2. 5
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs
  3. 1
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CSharpContextActionWrapper.cs
  4. 4
      src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs
  5. 4
      src/AddIns/Debugger/Debugger.AddIn/NRefactory/ExpressionEvaluationVisitor.cs
  6. 6
      src/AddIns/Debugger/Debugger.Core/Process.cs
  7. 70
      src/AddIns/DisplayBindings/ILSpyAddIn/DecompiledViewContent.cs
  8. 7
      src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.addin
  9. 3
      src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj
  10. 110
      src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyDecompilerService.cs
  11. 34
      src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyDisplayBinding.cs
  12. 5
      src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyFullParseInformation.cs
  13. 24
      src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyParser.cs
  14. 57
      src/AddIns/DisplayBindings/ILSpyAddIn/ILSpySymbolSource.cs
  15. 8
      src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyUnresolvedFile.cs
  16. 2
      src/AddIns/DisplayBindings/ILSpyAddIn/NavigateToDecompiledEntityService.cs
  17. 9
      src/Libraries/NRefactory/ICSharpCode.NRefactory.Xml/DocumentationElement.cs
  18. 30
      src/Main/Base/Project/Dom/IEntityModelContext.cs
  19. 2
      src/Main/Base/Project/Editor/ContextActions/ContextActionViewModel.cs
  20. 10
      src/Main/Base/Project/Parser/IAssemblyParserService.cs
  21. 6
      src/Main/Base/Project/Parser/IParser.cs
  22. 2
      src/Main/Base/Project/Refactoring/ContextAction.cs
  23. 31
      src/Main/SharpDevelop/Parser/AssemblyParserService.cs
  24. 2
      src/Main/SharpDevelop/Parser/ParserService.cs
  25. 6
      src/Main/SharpDevelop/Parser/ParserServiceEntry.cs
  26. 18
      src/Main/SharpDevelop/Workbench/DisplayBinding/DisplayBindingService.cs

3
src/AddIns/BackendBindings/CSharpBinding/Project/CSharpBinding.addin

@ -16,7 +16,8 @@
<Doozer name="CSharpCodeActionProvider" class="CSharpBinding.Refactoring.CSharpCodeActionProviderDoozer"/> <Doozer name="CSharpCodeActionProvider" class="CSharpBinding.Refactoring.CSharpCodeActionProviderDoozer"/>
</Import> </Import>
<Import assembly = ":ICSharpCode.SharpDevelop"/> <Import assembly = ":ICSharpCode.SharpDevelop"/>
<Import assembly = ":ICSharpCode.NRefactory.CSharp.Refactoring"/> <Import assembly = ":ICSharpCode.NRefactory.CSharp"/> <!-- used for CSharpAmbience -->
<Import assembly = ":ICSharpCode.NRefactory.CSharp.Refactoring"/> <!-- used for issues and refactorings -->
</Runtime> </Runtime>
<Path name = "/SharpDevelop/Workbench/Ambiences"> <Path name = "/SharpDevelop/Workbench/Ambiences">

5
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs

@ -68,6 +68,11 @@ namespace CSharpBinding.Parser
} }
*/ */
public ITextSource GetFileContent(FileName fileName)
{
return SD.FileService.GetFileContent(fileName);
}
public ParseInformation Parse(FileName fileName, ITextSource fileContent, bool fullParseInformationRequested, public ParseInformation Parse(FileName fileName, ITextSource fileContent, bool fullParseInformationRequested,
IProject parentProject, CancellationToken cancellationToken) IProject parentProject, CancellationToken cancellationToken)
{ {

1
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CSharpContextActionWrapper.cs

@ -54,7 +54,6 @@ namespace CSharpBinding.Refactoring
public void Execute(EditorRefactoringContext context) public void Execute(EditorRefactoringContext context)
{ {
SD.AnalyticsMonitor.TrackFeature(provider.ID);
var resolver = context.GetAstResolverAsync().Result; var resolver = context.GetAstResolverAsync().Result;
var refactoringContext = new SDRefactoringContext(context.Editor, resolver, context.CaretLocation); var refactoringContext = new SDRefactoringContext(context.Editor, resolver, context.CaretLocation);
var action = getUpdatedCodeAction(refactoringContext); var action = getUpdatedCodeAction(refactoringContext);

4
src/AddIns/BackendBindings/XamlBinding/XamlBinding/XamlParser.cs

@ -39,9 +39,9 @@ namespace ICSharpCode.XamlBinding
return Path.GetExtension(fileName).Equals(".xaml", StringComparison.OrdinalIgnoreCase); return Path.GetExtension(fileName).Equals(".xaml", StringComparison.OrdinalIgnoreCase);
} }
public bool CanParse(IProject project) public ITextSource GetFileContent(FileName fileName)
{ {
return false; return SD.FileService.GetFileContent(fileName);
} }
volatile IncrementalParserState parserState; volatile IncrementalParserState parserState;

4
src/AddIns/Debugger/Debugger.AddIn/NRefactory/ExpressionEvaluationVisitor.cs

@ -124,7 +124,7 @@ namespace Debugger.AddIn
} }
if (!allowMethodInvoke && (importedMember is IMethod)) if (!allowMethodInvoke && (importedMember is IMethod))
throw new InvalidOperationException("Method invocation not allowed in the current context!"); throw new InvalidOperationException("Method invocation not allowed in the current context!");
Value val = Value.GetMemberValue(evalThread, target, importedMember); Value val = Value.GetMemberValue(evalThread, target, importedMember.Specialize(context.MethodInfo.Substitution));
if (val == null) if (val == null)
throw new GetValueException("Member not found!"); throw new GetValueException("Member not found!");
return val; return val;
@ -272,7 +272,7 @@ namespace Debugger.AddIn
return Convert(val); return Convert(val);
} }
/// <remark /// <remarks>
/// See $7.10.10 of C# 4 Spec for details. /// See $7.10.10 of C# 4 Spec for details.
/// </remarks> /// </remarks>
Value Visit(TypeIsResolveResult result) Value Visit(TypeIsResolveResult result)

6
src/AddIns/Debugger/Debugger.Core/Process.cs

@ -613,12 +613,14 @@ namespace Debugger
internal void OnAppDomainCreated(AppDomain appDomain) internal void OnAppDomainCreated(AppDomain appDomain)
{ {
if (AppDomainCreated != null)
AppDomainCreated(this, new AppDomainEventArgs(appDomain));
} }
internal void OnAppDomainDestroyed(AppDomain appDomain) internal void OnAppDomainDestroyed(AppDomain appDomain)
{ {
if (AppDomainDestroyed != null)
AppDomainDestroyed(this, new AppDomainEventArgs(appDomain));
} }
} }
} }

70
src/AddIns/DisplayBindings/ILSpyAddIn/ViewContent/DecompiledViewContent.cs → src/AddIns/DisplayBindings/ILSpyAddIn/DecompiledViewContent.cs

@ -48,11 +48,7 @@ namespace ICSharpCode.ILSpyAddIn
this.jumpToEntityIdStringWhenDecompilationFinished = entityTag; this.jumpToEntityIdStringWhenDecompilationFinished = entityTag;
this.TitleName = "[" + ReflectionHelper.SplitTypeParameterCountFromReflectionName(typeName.Type.Name) + "]"; this.TitleName = "[" + ReflectionHelper.SplitTypeParameterCountFromReflectionName(typeName.Type.Name) + "]";
DecompilationThread(); InitializeView();
// Thread thread = new Thread(DecompilationThread);
// thread.Name = "Decompiler (" + shortTypeName + ")";
// thread.Start();
// thread.Join();
SD.BookmarkManager.BookmarkRemoved += BookmarkManager_Removed; SD.BookmarkManager.BookmarkRemoved += BookmarkManager_Removed;
SD.BookmarkManager.BookmarkAdded += BookmarkManager_Added; SD.BookmarkManager.BookmarkAdded += BookmarkManager_Added;
@ -63,56 +59,6 @@ namespace ICSharpCode.ILSpyAddIn
} }
#endregion #endregion
public static DecompiledViewContent Get(DecompiledTypeReference name)
{
var viewContents = SD.Workbench.ViewContentCollection.OfType<DecompiledViewContent>();
return viewContents.FirstOrDefault(c => c.DecompiledTypeName == name);
}
public static DecompiledViewContent Get(IEntity entity)
{
if (entity == null)
throw new ArgumentNullException("entity");
// Get the underlying entity for generic instance members
if (entity is IMember)
entity = ((IMember)entity).MemberDefinition;
ITypeDefinition declaringType = (entity as ITypeDefinition) ?? entity.DeclaringTypeDefinition;
if (declaringType == null)
return null;
// get the top-level type
while (declaringType.DeclaringTypeDefinition != null)
declaringType = declaringType.DeclaringTypeDefinition;
FileName assemblyLocation = declaringType.ParentAssembly.GetRuntimeAssemblyLocation();
if (assemblyLocation != null && File.Exists(assemblyLocation)) {
return Get(assemblyLocation, declaringType.ReflectionName);
}
return null;
}
public static DecompiledViewContent Get(FileName assemblyFile, string typeName)
{
if (assemblyFile == null)
throw new ArgumentNullException("assemblyFile");
if (string.IsNullOrEmpty(typeName))
throw new ArgumentException("typeName is null or empty");
var type = new FullTypeName(typeName);
foreach (var viewContent in SD.Workbench.ViewContentCollection.OfType<DecompiledViewContent>()) {
var viewContentName = viewContent.DecompiledTypeName;
if (viewContentName.AssemblyFile == assemblyFile && type == viewContentName.Type) {
return viewContent;
}
}
var newViewContent = new DecompiledViewContent(new DecompiledTypeReference(assemblyFile, new FullTypeName(typeName)), null);
SD.Workbench.ShowView(newViewContent);
return newViewContent;
}
#region Properties #region Properties
public DecompiledTypeReference DecompiledTypeName { get; private set; } public DecompiledTypeReference DecompiledTypeName { get; private set; }
@ -173,13 +119,15 @@ namespace ICSharpCode.ILSpyAddIn
#endregion #endregion
#region Decompilation #region Decompilation
void DecompilationThread() async void InitializeView()
{ {
try { try {
var file = ILSpyDecompilerService.DecompileType(DecompiledTypeName); var parseInformation = await SD.ParserService.ParseAsync(DecompiledTypeName.ToFileName(), cancellationToken: cancellation.Token);
if (parseInformation == null || !(parseInformation.UnresolvedFile is ILSpyUnresolvedFile)) return;
var file = (ILSpyUnresolvedFile)parseInformation.UnresolvedFile;
memberLocations = file.MemberLocations; memberLocations = file.MemberLocations;
DebugSymbols = file.DebugSymbols; DebugSymbols = file.DebugSymbols;
OnDecompilationFinished(file.Writer); OnDecompilationFinished(file.Output);
} catch (OperationCanceledException) { } catch (OperationCanceledException) {
// ignore cancellation // ignore cancellation
} catch (Exception ex) { } catch (Exception ex) {
@ -193,15 +141,15 @@ namespace ICSharpCode.ILSpyAddIn
writer.WriteLine(string.Format("Exception while decompiling {0} ({1})", DecompiledTypeName.Type, DecompiledTypeName.AssemblyFile)); writer.WriteLine(string.Format("Exception while decompiling {0} ({1})", DecompiledTypeName.Type, DecompiledTypeName.AssemblyFile));
writer.WriteLine(); writer.WriteLine();
writer.WriteLine(ex.ToString()); writer.WriteLine(ex.ToString());
SD.MainThread.InvokeAsyncAndForget(() => OnDecompilationFinished(writer)); OnDecompilationFinished(writer.ToString());
} }
} }
void OnDecompilationFinished(StringWriter output) void OnDecompilationFinished(string output)
{ {
if (cancellation.IsCancellationRequested) if (cancellation.IsCancellationRequested)
return; return;
codeEditor.Document.Text = output.ToString(); codeEditor.Document.Text = output;
codeEditor.Document.UndoStack.ClearAll(); codeEditor.Document.UndoStack.ClearAll();
this.decompilationFinished = true; this.decompilationFinished = true;

7
src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.addin

@ -32,4 +32,11 @@
<MenuItem id="ILSpySeparator" type="Separator" /> <MenuItem id="ILSpySeparator" type="Separator" />
<MenuItem id="ILSpy" icon="ILSpy" type="Item" label="${res:ILSpyAddIn.OpenILSpyCommand}" class="ICSharpCode.ILSpyAddIn.OpenInILSpyCommand"/> <MenuItem id="ILSpy" icon="ILSpy" type="Item" label="${res:ILSpyAddIn.OpenILSpyCommand}" class="ICSharpCode.ILSpyAddIn.OpenInILSpyCommand"/>
</Path> </Path>
<Path name = "/SharpDevelop/Workbench/DisplayBindings/UrlBased">
<DisplayBinding id = "ILSpyView"
class = "ICSharpCode.ILSpyAddIn.ILSpyDisplayBinding"
fileNamePattern = "^ilspy://"
title = "ILSpy Decompiler View"/>
</Path>
</AddIn> </AddIn>

3
src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyAddIn.csproj

@ -66,7 +66,9 @@
<Link>Properties\GlobalAssemblyInfo.cs</Link> <Link>Properties\GlobalAssemblyInfo.cs</Link>
</Compile> </Compile>
<Compile Include="DebuggerTextOutput.cs" /> <Compile Include="DebuggerTextOutput.cs" />
<Compile Include="DecompiledViewContent.cs" />
<Compile Include="ILSpyDecompilerService.cs" /> <Compile Include="ILSpyDecompilerService.cs" />
<Compile Include="ILSpyDisplayBinding.cs" />
<Compile Include="ILSpyFullParseInformation.cs" /> <Compile Include="ILSpyFullParseInformation.cs" />
<Compile Include="ILSpyParser.cs" /> <Compile Include="ILSpyParser.cs" />
<Compile Include="ILSpySymbolSource.cs" /> <Compile Include="ILSpySymbolSource.cs" />
@ -81,7 +83,6 @@
<DependentUpon>SetILSpyPathDialog.cs</DependentUpon> <DependentUpon>SetILSpyPathDialog.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="LaunchILSpy\OpenInILSpyCommand.cs" /> <Compile Include="LaunchILSpy\OpenInILSpyCommand.cs" />
<Compile Include="ViewContent\DecompiledViewContent.cs" />
<EmbeddedResource Include="LaunchILSpy\SetILSpyPathDialog.resx"> <EmbeddedResource Include="LaunchILSpy\SetILSpyPathDialog.resx">
<DependentUpon>SetILSpyPathDialog.cs</DependentUpon> <DependentUpon>SetILSpyPathDialog.cs</DependentUpon>
</EmbeddedResource> </EmbeddedResource>

110
src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyDecompilerService.cs

@ -13,6 +13,7 @@ using ICSharpCode.Core;
using ICSharpCode.Decompiler; using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Ast; using ICSharpCode.Decompiler.Ast;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Parser; using ICSharpCode.SharpDevelop.Parser;
using Mono.Cecil; using Mono.Cecil;
@ -23,45 +24,46 @@ namespace ICSharpCode.ILSpyAddIn
/// </summary> /// </summary>
public static class ILSpyDecompilerService public static class ILSpyDecompilerService
{ {
class AssemblyCacheInfo class ModuleCacheInfo
{ {
public readonly DateTime LastUpdateTime; public readonly DateTime LastUpdateTime;
public readonly WeakReference<AssemblyDefinition> Assembly; public readonly WeakReference<ModuleDefinition> Module;
public AssemblyCacheInfo(DateTime lastUpdateTime, AssemblyDefinition assembly) public ModuleCacheInfo(DateTime lastUpdateTime, ModuleDefinition assembly)
{ {
if (assembly == null) if (assembly == null)
throw new ArgumentNullException("assembly"); throw new ArgumentNullException("assembly");
this.LastUpdateTime = lastUpdateTime; this.LastUpdateTime = lastUpdateTime;
this.Assembly = new WeakReference<AssemblyDefinition>(assembly); this.Module = new WeakReference<ModuleDefinition>(assembly);
} }
} }
static readonly Dictionary<FileName, AssemblyCacheInfo> assemblyCache = new Dictionary<FileName, AssemblyCacheInfo>(); static readonly Dictionary<FileName, ModuleCacheInfo> moduleCache = new Dictionary<FileName, ModuleCacheInfo>();
static AssemblyDefinition GetAssemblyDefinitionFromCache(FileName file, ReaderParameters parameters = null) static ModuleDefinition GetModuleDefinitionFromCache(FileName file)
{ {
if (file == null) return null; if (file == null) return null;
if (parameters == null) parameters = new ReaderParameters(); ReaderParameters parameters = new ReaderParameters();
var resolver = new ILSpyAssemblyResolver(file);
var lastUpdateTime = File.GetLastWriteTimeUtc(file); var lastUpdateTime = File.GetLastWriteTimeUtc(file);
lock (assemblyCache) { lock (moduleCache) {
AssemblyCacheInfo info; ModuleCacheInfo info;
AssemblyDefinition asm; ModuleDefinition module;
if (!assemblyCache.TryGetValue(file, out info)) { if (!moduleCache.TryGetValue(file, out info)) {
asm = AssemblyDefinition.ReadAssembly(file, parameters); module = ModuleDefinition.ReadModule(file, parameters);
assemblyCache.Add(file, new AssemblyCacheInfo(lastUpdateTime, asm)); moduleCache.Add(file, new ModuleCacheInfo(lastUpdateTime, module));
return asm; return module;
} else if (info.LastUpdateTime < lastUpdateTime) { } else if (info.LastUpdateTime < lastUpdateTime) {
assemblyCache.Remove(file); moduleCache.Remove(file);
asm = AssemblyDefinition.ReadAssembly(file, parameters); module = ModuleDefinition.ReadModule(file, parameters);
assemblyCache.Add(file, new AssemblyCacheInfo(lastUpdateTime, asm)); moduleCache.Add(file, new ModuleCacheInfo(lastUpdateTime, module));
return asm; return module;
} else { } else {
if (info.Assembly.TryGetTarget(out asm)) if (info.Module.TryGetTarget(out module))
return asm; return module;
asm = AssemblyDefinition.ReadAssembly(file, parameters); module = ModuleDefinition.ReadModule(file, parameters);
info.Assembly.SetTarget(asm); info.Module.SetTarget(module);
return asm; return module;
} }
} }
} }
@ -77,14 +79,19 @@ namespace ICSharpCode.ILSpyAddIn
{ {
} }
/// <summary>
/// Used to remember the referenced assemblies for the WeakReference cache policy.
/// </summary>
readonly ISet<AssemblyDefinition> resolvedAssemblies = new HashSet<AssemblyDefinition>(); readonly ISet<AssemblyDefinition> resolvedAssemblies = new HashSet<AssemblyDefinition>();
AssemblyDefinition Resolve(DomAssemblyName name, ReaderParameters parameters) AssemblyDefinition Resolve(DomAssemblyName name, ReaderParameters parameters)
{ {
var assemblyDefinition = GetAssemblyDefinitionFromCache(FindAssembly(name), parameters); var moduleDefinition = GetModuleDefinitionFromCache(FindAssembly(name));
if (assemblyDefinition != null) if (moduleDefinition != null) {
resolvedAssemblies.Add(assemblyDefinition); resolvedAssemblies.Add(moduleDefinition.Assembly);
return assemblyDefinition; return moduleDefinition.Assembly;
}
return null;
} }
public AssemblyDefinition Resolve(AssemblyNameReference name) public AssemblyDefinition Resolve(AssemblyNameReference name)
@ -108,31 +115,24 @@ namespace ICSharpCode.ILSpyAddIn
} }
} }
public static ILSpyUnresolvedFile DecompileType(DecompiledTypeReference name) public static ILSpyFullParseInformation DecompileType(DecompiledTypeReference name, CancellationToken cancellationToken = default(CancellationToken))
{ {
if (name == null) if (name == null)
throw new ArgumentNullException("entity"); throw new ArgumentNullException("name");
return DoDecompile(name); var astBuilder = CreateAstBuilder(name, cancellationToken);
return new ILSpyFullParseInformation(ILSpyUnresolvedFile.Create(name, astBuilder), null, astBuilder.SyntaxTree);
} }
public static async Task<ILSpyUnresolvedFile> DecompileTypeAsync(DecompiledTypeReference name, CancellationToken cancellationToken) static AstBuilder CreateAstBuilder(DecompiledTypeReference name, CancellationToken cancellationToken = default(CancellationToken))
{
return await Task.Run(
delegate() { return DoDecompile(name, cancellationToken); },
cancellationToken);
}
static AstBuilder CreateAstBuilder(DecompiledTypeReference name, out AssemblyDefinition[] neededAssemblies, CancellationToken cancellationToken = default(CancellationToken))
{ {
ReaderParameters readerParameters = new ReaderParameters(); ReaderParameters readerParameters = new ReaderParameters();
// Use new assembly resolver instance so that the AssemblyDefinitions // Use new assembly resolver instance so that the AssemblyDefinitions
// can be garbage-collected once the code is decompiled. // can be garbage-collected once the code is decompiled.
var resolver = new ILSpyAssemblyResolver(name.AssemblyFile); var resolver = new ILSpyAssemblyResolver(name.AssemblyFile);
readerParameters.AssemblyResolver = resolver; readerParameters.AssemblyResolver = resolver;
AssemblyDefinition asm = GetAssemblyDefinitionFromCache(name.AssemblyFile, readerParameters); ModuleDefinition module = GetModuleDefinitionFromCache(name.AssemblyFile);
if (asm == null) if (module == null)
throw new InvalidOperationException("Could not find assembly file"); throw new InvalidOperationException("Could not find assembly file");
ModuleDefinition module = asm.MainModule;
TypeDefinition typeDefinition = module.GetType(name.Type.ReflectionName); TypeDefinition typeDefinition = module.GetType(name.Type.ReflectionName);
if (typeDefinition == null) if (typeDefinition == null)
throw new InvalidOperationException("Could not find type"); throw new InvalidOperationException("Could not find type");
@ -140,30 +140,21 @@ namespace ICSharpCode.ILSpyAddIn
context.CancellationToken = cancellationToken; context.CancellationToken = cancellationToken;
AstBuilder astBuilder = new AstBuilder(context); AstBuilder astBuilder = new AstBuilder(context);
astBuilder.AddType(typeDefinition); astBuilder.AddType(typeDefinition);
neededAssemblies = resolver.ResolvedAssemblies.ToArray();
return astBuilder; return astBuilder;
} }
static ILSpyUnresolvedFile DoDecompile(DecompiledTypeReference name, CancellationToken cancellationToken = default(CancellationToken)) static ILSpyUnresolvedFile DoDecompile(DecompiledTypeReference name, CancellationToken cancellationToken = default(CancellationToken))
{ {
AssemblyDefinition[] assemblies; return ILSpyUnresolvedFile.Create(name, CreateAstBuilder(name, cancellationToken));
return ILSpyUnresolvedFile.Create(name, CreateAstBuilder(name, out assemblies, cancellationToken));
}
public static ILSpyFullParseInformation ParseDecompiledType(DecompiledTypeReference name, CancellationToken cancellationToken = default(CancellationToken))
{
AssemblyDefinition[] assemblies;
var astBuilder = CreateAstBuilder(name, out assemblies, cancellationToken);
return new ILSpyFullParseInformation(ILSpyUnresolvedFile.Create(name, astBuilder), null, astBuilder.SyntaxTree, assemblies);
} }
} }
public class DecompiledTypeReference : IEquatable<DecompiledTypeReference> public class DecompiledTypeReference : IEquatable<DecompiledTypeReference>
{ {
public FileName AssemblyFile { get; private set; } public FileName AssemblyFile { get; private set; }
public FullTypeName Type { get; private set; } public TopLevelTypeName Type { get; private set; }
public DecompiledTypeReference(FileName assemblyFile, FullTypeName type) public DecompiledTypeReference(FileName assemblyFile, TopLevelTypeName type)
{ {
this.AssemblyFile = assemblyFile; this.AssemblyFile = assemblyFile;
this.Type = type; this.Type = type;
@ -185,7 +176,16 @@ namespace ICSharpCode.ILSpyAddIn
asm = match.Groups[1].Value; asm = match.Groups[1].Value;
typeName = UnescapeTypeName(match.Groups[2].Value); typeName = UnescapeTypeName(match.Groups[2].Value);
return new DecompiledTypeReference(new FileName(asm), new FullTypeName(typeName)); return new DecompiledTypeReference(new FileName(asm), new TopLevelTypeName(typeName));
}
public static DecompiledTypeReference FromTypeDefinition(ITypeDefinition definition)
{
FileName assemblyLocation = definition.ParentAssembly.GetRuntimeAssemblyLocation();
if (assemblyLocation != null && SD.FileSystem.FileExists(assemblyLocation)) {
return new DecompiledTypeReference(assemblyLocation, definition.FullTypeName.TopLevelTypeName);
}
return null;
} }
public static string EscapeTypeName(string typeName) public static string EscapeTypeName(string typeName)
@ -204,9 +204,7 @@ namespace ICSharpCode.ILSpyAddIn
{ {
if (typeName == null) if (typeName == null)
throw new ArgumentNullException("typeName"); throw new ArgumentNullException("typeName");
foreach (var ch in Path.GetInvalidFileNameChars().Concat(new[] { '_' })) {
typeName = unescapeRegex.Replace(typeName, m => ((char)int.Parse(m.Groups[1].Value, System.Globalization.NumberStyles.HexNumber)).ToString()); typeName = unescapeRegex.Replace(typeName, m => ((char)int.Parse(m.Groups[1].Value, System.Globalization.NumberStyles.HexNumber)).ToString());
}
return typeName; return typeName;
} }

34
src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyDisplayBinding.cs

@ -0,0 +1,34 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.IO;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Workbench;
namespace ICSharpCode.ILSpyAddIn
{
public class ILSpyDisplayBinding : IDisplayBinding
{
public bool IsPreferredBindingForFile(FileName fileName)
{
return fileName.ToString().StartsWith("ilspy://", StringComparison.OrdinalIgnoreCase);
}
public bool CanCreateContentForFile(FileName fileName)
{
return fileName.ToString().StartsWith("ilspy://", StringComparison.OrdinalIgnoreCase);
}
public double AutoDetectFileContent(FileName fileName, Stream fileContent, string detectedMimeType)
{
return 1;
}
public IViewContent CreateContentForFile(OpenedFile file)
{
return new DecompiledViewContent(DecompiledTypeReference.FromFileName(file.FileName), "");
}
}
}

5
src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyFullParseInformation.cs

@ -17,14 +17,11 @@ namespace ICSharpCode.ILSpyAddIn
public class ILSpyFullParseInformation : ParseInformation public class ILSpyFullParseInformation : ParseInformation
{ {
SyntaxTree syntaxTree; SyntaxTree syntaxTree;
// Required to make WeakReferences work properly as cache policy.
AssemblyDefinition[] neededAssemblies;
public ILSpyFullParseInformation(ILSpyUnresolvedFile unresolvedFile, ITextSourceVersion parsedVersion, SyntaxTree syntaxTree, IEnumerable<AssemblyDefinition> neededAssemblies) public ILSpyFullParseInformation(ILSpyUnresolvedFile unresolvedFile, ITextSourceVersion parsedVersion, SyntaxTree syntaxTree)
: base(unresolvedFile, parsedVersion, true) : base(unresolvedFile, parsedVersion, true)
{ {
this.syntaxTree = syntaxTree; this.syntaxTree = syntaxTree;
this.neededAssemblies = neededAssemblies.ToArray();
} }
public SyntaxTree SyntaxTree { get { return syntaxTree; } } public SyntaxTree SyntaxTree { get { return syntaxTree; } }

24
src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyParser.cs

@ -32,16 +32,23 @@ namespace ICSharpCode.ILSpyAddIn
return fileName != null && fileName.StartsWith("ilspy://", StringComparison.OrdinalIgnoreCase); return fileName != null && fileName.StartsWith("ilspy://", StringComparison.OrdinalIgnoreCase);
} }
readonly static ITextSource EmptyFileContent = new StringTextSource("");
public ITextSource GetFileContent(FileName fileName)
{
return EmptyFileContent;
}
public ParseInformation Parse(FileName fileName, ITextSource fileContent, bool fullParseInformationRequested, IProject parentProject, CancellationToken cancellationToken) public ParseInformation Parse(FileName fileName, ITextSource fileContent, bool fullParseInformationRequested, IProject parentProject, CancellationToken cancellationToken)
{ {
return ILSpyDecompilerService.ParseDecompiledType(DecompiledTypeReference.FromFileName(fileName), cancellationToken); return ILSpyDecompilerService.DecompileType(DecompiledTypeReference.FromFileName(fileName), cancellationToken);
} }
public ResolveResult Resolve(ParseInformation parseInfo, TextLocation location, ICompilation compilation, CancellationToken cancellationToken) public ResolveResult Resolve(ParseInformation parseInfo, TextLocation location, ICompilation compilation, CancellationToken cancellationToken)
{ {
var decompiledParseInfo = parseInfo as ILSpyFullParseInformation; var decompiledParseInfo = parseInfo as ILSpyFullParseInformation;
if (decompiledParseInfo == null) if (decompiledParseInfo == null)
throw new ArgumentException("Parse info does not have SyntaxTree"); throw new ArgumentException("ParseInfo does not have SyntaxTree");
return ResolveAtLocation.Resolve(compilation, null, decompiledParseInfo.SyntaxTree, location, cancellationToken); return ResolveAtLocation.Resolve(compilation, null, decompiledParseInfo.SyntaxTree, location, cancellationToken);
} }
@ -55,16 +62,6 @@ namespace ICSharpCode.ILSpyAddIn
throw new NotImplementedException(); throw new NotImplementedException();
} }
static readonly Lazy<IAssemblyReference[]> defaultReferences = new Lazy<IAssemblyReference[]>(
delegate {
Assembly[] assemblies = {
typeof(object).Assembly,
typeof(Uri).Assembly,
typeof(Enumerable).Assembly
};
return assemblies.Select(asm => new CecilLoader().LoadAssemblyFile(asm.Location)).ToArray();
});
public ICompilation CreateCompilationForSingleFile(FileName fileName, IUnresolvedFile unresolvedFile) public ICompilation CreateCompilationForSingleFile(FileName fileName, IUnresolvedFile unresolvedFile)
{ {
DecompiledTypeReference reference = DecompiledTypeReference.FromFileName(fileName); DecompiledTypeReference reference = DecompiledTypeReference.FromFileName(fileName);
@ -73,10 +70,9 @@ namespace ICSharpCode.ILSpyAddIn
if (model == null) if (model == null)
model = SD.AssemblyParserService.GetAssemblyModelSafe(reference.AssemblyFile, true); model = SD.AssemblyParserService.GetAssemblyModelSafe(reference.AssemblyFile, true);
if (model != null) if (model != null)
return SD.AssemblyParserService.CreateCompilationForAssembly(model, true); return model.Context.GetCompilation();
} }
return new CSharpProjectContent() return new CSharpProjectContent()
.AddAssemblyReferences(defaultReferences.Value)
.AddOrUpdateFiles(unresolvedFile) .AddOrUpdateFiles(unresolvedFile)
.CreateCompilation(); .CreateCompilation();
} }

57
src/AddIns/DisplayBindings/ILSpyAddIn/ILSpySymbolSource.cs

@ -8,6 +8,7 @@ using ICSharpCode.Decompiler;
using ICSharpCode.NRefactory; using ICSharpCode.NRefactory;
using ICSharpCode.NRefactory.Documentation; using ICSharpCode.NRefactory.Documentation;
using ICSharpCode.NRefactory.TypeSystem; using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop;
namespace ICSharpCode.ILSpyAddIn namespace ICSharpCode.ILSpyAddIn
{ {
@ -20,28 +21,23 @@ namespace ICSharpCode.ILSpyAddIn
public bool IsCompilerGenerated(IMethod method) public bool IsCompilerGenerated(IMethod method)
{ {
var symbols = GetSymbols(method); return false;
return symbols == null || symbols.SequencePoints.Count == 0;
} }
public static MethodDebugSymbols GetSymbols(IMethod method) public static ILSpyUnresolvedFile GetSymbols(IMethod method)
{ {
// Use the non-specialised method definition to look up decompiled symbols var typeName = DecompiledTypeReference.FromTypeDefinition(method.DeclaringTypeDefinition);
var id = IdStringProvider.GetIdString(method.MemberDefinition); if (typeName == null) return null;
var content = DecompiledViewContent.Get(method); return SD.ParserService.ParseFile(typeName.ToFileName()) as ILSpyUnresolvedFile;
if (content != null && content.DebugSymbols.ContainsKey(id)) {
return content.DebugSymbols[id];
}
return null;
} }
public Debugger.SequencePoint GetSequencePoint(IMethod method, int iloffset) public Debugger.SequencePoint GetSequencePoint(IMethod method, int iloffset)
{ {
string id = IdStringProvider.GetIdString(method.MemberDefinition); string id = IdStringProvider.GetIdString(method.MemberDefinition);
var content = DecompiledViewContent.Get(method); var file = GetSymbols(method);
if (content == null || !content.DebugSymbols.ContainsKey(id)) if (file == null || !file.DebugSymbols.ContainsKey(id))
return null; return null;
var symbols = content.DebugSymbols[id]; var symbols = file.DebugSymbols[id];
var seqs = symbols.SequencePoints; var seqs = symbols.SequencePoints;
var seq = seqs.FirstOrDefault(p => p.ILRanges.Any(r => r.From <= iloffset && iloffset < r.To)); var seq = seqs.FirstOrDefault(p => p.ILRanges.Any(r => r.From <= iloffset && iloffset < r.To));
if (seq == null) if (seq == null)
@ -52,7 +48,7 @@ namespace ICSharpCode.ILSpyAddIn
seq = seqs.Where(p => p.ILRanges.Any(r => r.From <= iloffset && iloffset < r.To)) seq = seqs.Where(p => p.ILRanges.Any(r => r.From <= iloffset && iloffset < r.To))
.OrderByDescending(p => p.ILRanges.Last().To - p.ILRanges.First().From) .OrderByDescending(p => p.ILRanges.Last().To - p.ILRanges.First().From)
.FirstOrDefault(); .FirstOrDefault();
return seq.ToDebugger(symbols, content.PrimaryFileName); return seq.ToDebugger(symbols, file.FileName);
} }
return null; return null;
} }
@ -63,28 +59,31 @@ namespace ICSharpCode.ILSpyAddIn
if (name == null || !FileUtility.IsEqualFileName(module.FullPath, name.AssemblyFile)) if (name == null || !FileUtility.IsEqualFileName(module.FullPath, name.AssemblyFile))
yield break; yield break;
var content = DecompiledViewContent.Get(name); var file = SD.ParserService.ParseFile(name.ToFileName()) as ILSpyUnresolvedFile;
if (content == null) if (file == null)
yield break; yield break;
TextLocation loc = new TextLocation(line, column); TextLocation loc = new TextLocation(line, column);
foreach(var symbols in content.DebugSymbols.Values.Where(s => s.StartLocation <= loc && loc <= s.EndLocation)) { foreach(var symbols in file.DebugSymbols.Values.Where(s => s.StartLocation <= loc && loc <= s.EndLocation)) {
Decompiler.SequencePoint seq = null; Decompiler.SequencePoint seq = null;
if (column != 0) if (column != 0)
seq = symbols.SequencePoints.FirstOrDefault(p => p.StartLocation <= loc && loc <= p.EndLocation); seq = symbols.SequencePoints.FirstOrDefault(p => p.StartLocation <= loc && loc <= p.EndLocation);
if (seq == null) if (seq == null)
seq = symbols.SequencePoints.FirstOrDefault(p => line <= p.StartLocation.Line); seq = symbols.SequencePoints.FirstOrDefault(p => line <= p.StartLocation.Line);
if (seq != null) if (seq != null)
yield return seq.ToDebugger(symbols, content.PrimaryFileName); yield return seq.ToDebugger(symbols, filename);
} }
} }
public IEnumerable<ILRange> GetIgnoredILRanges(IMethod method) public IEnumerable<ILRange> GetIgnoredILRanges(IMethod method)
{ {
var symbols = GetSymbols(method); string id = IdStringProvider.GetIdString(method.MemberDefinition);
if (symbols == null) var file = GetSymbols(method);
if (file == null || !file.DebugSymbols.ContainsKey(id))
return new ILRange[] { }; return new ILRange[] { };
var symbols = file.DebugSymbols[id];
int codesize = symbols.CecilMethod.Body.CodeSize; int codesize = symbols.CecilMethod.Body.CodeSize;
var inv = ICSharpCode.Decompiler.ILAst.ILRange.Invert(symbols.SequencePoints.SelectMany(s => s.ILRanges), codesize); var inv = ICSharpCode.Decompiler.ILAst.ILRange.Invert(symbols.SequencePoints.SelectMany(s => s.ILRanges), codesize);
return inv.Select(r => new ILRange(r.From, r.To)); return inv.Select(r => new ILRange(r.From, r.To));
@ -92,16 +91,24 @@ namespace ICSharpCode.ILSpyAddIn
public IEnumerable<ILLocalVariable> GetLocalVariables(IMethod method) public IEnumerable<ILLocalVariable> GetLocalVariables(IMethod method)
{ {
var symbols = GetSymbols(method); string id = IdStringProvider.GetIdString(method.MemberDefinition);
if (symbols == null) var file = GetSymbols(method);
if (file == null || !file.DebugSymbols.ContainsKey(id))
return null; return null;
return symbols.LocalVariables.Select(v => new Debugger.ILLocalVariable() { var symbols = file.DebugSymbols[id];
var context = new SimpleTypeResolveContext(method);
var loader = new CecilLoader();
return symbols.LocalVariables.Select(
v => new Debugger.ILLocalVariable() {
Index = v.OriginalVariable.Index, Index = v.OriginalVariable.Index,
Type = method.Compilation.FindType(KnownTypeCode.Object), // TODO Type = loader.ReadTypeReference(v.Type).Resolve(context),
Name = v.Name, Name = v.Name,
IsCompilerGenerated = false, IsCompilerGenerated = false,
ILRanges = new [] { new Debugger.ILRange(0, int.MaxValue) } ILRanges = new [] { new ILRange(0, int.MaxValue) }
}); });
} }
} }

8
src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyUnresolvedFile.cs

@ -20,7 +20,7 @@ namespace ICSharpCode.ILSpyAddIn
public class ILSpyUnresolvedFile : CSharpUnresolvedFile public class ILSpyUnresolvedFile : CSharpUnresolvedFile
{ {
DecompiledTypeReference name; DecompiledTypeReference name;
StringWriter writer; string output;
public static ILSpyUnresolvedFile Create(DecompiledTypeReference name, AstBuilder builder) public static ILSpyUnresolvedFile Create(DecompiledTypeReference name, AstBuilder builder)
{ {
@ -38,7 +38,7 @@ namespace ICSharpCode.ILSpyAddIn
file.MemberLocations = output.MemberLocations; file.MemberLocations = output.MemberLocations;
file.DebugSymbols = output.DebugSymbols; file.DebugSymbols = output.DebugSymbols;
file.writer = writer; file.output = writer.ToString();
return file; return file;
} }
@ -53,8 +53,8 @@ namespace ICSharpCode.ILSpyAddIn
public Dictionary<string, MethodDebugSymbols> DebugSymbols { get; private set; } public Dictionary<string, MethodDebugSymbols> DebugSymbols { get; private set; }
public StringWriter Writer { public string Output {
get { return writer; } get { return output; }
} }
public FileName AssemblyFile { public FileName AssemblyFile {

2
src/AddIns/DisplayBindings/ILSpyAddIn/NavigateToDecompiledEntityService.cs

@ -44,7 +44,7 @@ namespace ICSharpCode.ILSpyAddIn
if (string.IsNullOrEmpty(typeName)) if (string.IsNullOrEmpty(typeName))
throw new ArgumentException("typeName is null or empty"); throw new ArgumentException("typeName is null or empty");
var type = new FullTypeName(typeName); var type = new TopLevelTypeName(typeName);
var target = new DecompiledTypeReference(assemblyFile, type); var target = new DecompiledTypeReference(assemblyFile, type);
foreach (var viewContent in SD.Workbench.ViewContentCollection.OfType<DecompiledViewContent>()) { foreach (var viewContent in SD.Workbench.ViewContentCollection.OfType<DecompiledViewContent>()) {

9
src/Libraries/NRefactory/ICSharpCode.NRefactory.Xml/DocumentationElement.cs

@ -46,6 +46,12 @@ namespace ICSharpCode.NRefactory.Xml
IMember member = entity as IMember; IMember member = entity as IMember;
if (inheritDocIfMissing && member != null) { if (inheritDocIfMissing && member != null) {
if (member.SymbolKind == SymbolKind.Constructor) {
// For constructors, the documentation of the base class ctor
// isn't really suitable as constructors are not inherited.
// We'll use the type's documentation instead:
return Get(entity.DeclaringTypeDefinition, inheritDocIfMissing);
}
foreach (IMember baseMember in InheritanceHelper.GetBaseMembers(member, includeImplementedInterfaces: true)) { foreach (IMember baseMember in InheritanceHelper.GetBaseMembers(member, includeImplementedInterfaces: true)) {
documentationComment = baseMember.Documentation; documentationComment = baseMember.Documentation;
if (documentationComment != null) if (documentationComment != null)
@ -104,6 +110,7 @@ namespace ICSharpCode.NRefactory.Xml
{ {
if (text == null) if (text == null)
throw new ArgumentNullException("text"); throw new ArgumentNullException("text");
this.declaringEntity = declaringEntity;
this.textContent = text; this.textContent = text;
} }
@ -112,7 +119,7 @@ namespace ICSharpCode.NRefactory.Xml
/// May return null. /// May return null.
/// </summary> /// </summary>
public IEntity DeclaringEntity { public IEntity DeclaringEntity {
get { return null; } get { return declaringEntity; }
} }
IEntity referencedEntity; IEntity referencedEntity;

30
src/Main/Base/Project/Dom/IEntityModelContext.cs

@ -107,20 +107,40 @@ namespace ICSharpCode.SharpDevelop.Dom
} }
} }
public class DomAssemblyNameReference : IAssemblyReference
{
DomAssemblyName name;
IAssemblySearcher searcher;
public DomAssemblyNameReference(DomAssemblyName name, IAssemblySearcher searcher)
{
if (name == null)
throw new ArgumentNullException("name");
if (searcher == null)
throw new ArgumentNullException("searcher");
this.name = name;
this.searcher = searcher;
}
public IAssembly Resolve(ITypeResolveContext context)
{
return SD.AssemblyParserService.GetAssembly(searcher.FindAssembly(name), true).Resolve(context);
}
}
public class AssemblyEntityModelContext : IEntityModelContext public class AssemblyEntityModelContext : IEntityModelContext
{ {
ICompilation compilation; Lazy<ICompilation> compilation;
IUnresolvedAssembly mainAssembly; IUnresolvedAssembly mainAssembly;
IAssemblyReference[] references; IAssemblyReference[] references;
public AssemblyEntityModelContext(IUnresolvedAssembly mainAssembly, params IAssemblyReference[] references) public AssemblyEntityModelContext(IUnresolvedAssembly mainAssembly, IAssemblyReference[] references)
{ {
if (mainAssembly == null) if (mainAssembly == null)
throw new ArgumentNullException("mainAssembly"); throw new ArgumentNullException("mainAssembly");
this.mainAssembly = mainAssembly; this.mainAssembly = mainAssembly;
this.references = references; this.references = references;
// implement lazy init + weak caching this.compilation = new Lazy<ICompilation>(() => new SimpleCompilation(mainAssembly, references));
this.compilation = new SimpleCompilation(mainAssembly, references);
} }
public string AssemblyName { public string AssemblyName {
@ -137,7 +157,7 @@ namespace ICSharpCode.SharpDevelop.Dom
public ICompilation GetCompilation() public ICompilation GetCompilation()
{ {
return compilation; return compilation.Value;
} }
public bool IsBetterPart(IUnresolvedTypeDefinition part1, IUnresolvedTypeDefinition part2) public bool IsBetterPart(IUnresolvedTypeDefinition part1, IUnresolvedTypeDefinition part2)

2
src/Main/Base/Project/Editor/ContextActions/ContextActionViewModel.cs

@ -86,6 +86,8 @@ namespace ICSharpCode.SharpDevelop.Editor.ContextActions
public void Execute(object parameter) public void Execute(object parameter)
{ {
if (action.Provider != null)
SD.AnalyticsMonitor.TrackFeature(action.Provider.ID);
this.action.Execute(context); this.action.Execute(context);
} }

10
src/Main/Base/Project/Parser/IAssemblyParserService.cs

@ -51,16 +51,6 @@ namespace ICSharpCode.SharpDevelop.Parser
event EventHandler<RefreshAssemblyEventArgs> AssemblyRefreshed; event EventHandler<RefreshAssemblyEventArgs> AssemblyRefreshed;
/// <summary>
/// Creates a compilation for the specified assembly.
/// </summary>
ICompilation CreateCompilationForAssembly(IAssemblyModel assembly, bool includeInternalMembers = false);
/// <summary>
/// Creates a compilation for the specified assembly.
/// </summary>
ICompilation CreateCompilationForAssembly(FileName assembly, bool includeInternalMembers = false);
/// <summary> /// <summary>
/// Creates an IAssemblyModel for the given assembly file. /// Creates an IAssemblyModel for the given assembly file.
/// </summary> /// </summary>

6
src/Main/Base/Project/Parser/IParser.cs

@ -34,10 +34,14 @@ namespace ICSharpCode.SharpDevelop.Parser
/// </summary> /// </summary>
bool CanParse(string fileName); bool CanParse(string fileName);
/// <summary>
/// Returns the content for a given filename.
/// </summary>
ITextSource GetFileContent(FileName fileName);
/// <summary> /// <summary>
/// Parses a file. /// Parses a file.
/// </summary> /// </summary>
/// <param name="projectContent">The parent project of the file.</param>
/// <param name="fileName">The name of the file being parsed.</param> /// <param name="fileName">The name of the file being parsed.</param>
/// <param name="fileContent">The content of the file.</param> /// <param name="fileContent">The content of the file.</param>
/// <param name="fullParseInformationRequested"> /// <param name="fullParseInformationRequested">

2
src/Main/Base/Project/Refactoring/ContextAction.cs

@ -12,7 +12,7 @@ namespace ICSharpCode.SharpDevelop.Refactoring
{ {
/// <summary> /// <summary>
/// Base class for implementing one context action. /// Base class for implementing one context action.
/// Useful for implementing <see cref="IContextActionsProvider" /> that provides just one action - common scenario. /// Useful for implementing <see cref="IContextActionProvider" /> that provides just one action - common scenario.
/// </summary> /// </summary>
public abstract class ContextAction : IContextActionProvider, IContextAction public abstract class ContextAction : IContextActionProvider, IContextAction
{ {

31
src/Main/SharpDevelop/Parser/AssemblyParserService.cs

@ -83,14 +83,14 @@ namespace ICSharpCode.SharpDevelop.Parser
void CleanWeakDictionary() void CleanWeakDictionary()
{ {
Debug.Assert(Monitor.IsEntered(projectContentDictionary)); // Debug.Assert(Monitor.IsEntered(projectContentDictionary));
List<FileName> removed = new List<FileName>(); // List<FileName> removed = new List<FileName>();
foreach (var pair in projectContentDictionary) { // foreach (var pair in projectContentDictionary) {
//if (!pair.Value.IsAlive) // if (!pair.Value.IsAlive)
// removed.Add(pair.Key); // removed.Add(pair.Key);
} // }
foreach (var key in removed) // foreach (var key in removed)
projectContentDictionary.Remove(key); // projectContentDictionary.Remove(key);
} }
LoadedAssembly GetLoadedAssembly(FileName fileName, bool includeInternalMembers) LoadedAssembly GetLoadedAssembly(FileName fileName, bool includeInternalMembers)
@ -327,21 +327,6 @@ namespace ICSharpCode.SharpDevelop.Parser
} }
#endregion #endregion
public ICompilation CreateCompilationForAssembly(IAssemblyModel assembly, bool includeInternalMembers = false)
{
var mainAssembly = GetAssembly(assembly.Location, includeInternalMembers);
var searcher = new DefaultAssemblySearcher(assembly.Location);
var references = assembly.References
.Select(searcher.FindAssembly)
.Where(f => f != null);
return new SimpleCompilation(mainAssembly, references.Select(fn => GetAssembly(fn, includeInternalMembers)));
}
public ICompilation CreateCompilationForAssembly(FileName assembly, bool includeInternalMembers = false)
{
return CreateCompilationForAssembly(GetAssemblyModel(assembly, includeInternalMembers), includeInternalMembers);
}
public IAssemblyModel GetAssemblyModel(FileName fileName, bool includeInternalMembers = false) public IAssemblyModel GetAssemblyModel(FileName fileName, bool includeInternalMembers = false)
{ {
LoadedAssembly assembly = GetLoadedAssembly(fileName, includeInternalMembers); LoadedAssembly assembly = GetLoadedAssembly(fileName, includeInternalMembers);

2
src/Main/SharpDevelop/Parser/ParserService.cs

@ -315,7 +315,7 @@ namespace ICSharpCode.SharpDevelop.Parser
if (entry.parser == null) if (entry.parser == null)
return; return;
if (fileContent == null) if (fileContent == null)
fileContent = SD.FileService.GetFileContent(fileName); fileContent = entry.parser.GetFileContent(fileName);
if (compilation == null) if (compilation == null)
compilation = GetCompilationForFile(fileName); compilation = GetCompilationForFile(fileName);
var parseInfo = await entry.ParseAsync(fileContent, compilation.GetProject(), cancellationToken).ConfigureAwait(false); var parseInfo = await entry.ParseAsync(fileContent, compilation.GetProject(), cancellationToken).ConfigureAwait(false);

6
src/Main/SharpDevelop/Parser/ParserServiceEntry.cs

@ -167,7 +167,7 @@ namespace ICSharpCode.SharpDevelop.Parser
public ParseInformation Parse(ITextSource fileContent, IProject parentProject, CancellationToken cancellationToken) public ParseInformation Parse(ITextSource fileContent, IProject parentProject, CancellationToken cancellationToken)
{ {
if (fileContent == null) { if (fileContent == null) {
fileContent = SD.FileService.GetFileContent(fileName); fileContent = parser.GetFileContent(fileName);
} }
return DoParse(fileContent, parentProject, true, cancellationToken).CachedParseInformation; return DoParse(fileContent, parentProject, true, cancellationToken).CachedParseInformation;
@ -176,7 +176,7 @@ namespace ICSharpCode.SharpDevelop.Parser
public IUnresolvedFile ParseFile(ITextSource fileContent, IProject parentProject, CancellationToken cancellationToken) public IUnresolvedFile ParseFile(ITextSource fileContent, IProject parentProject, CancellationToken cancellationToken)
{ {
if (fileContent == null) { if (fileContent == null) {
fileContent = SD.FileService.GetFileContent(fileName); fileContent = parser.GetFileContent(fileName);
} }
return DoParse(fileContent, parentProject, false, cancellationToken).UnresolvedFile; return DoParse(fileContent, parentProject, false, cancellationToken).UnresolvedFile;
@ -302,7 +302,7 @@ namespace ICSharpCode.SharpDevelop.Parser
// Let's look up the file in the list of open files right now // Let's look up the file in the list of open files right now
// so that we don't need to SafeThreadCall() later on. // so that we don't need to SafeThreadCall() later on.
lookupOpenFileOnTargetThread = false; lookupOpenFileOnTargetThread = false;
fileContent = SD.FileService.GetFileContentForOpenFile(fileName); fileContent = parser.GetFileContent(fileName);
} }
Task<ProjectEntry> task; Task<ProjectEntry> task;
lock (this) { lock (this) {

18
src/Main/SharpDevelop/Workbench/DisplayBinding/DisplayBindingService.cs

@ -15,15 +15,18 @@ namespace ICSharpCode.SharpDevelop.Workbench
sealed class DisplayBindingService : IDisplayBindingService sealed class DisplayBindingService : IDisplayBindingService
{ {
const string displayBindingPath = "/SharpDevelop/Workbench/DisplayBindings"; const string displayBindingPath = "/SharpDevelop/Workbench/DisplayBindings";
const string urlBasedDisplayBindingPath = "/SharpDevelop/Workbench/DisplayBindings/UrlBased";
Properties displayBindingServiceProperties; Properties displayBindingServiceProperties;
List<DisplayBindingDescriptor> bindings; List<DisplayBindingDescriptor> bindings;
List<DisplayBindingDescriptor> urlBasedBindings;
List<ExternalProcessDisplayBinding> externalProcessDisplayBindings = new List<ExternalProcessDisplayBinding>(); List<ExternalProcessDisplayBinding> externalProcessDisplayBindings = new List<ExternalProcessDisplayBinding>();
public DisplayBindingService() public DisplayBindingService()
{ {
bindings = AddInTree.BuildItems<DisplayBindingDescriptor>(displayBindingPath, null, true); bindings = AddInTree.BuildItems<DisplayBindingDescriptor>(displayBindingPath, null, true);
urlBasedBindings = AddInTree.BuildItems<DisplayBindingDescriptor>(urlBasedDisplayBindingPath, null, false);
displayBindingServiceProperties = SD.PropertyService.NestedProperties("DisplayBindingService"); displayBindingServiceProperties = SD.PropertyService.NestedProperties("DisplayBindingService");
foreach (var binding in displayBindingServiceProperties.GetList<ExternalProcessDisplayBinding>("ExternalProcesses")) { foreach (var binding in displayBindingServiceProperties.GetList<ExternalProcessDisplayBinding>("ExternalProcesses")) {
if (binding != null) { if (binding != null) {
@ -84,7 +87,7 @@ namespace ICSharpCode.SharpDevelop.Workbench
if (FileUtility.IsUrl(filename)) { if (FileUtility.IsUrl(filename)) {
// The normal display binding dispatching code can't handle URLs (e.g. because it uses Path.GetExtension), // The normal display binding dispatching code can't handle URLs (e.g. because it uses Path.GetExtension),
// so we'll directly return the browser display binding. // so we'll directly return the browser display binding.
return new BrowserDisplayBinding.BrowserDisplayBinding(); return GetBindingForUrl(filename);
} }
DisplayBindingDescriptor codon = GetDefaultCodonPerFileName(filename); DisplayBindingDescriptor codon = GetDefaultCodonPerFileName(filename);
return codon == null ? null : codon.Binding; return codon == null ? null : codon.Binding;
@ -112,13 +115,24 @@ namespace ICSharpCode.SharpDevelop.Workbench
if (IsPrimaryBindingValidForFileName(binding, filename)) { if (IsPrimaryBindingValidForFileName(binding, filename)) {
if (binding.Binding.IsPreferredBindingForFile(filename)) if (binding.Binding.IsPreferredBindingForFile(filename))
return binding; return binding;
else if (binding.Binding is AutoDetectDisplayBinding) if (binding.Binding is AutoDetectDisplayBinding)
autoDetectDescriptor = binding; autoDetectDescriptor = binding;
} }
} }
return autoDetectDescriptor; return autoDetectDescriptor;
} }
IDisplayBinding GetBindingForUrl(FileName url)
{
foreach (DisplayBindingDescriptor binding in urlBasedBindings) {
if (IsPrimaryBindingValidForFileName(binding, url)) {
if (binding.Binding.IsPreferredBindingForFile(url))
return binding.Binding;
}
}
return new BrowserDisplayBinding.BrowserDisplayBinding();
}
public void SetDefaultCodon(string extension, DisplayBindingDescriptor bindingDescriptor) public void SetDefaultCodon(string extension, DisplayBindingDescriptor bindingDescriptor)
{ {
SD.MainThread.VerifyAccess(); SD.MainThread.VerifyAccess();

Loading…
Cancel
Save