diff --git a/src/AddIns/Debugger/Debugger.Core/Breakpoint.cs b/src/AddIns/Debugger/Debugger.Core/Breakpoint.cs index 2e170818cc..f6b1e8a034 100644 --- a/src/AddIns/Debugger/Debugger.Core/Breakpoint.cs +++ b/src/AddIns/Debugger/Debugger.Core/Breakpoint.cs @@ -84,7 +84,7 @@ namespace Debugger public void SetBreakpoint(Module module) { - foreach(var symbolSource in module.Process.Debugger.SymbolSources) { + foreach (var symbolSource in module.Process.Debugger.SymbolSources) { foreach (var seq in symbolSource.GetSequencePoints(module, this.FileName, this.Line, this.Column)) { ICorDebugFunction corFunction = module.CorModule.GetFunctionFromToken(seq.MethodDefToken); ICorDebugFunctionBreakpoint corBreakpoint = corFunction.GetILCode().CreateBreakpoint((uint)seq.ILOffset); diff --git a/src/AddIns/Debugger/Debugger.Core/PdbSymbolSource.cs b/src/AddIns/Debugger/Debugger.Core/PdbSymbolSource.cs index 5715fa7443..945242fbe3 100644 --- a/src/AddIns/Debugger/Debugger.Core/PdbSymbolSource.cs +++ b/src/AddIns/Debugger/Debugger.Core/PdbSymbolSource.cs @@ -48,6 +48,14 @@ namespace Debugger this.StartLine, this.StartColumn, this.EndLine, this.EndColumn); } + + public bool ContainsLocation(int line, int column = 0) + { + if (column == 0) + return line >= StartLine && line <= EndLine; + return (StartLine < line || (StartLine == line && StartColumn <= column)) + && (line < EndLine || (line == EndLine && column <= EndColumn)); + } } public struct ILRange @@ -185,14 +193,14 @@ namespace Debugger var realSeqPoints = sequencePoints.Where(p => p.StartLine != 0xFEEFEE); // Find point for which (ilstart <= iloffset < ilend) or fallback to the next valid sequence point - var sequencePoint = realSeqPoints.FirstOrDefault(p => p.ILRanges.Any(r => r.From <= iloffset && iloffset < r.To)) ?? - realSeqPoints.FirstOrDefault(p => iloffset <= p.ILOffset); + var sequencePoint = realSeqPoints.FirstOrDefault(p => p.ILRanges.Any(r => r.From <= iloffset && iloffset < r.To)) + ?? realSeqPoints.FirstOrDefault(p => iloffset <= p.ILOffset); if (sequencePoint != null) { // VB.NET sometimes produces temporary files which it then deletes // (eg 17d14f5c-a337-4978-8281-53493378c1071.vb) string name = Path.GetFileName(sequencePoint.Filename); - if (name.Length == 40 && name.EndsWith(".vb")) { + if (name.Length == 40 && name.EndsWith(".vb", StringComparison.OrdinalIgnoreCase)) { if (name.Substring(0, name.Length - 3).All(c => ('0' <= c && c <= '9') || ('a' <= c && c <= 'f') || ('A' <= c && c <= 'F') || (c == '-'))) { return null; } @@ -226,25 +234,34 @@ namespace Debugger try { uint validLine = symDoc.FindClosestLine((uint)line); symMethods = symReader.GetMethodsFromDocumentPosition(symDoc, validLine, (uint)column); + if (validLine > 0) + line = (int)validLine; } catch { yield break; //Not found } foreach (ISymUnmanagedMethod symMethod in symMethods) { var corFunction = module.CorModule.GetFunctionFromToken(symMethod.GetToken()); - int codesize = (int)corFunction.GetILCode().GetSize(); - var seqPoints = symMethod.GetSequencePoints(codesize).Where(s => s.StartLine != 0xFEEFEE); - SequencePoint seqPoint = null; - if (column != 0) { - seqPoint = seqPoints.FirstOrDefault(s => (s.StartLine < line || (s.StartLine == line && s.StartColumn <= column)) && - (line < s.EndLine || (line == s.EndLine && column <= s.EndColumn))); - } - seqPoint = seqPoint ?? seqPoints.FirstOrDefault(s => line <= s.StartLine); + int codeSize = (int)corFunction.GetILCode().GetSize(); + var seqPoints = symMethod.GetSequencePoints(codeSize).Where(s => s.StartLine != 0xFEEFEE).OrderBy(s => s.StartLine).ToArray(); + SequencePoint seqPoint = FindNearestMatchingSequencePoint(seqPoints, line, column); if (seqPoint != null) yield return seqPoint; } } + SequencePoint FindNearestMatchingSequencePoint(SequencePoint[] seqPoints, int line, int column) + { + for (int i = 0; i < seqPoints.Length; i++) { + var s = seqPoints[i]; + if (s.ContainsLocation(line, column)) + return s; + if (s.StartLine > line) + return s; + } + return null; + } + public IEnumerable GetIgnoredILRanges(IMethod method) { var symMethod = method.GetSymMethod(); diff --git a/src/Main/Core/Project/Src/Util/CommandWrapper.cs b/src/Main/Core/Project/Src/Util/CommandWrapper.cs index 70009c5366..b2adc9479f 100644 --- a/src/Main/Core/Project/Src/Util/CommandWrapper.cs +++ b/src/Main/Core/Project/Src/Util/CommandWrapper.cs @@ -44,6 +44,17 @@ namespace ICSharpCode.Core /// public static ICommand CreateLazyCommand(Codon codon, IReadOnlyCollection conditions) { + if (codon.Properties["loadclasslazy"] == "false") { + // if lazy loading was explicitly disabled, create the actual command now + return CreateCommand(codon, conditions); + } + if (codon.Properties.Contains("command") && !codon.Properties.Contains("loadclasslazy")) { + // If we're using the 'command=' syntax, this is most likely a built-in command + // where lazy loading isn't useful (and hurts if CanExecute is used). + // Don't use lazy loading unless loadclasslazy is set explicitly. + return CreateCommand(codon, conditions); + } + // Create the wrapper that lazily loads the actual command. return new CommandWrapper(codon, conditions); } diff --git a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs index c96ed51a2b..d134811d71 100644 --- a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs +++ b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuCommand.cs @@ -32,13 +32,10 @@ namespace ICSharpCode.Core.Presentation { readonly string ActivationMethod; - public MenuCommand(UIElement inputBindingOwner, Codon codon, object caller, bool createCommand, string activationMethod, IReadOnlyCollection conditions) : base(codon, caller, conditions) + public MenuCommand(UIElement inputBindingOwner, Codon codon, object caller, string activationMethod, IReadOnlyCollection conditions) : base(codon, caller, conditions) { this.ActivationMethod = activationMethod; - if (createCommand) - this.Command = CommandWrapper.CreateCommand(codon, conditions); - else - this.Command = CommandWrapper.CreateLazyCommand(codon, conditions); + this.Command = CommandWrapper.CreateLazyCommand(codon, conditions); this.CommandParameter = caller; if (!string.IsNullOrEmpty(codon.Properties["shortcut"])) { diff --git a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs index efdfb4209f..7f68990b38 100644 --- a/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs +++ b/src/Main/ICSharpCode.Core.Presentation/Menu/MenuService.cs @@ -211,7 +211,6 @@ namespace ICSharpCode.Core.Presentation { Codon codon = descriptor.Codon; string type = codon.Properties.Contains("type") ? codon.Properties["type"] : "Command"; - bool createCommand = codon.Properties["loadclasslazy"] == "false"; switch (type) { case "Separator": @@ -220,7 +219,7 @@ namespace ICSharpCode.Core.Presentation return new MenuCheckBox(context.InputBindingOwner, codon, descriptor.Parameter, descriptor.Conditions); case "Item": case "Command": - return new MenuCommand(context.InputBindingOwner, codon, descriptor.Parameter, createCommand, context.ActivationMethod, descriptor.Conditions); + return new MenuCommand(context.InputBindingOwner, codon, descriptor.Parameter, context.ActivationMethod, descriptor.Conditions); case "Menu": var item = new CoreMenuItem(codon, descriptor.Parameter, descriptor.Conditions) { ItemsSource = new object[1], diff --git a/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs b/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs index 094a150956..4b4e4663ab 100644 --- a/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs +++ b/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarButton.cs @@ -36,16 +36,13 @@ namespace ICSharpCode.Core.Presentation readonly string inputGestureText; readonly IEnumerable conditions; - public ToolBarButton(UIElement inputBindingOwner, Codon codon, object caller, bool createCommand, IReadOnlyCollection conditions) + public ToolBarButton(UIElement inputBindingOwner, Codon codon, object caller, IReadOnlyCollection conditions) { ToolTipService.SetShowOnDisabled(this, true); this.codon = codon; this.caller = caller; - if (createCommand) - this.Command = CommandWrapper.CreateCommand(codon, conditions); - else - this.Command = CommandWrapper.CreateLazyCommand(codon, conditions); + this.Command = CommandWrapper.CreateLazyCommand(codon, conditions); this.CommandParameter = caller; this.Content = ToolBarService.CreateToolBarItemContent(codon); this.conditions = conditions; diff --git a/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarService.cs b/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarService.cs index 9c0d128fe8..dce695ec80 100644 --- a/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarService.cs +++ b/src/Main/ICSharpCode.Core.Presentation/ToolBar/ToolBarService.cs @@ -65,15 +65,13 @@ namespace ICSharpCode.Core.Presentation object caller = descriptor.Parameter; string type = codon.Properties.Contains("type") ? codon.Properties["type"] : "Item"; - bool createCommand = codon.Properties["loadclasslazy"] == "false"; - switch (type) { case "Separator": return new ConditionalSeparator(codon, caller, true, descriptor.Conditions); case "CheckBox": return new ToolBarCheckBox(codon, caller, descriptor.Conditions); case "Item": - return new ToolBarButton(inputBindingOwner, codon, caller, createCommand, descriptor.Conditions); + return new ToolBarButton(inputBindingOwner, codon, caller, descriptor.Conditions); case "DropDownButton": return new ToolBarDropDownButton( codon, caller, MenuService.CreateUnexpandedMenuItems( diff --git a/src/Main/ICSharpCode.Core.WinForms/Menu/MenuCommand.cs b/src/Main/ICSharpCode.Core.WinForms/Menu/MenuCommand.cs index b8d2fc061f..92169ca890 100644 --- a/src/Main/ICSharpCode.Core.WinForms/Menu/MenuCommand.cs +++ b/src/Main/ICSharpCode.Core.WinForms/Menu/MenuCommand.cs @@ -43,23 +43,13 @@ namespace ICSharpCode.Core.WinForms } public MenuCommand(Codon codon, object caller, IReadOnlyCollection conditions) - : this(codon, caller, false, conditions) - { - - } - - public MenuCommand(Codon codon, object caller, bool createCommand, IReadOnlyCollection conditions) { this.RightToLeft = RightToLeft.Inherit; this.caller = caller; this.codon = codon; this.conditions = conditions; - if (createCommand) { - this.command = CommandWrapper.CreateCommand(codon, conditions); - } else { - this.command = CommandWrapper.CreateLazyCommand(codon, conditions); - } + this.command = CommandWrapper.CreateLazyCommand(codon, conditions); UpdateText(); } diff --git a/src/Main/ICSharpCode.Core.WinForms/Menu/MenuService.cs b/src/Main/ICSharpCode.Core.WinForms/Menu/MenuService.cs index d6237501a1..f82aa51fb2 100644 --- a/src/Main/ICSharpCode.Core.WinForms/Menu/MenuService.cs +++ b/src/Main/ICSharpCode.Core.WinForms/Menu/MenuService.cs @@ -62,7 +62,7 @@ namespace ICSharpCode.Core.WinForms return new MenuCheckBox(codon, descriptor.Parameter, descriptor.Conditions); case "Item": case "Command": - return new MenuCommand(codon, descriptor.Parameter, createCommand, descriptor.Conditions); + return new MenuCommand(codon, descriptor.Parameter, descriptor.Conditions); case "Menu": return new Menu(codon, descriptor.Parameter, ConvertSubItems(descriptor.SubItems), descriptor.Conditions); case "Builder": diff --git a/src/Main/SharpDevelop/Project/Build/MSBuildEngine/MSBuildEngine.cs b/src/Main/SharpDevelop/Project/Build/MSBuildEngine/MSBuildEngine.cs index f4c9f5af5c..6142d601f2 100644 --- a/src/Main/SharpDevelop/Project/Build/MSBuildEngine/MSBuildEngine.cs +++ b/src/Main/SharpDevelop/Project/Build/MSBuildEngine/MSBuildEngine.cs @@ -94,6 +94,7 @@ namespace ICSharpCode.SharpDevelop.Project throw new ArgumentNullException("feedbackSink"); var additionalTargetFileList = additionalTargetFiles != null ? additionalTargetFiles.ToList() : new List(); + additionalTargetFileList.AddRange(AdditionalTargetFiles.Select(fileName => fileName.ToString())); if (project.MinimumSolutionVersion >= SolutionFormatVersion.VS2010) { additionalTargetFileList.Add(Path.Combine(Path.GetDirectoryName(typeof(MSBuildEngine).Assembly.Location), "SharpDevelop.TargetingPack.targets")); }