Skip to content
This repository was archived by the owner on Oct 16, 2020. It is now read-only.

Commit 2882c6a

Browse files
Merge branch 'master' of github.com:icsharpcode/SharpDevelop
2 parents a98e696 + 69bef7e commit 2882c6a

11 files changed

Lines changed: 196 additions & 83 deletions

File tree

src/AddIns/Analysis/CodeCoverage/Project/Src/CodeCoverageMethodElement.cs

Lines changed: 71 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ public CodeCoverageMethodElement(XElement element, CodeCoverageResults results)
5858

5959
public string FileID { get; private set; }
6060
public string FileName { get; private set; }
61+
public string FileNameExt { get; private set; }
6162
public bool IsVisited { get; private set; }
6263
public int CyclomaticComplexity { get; private set; }
6364
public decimal SequenceCoverage { get; private set; }
@@ -86,9 +87,14 @@ void Init()
8687

8788
this.FileID = GetFileRef();
8889
this.FileName = String.Empty;
90+
this.FileNameExt = String.Empty;
8991
if (!String.IsNullOrEmpty(this.FileID)) {
9092
if (results != null) {
9193
this.FileName = results.GetFileName(this.FileID);
94+
try {
95+
this.FileNameExt = Path.GetExtension(this.FileName).ToLowerInvariant();
96+
}
97+
catch {}
9298
if (cacheFileName != this.FileName) {
9399
cacheFileName = this.FileName;
94100
cacheDocument = GetSource (cacheFileName);
@@ -220,14 +226,19 @@ void GetSequencePointContent(CodeCoverageSequencePoint sp)
220226
// -> this method SP with lowest Line/Column
221227
void getBodyStartSP() {
222228
if (this.SequencePoints.Count != 0) {
223-
foreach (CodeCoverageSequencePoint sp in this.SequencePoints) {
224-
if (sp.FileID != this.FileID) continue;
225-
if (this.BodyStartSP == null || (sp.Line < this.BodyStartSP.Line) ||
226-
(sp.Line == this.BodyStartSP.Line && sp.Column < this.BodyStartSP.Column)
227-
) {
228-
this.BodyStartSP = sp;
229+
if (this.FileNameExt == ".cs") {
230+
foreach (CodeCoverageSequencePoint sp in this.SequencePoints) {
231+
if (sp.FileID != this.FileID) continue;
232+
if (this.BodyStartSP == null || (sp.Line < this.BodyStartSP.Line) ||
233+
(sp.Line == this.BodyStartSP.Line && sp.Column < this.BodyStartSP.Column)
234+
) {
235+
this.BodyStartSP = sp;
236+
}
229237
}
230238
}
239+
else {
240+
this.BodyStartSP = this.SequencePoints.First();
241+
}
231242
}
232243
}
233244

@@ -236,29 +247,34 @@ void getBodyStartSP() {
236247
// and lowest Offset (when duplicated bw ccrewrite)
237248
void getBodyFinalSP() {
238249
if (this.SequencePoints.Count != 0) {
239-
for (int i = this.SequencePoints.Count-1; i > 0; i--) {
240-
var sp = this.SequencePoints[i];
241-
if (sp.FileID != this.FileID) continue;
242-
if (sp.Content != "}") continue;
243-
if (this.BodyFinalSP == null || (sp.Line > this.BodyFinalSP.Line) ||
244-
(sp.Line == this.BodyFinalSP.Line && sp.Column >= this.BodyFinalSP.Column)
245-
) {
246-
// ccrewrite ContractClass/ContractClassFor
247-
// adds duplicate method end-sequence-point "}"
248-
//
249-
// Take duplicate BodyFinalSP with lower Offset
250-
// Because IL.Offset of second duplicate
251-
// will extend branch coverage of this method
252-
// by coverage of ContractClassFor inserted SequencePoint!
253-
if (this.BodyFinalSP != null &&
254-
sp.Line == this.BodyFinalSP.Line &&
255-
sp.Column == this.BodyFinalSP.Column &&
256-
sp.Offset < this.BodyFinalSP.Offset) {
257-
this.SequencePoints.Remove(this.BodyFinalSP); // remove duplicate
250+
if (this.FileNameExt == ".cs") {
251+
for (int i = this.SequencePoints.Count-1; i > 0; i--) {
252+
var sp = this.SequencePoints[i];
253+
if (sp.FileID != this.FileID) continue;
254+
if (sp.Content != "}") continue;
255+
if (this.BodyFinalSP == null || (sp.Line > this.BodyFinalSP.Line) ||
256+
(sp.Line == this.BodyFinalSP.Line && sp.Column >= this.BodyFinalSP.Column)
257+
) {
258+
// ccrewrite ContractClass/ContractClassFor
259+
// adds duplicate method end-sequence-point "}"
260+
//
261+
// Take duplicate BodyFinalSP with lower Offset
262+
// Because IL.Offset of second duplicate
263+
// will extend branch coverage of this method
264+
// by coverage of ContractClassFor inserted SequencePoint!
265+
if (this.BodyFinalSP != null &&
266+
sp.Line == this.BodyFinalSP.Line &&
267+
sp.Column == this.BodyFinalSP.Column &&
268+
sp.Offset < this.BodyFinalSP.Offset) {
269+
this.SequencePoints.Remove(this.BodyFinalSP); // remove duplicate
270+
}
271+
this.BodyFinalSP = sp;
258272
}
259-
this.BodyFinalSP = sp;
260273
}
261274
}
275+
else {
276+
this.BodyFinalSP = this.SequencePoints.Last();
277+
}
262278
}
263279
}
264280

@@ -273,6 +289,9 @@ int GetSequencePointsCount() {
273289
return 0;
274290
}
275291

292+
const string @assert = "Assert";
293+
const string @contract = "Contract";
294+
276295
void GetBranchRatio () {
277296

278297
this.BranchCoverageRatio = null;
@@ -295,31 +314,33 @@ void GetBranchRatio () {
295314
// SequencePoint is visited and belongs to this method?
296315
if (sp.VisitCount != 0 && sp.FileID == this.FileID) {
297316

298-
// Don't want branch coverage of ccrewrite(n)
299-
// SequencePoint's with offset before and after method body
300-
if (sp.Offset < BodyStartSP.Offset ||
301-
sp.Offset > BodyFinalSP.Offset) {
302-
sp.BranchCoverage = true;
303-
continue; // skip
304-
}
317+
if (this.FileNameExt == ".cs") {
318+
// Only for C#
305319

306-
// 1) Generated "in" code for IEnumerables contains hidden "try/catch/finally" branches that
307-
// one do not want or cannot cover by test-case because is handled earlier at same method.
308-
// ie: NullReferenceException in foreach loop is pre-handled at method entry, ie. by Contract.Require(items!=null)
309-
// 2) Branches within sequence points "{" and "}" are not source branches but compiler generated branches
310-
// ie: static methods start sequence point "{" contains compiler generated branches
311-
// 3) Exclude Contract class (EnsuresOnThrow/Assert/Assume is inside method body)
312-
// 4) Exclude NUnit Assert(.Throws) class
313-
const string assert = "Assert";
314-
const string contract = "Contract";
315-
if (sp.Content == "in" || sp.Content == "{" || sp.Content == "}" ||
316-
sp.Content.StartsWith(assert + ".", StringComparison.Ordinal) ||
317-
sp.Content.StartsWith(assert + " ", StringComparison.Ordinal) ||
318-
sp.Content.StartsWith(contract + ".", StringComparison.Ordinal) ||
319-
sp.Content.StartsWith(contract + " ", StringComparison.Ordinal)
320-
) {
321-
sp.BranchCoverage = true;
322-
continue; // skip
320+
// Don't want branch coverage of ccrewrite(n)
321+
// SequencePoint(s) with offset before and after method body
322+
if (sp.Offset < BodyStartSP.Offset ||
323+
sp.Offset > BodyFinalSP.Offset) {
324+
sp.BranchCoverage = true;
325+
continue; // skip
326+
}
327+
328+
// 1) Generated "in" code for IEnumerables contains hidden "try/catch/finally" branches that
329+
// one do not want or cannot cover by test-case because is handled earlier at same method.
330+
// ie: NullReferenceException in foreach loop is pre-handled at method entry, ie. by Contract.Require(items!=null)
331+
// 2) Branches within sequence points "{" and "}" are not source branches but compiler generated branches
332+
// ie: static methods start sequence point "{" contains compiler generated branches
333+
// 3) Exclude Contract class (EnsuresOnThrow/Assert/Assume is inside method body)
334+
// 4) Exclude NUnit Assert(.Throws) class
335+
if (sp.Content == "in" || sp.Content == "{" || sp.Content == "}" ||
336+
sp.Content.StartsWith(@assert + ".", StringComparison.Ordinal) ||
337+
sp.Content.StartsWith(@assert + " ", StringComparison.Ordinal) ||
338+
sp.Content.StartsWith(@contract + ".", StringComparison.Ordinal) ||
339+
sp.Content.StartsWith(@contract + " ", StringComparison.Ordinal)
340+
) {
341+
sp.BranchCoverage = true;
342+
continue; // skip
343+
}
323344
}
324345

325346
totalBranchCount += sp.BranchExitsCount;

src/AddIns/BackendBindings/CSharpBinding/Project/Src/Completion/CSharpMethodInsight.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ public CSharpMethodInsight(ITextEditor editor, int startOffset, IEnumerable<CSha
5050
public void Show()
5151
{
5252
window = editor.ShowInsightWindow(items);
53-
window.StartOffset = startOffset;
53+
// Set startOffset so that window always appears below the caret line
54+
var startLocation = editor.Document.GetLocation(startOffset);
55+
window.StartOffset = editor.Document.GetOffset(editor.Caret.Line, startLocation.Column);
5456
// closing the window at the end of the parameter list is handled by the CaretPositionChanged event
5557
window.EndOffset = editor.Document.TextLength;
5658
if (initiallySelectedItem != null)

src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/CSharpCodeGenerator.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,10 @@ public override void InsertEventHandler(ITypeDefinition target, string name, IEv
8686
var node = context.RootNode.GetNodeAt<EntityDeclaration>(last.Region.Begin);
8787
var resolver = context.GetResolverStateAfter(node);
8888
var builder = new TypeSystemAstBuilder(resolver);
89-
var delegateDecl = builder.ConvertEntity(eventDefinition.ReturnType.GetDefinition()) as DelegateDeclaration;
89+
var invokeMethod = eventDefinition.ReturnType.GetDelegateInvokeMethod();
90+
if (invokeMethod == null) return;
91+
var importedMethod = resolver.Compilation.Import(invokeMethod);
92+
var delegateDecl = builder.ConvertEntity(importedMethod) as MethodDeclaration;
9093
if (delegateDecl == null) return;
9194
var throwStmt = new ThrowStatement(new ObjectCreateExpression(context.CreateShortType("System", "NotImplementedException")));
9295
var decl = new MethodDeclaration() {
@@ -96,7 +99,7 @@ public override void InsertEventHandler(ITypeDefinition target, string name, IEv
9699
throwStmt
97100
}
98101
};
99-
var param = delegateDecl.Parameters.Select(p => p.Clone()).OfType<ParameterDeclaration>().ToArray();
102+
var param = delegateDecl.Parameters.Select(p => p.Clone()).ToArray();
100103
decl.Parameters.AddRange(param);
101104

102105
using (Script script = context.StartScript()) {

src/AddIns/DisplayBindings/ILSpyAddIn/ILSpyParser.cs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
using System.Collections.Generic;
2121
using System.Linq;
2222
using System.Reflection;
23+
using System.Text;
2324
using System.Threading;
2425
using ICSharpCode.Core;
2526
using ICSharpCode.NRefactory;
@@ -82,7 +83,32 @@ public ICodeContext ResolveContext(ParseInformation parseInfo, TextLocation loca
8283

8384
public ResolveResult ResolveSnippet(ParseInformation parseInfo, TextLocation location, string codeSnippet, ICompilation compilation, CancellationToken cancellationToken)
8485
{
85-
return null;
86+
var decompiledParseInfo = parseInfo as ILSpyFullParseInformation;
87+
if (decompiledParseInfo == null)
88+
throw new ArgumentException("ParseInfo does not have SyntaxTree");
89+
CSharpAstResolver contextResolver = new CSharpAstResolver(compilation, decompiledParseInfo.SyntaxTree, null);
90+
var node = decompiledParseInfo.SyntaxTree.GetNodeAt(location);
91+
CSharpResolver context;
92+
if (node != null)
93+
context = contextResolver.GetResolverStateAfter(node, cancellationToken);
94+
else
95+
context = new CSharpResolver(compilation);
96+
CSharpParser parser = new CSharpParser();
97+
var expr = parser.ParseExpression(codeSnippet);
98+
if (parser.HasErrors)
99+
return new ErrorResolveResult(SpecialType.UnknownType, PrintErrorsAsString(parser.Errors), TextLocation.Empty);
100+
CSharpAstResolver snippetResolver = new CSharpAstResolver(context, expr);
101+
return snippetResolver.Resolve(expr, cancellationToken);
102+
}
103+
104+
string PrintErrorsAsString(IEnumerable<Error> errors)
105+
{
106+
StringBuilder builder = new StringBuilder();
107+
108+
foreach (var error in errors)
109+
builder.AppendLine(error.Message);
110+
111+
return builder.ToString();
86112
}
87113

88114
public void FindLocalReferences(ParseInformation parseInfo, ITextSource fileContent, IVariable variable, ICompilation compilation, Action<SearchResultMatch> callback, CancellationToken cancellationToken)

src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/ModelTests.cs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,11 @@ public void AddBrushAsResource()
668668
}
669669

670670
public void AddNativeTypeAsResource(object component, string expectedXamlValue)
671+
{
672+
AddTypeAsResource(component, expectedXamlValue, "Controls0:", new string[] { "xmlns:Controls0=\"clr-namespace:System;assembly=mscorlib\""} );
673+
}
674+
675+
public void AddTypeAsResource(object component, string expectedXamlValue, string typePrefix, String[] additionalXmlns)
671676
{
672677
DesignItem textBlock = CreateCanvasContext("<TextBlock/>");
673678
DesignItem canvas = textBlock.Parent;
@@ -687,11 +692,11 @@ public void AddNativeTypeAsResource(object component, string expectedXamlValue)
687692
string typeName = component.GetType().Name;
688693

689694
string expectedXaml = "<Canvas.Resources>\n" +
690-
" <Controls0:" + typeName + " x:Key=\"res1\">" + expectedXamlValue + "</Controls0:" + typeName + ">\n" +
695+
" <" + typePrefix + typeName + " x:Key=\"res1\">" + expectedXamlValue + "</" + typePrefix + typeName + ">\n" +
691696
"</Canvas.Resources>\n" +
692697
"<TextBlock Tag=\"{StaticResource ResourceKey=res1}\" />";
693698

694-
AssertCanvasDesignerOutput(expectedXaml, textBlock.Context, "xmlns:Controls0=\"clr-namespace:System;assembly=mscorlib\"");
699+
AssertCanvasDesignerOutput(expectedXaml, textBlock.Context, additionalXmlns);
695700
AssertLog("");
696701
}
697702

@@ -736,6 +741,18 @@ public void AddInt32AsResource()
736741
const int i = 123;
737742
AddNativeTypeAsResource(i, "123");
738743
}
744+
745+
[Test]
746+
public void AddWpfEnumAsResource()
747+
{
748+
AddTypeAsResource(VerticalAlignment.Center, "Center", "", new string[0]);
749+
}
750+
751+
[Test]
752+
public void AddCustomEnumAsResource()
753+
{
754+
AddTypeAsResource(MyEnum.One, "One", "t:", new string[0]);
755+
}
739756
}
740757

741758
public class MyMultiConverter : IMultiValueConverter
@@ -760,4 +777,9 @@ public string StringProp {
760777
set { stringProp = value; }
761778
}
762779
}
780+
781+
public enum MyEnum
782+
{
783+
One, Two
784+
}
763785
}

src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ internal string GetPrefixForNamespace(string @namespace)
275275

276276
bool IsNativeType(object instance)
277277
{
278-
return instance.GetType().Assembly == typeof(String).Assembly;
278+
return instance.GetType().Assembly == typeof(String).Assembly || instance.GetType().IsEnum;
279279
}
280280
}
281281
}

src/AddIns/VersionControl/SubversionAddIn/Src/Commands/AutostartCommands.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,10 @@ void FileRenaming(object sender, FileRenamingEventArgs e)
389389
if (!AddInOptions.AutomaticallyRenameFiles) return;
390390
string fullSource = Path.GetFullPath(e.SourceFile);
391391
if (!CanBeVersionControlledFile(fullSource)) return;
392+
if (!FileHelpers.CheckRenameOrReplacePossible(e)) {
393+
e.Cancel = true;
394+
return;
395+
}
392396
try {
393397
using (SvnClientWrapper client = new SvnClientWrapper()) {
394398
SvnMessageView.HandleNotifications(client);

src/Libraries/NRefactory/ICSharpCode.NRefactory.CSharp/OutputVisitor/InsertMissingTokensDecorator.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public override void EndNode(AstNode node)
6161
public override void WriteToken(Role role, string token)
6262
{
6363
CSharpTokenNode t = new CSharpTokenNode(locationProvider.Location, (TokenRole)role);
64+
t.Role = role;
6465
EmptyStatement node = nodes.Peek().LastOrDefault() as EmptyStatement;
6566
if (node == null)
6667
currentList.Add(t);

src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@
366366
<Compile Include="Workbench\DisplayBinding\ISecondaryDisplayBinding.cs" />
367367
<Compile Include="Workbench\FakeXmlViewContent.cs" />
368368
<Compile Include="Workbench\FileChangeWatcher.cs" />
369+
<Compile Include="Workbench\File\FileHelpers.cs" />
369370
<Compile Include="Workbench\File\FileService.cs" />
370371
<Compile Include="Workbench\File\IRecentOpen.cs" />
371372
<Compile Include="Workbench\ICustomizedCommands.cs" />
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
2+
//
3+
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4+
// software and associated documentation files (the "Software"), to deal in the Software
5+
// without restriction, including without limitation the rights to use, copy, modify, merge,
6+
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7+
// to whom the Software is furnished to do so, subject to the following conditions:
8+
//
9+
// The above copyright notice and this permission notice shall be included in all copies or
10+
// substantial portions of the Software.
11+
//
12+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13+
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14+
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15+
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16+
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17+
// DEALINGS IN THE SOFTWARE.
18+
19+
using System;
20+
using System.IO;
21+
using ICSharpCode.Core;
22+
23+
namespace ICSharpCode.SharpDevelop.Workbench
24+
{
25+
/// <summary>
26+
/// Utility/helper methods for IFileService to avoid changing the IFileService interface.
27+
/// </summary>
28+
public static class FileHelpers
29+
{
30+
/// <summary>
31+
/// Checks that the rename/overwrite operation is possible.
32+
/// </summary>
33+
public static bool CheckRenameOrReplacePossible(FileRenameEventArgs e, bool replaceAllowed = false)
34+
{
35+
if (e.IsDirectory && Directory.Exists(e.SourceFile)) {
36+
if (!replaceAllowed && Directory.Exists(e.TargetFile)) {
37+
SD.MessageService.ShowMessage(StringParser.Parse("${res:Gui.ProjectBrowser.FileInUseError}"));
38+
return false;
39+
}
40+
} else if (File.Exists(e.SourceFile)) {
41+
if (!replaceAllowed && File.Exists(e.TargetFile)) {
42+
SD.MessageService.ShowMessage(StringParser.Parse("${res:Gui.ProjectBrowser.FileInUseError}"));
43+
return false;
44+
}
45+
}
46+
return true;
47+
}
48+
}
49+
}

0 commit comments

Comments
 (0)