From 515b955432857bca4570440c43a19149416ba6f3 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Tue, 13 Jun 2006 15:18:37 +0000 Subject: [PATCH] Lock access to DefaultProjectContent.ReferencedContents - can be modified by main thread and solution loading thread. git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/branches/2.0@1477 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61 --- .../Src/Output/CSharp/CSharpOutputVisitor.cs | 16 ++++++-- .../Output/CodeDOM/CodeDOMOutputVisitor.cs | 2 +- .../Src/Output/VBNet/VBNetOutputVisitor.cs | 30 ++++++++------ .../Project/Src/Parser/AST/TypeReference.cs | 2 +- .../NRefactory/Test/General/UnitTest.cs | 20 +++++++++- .../Output/CSharp/VBToCSharpConverterTest.cs | 13 ++++++ .../Test/Output/VBNet/VBNetOutputTest.cs | 31 ++++++++++++++ .../ParserService/DefaultProjectContent.cs | 40 +++++++++++-------- .../ParserService/ParseProjectContent.cs | 25 +++++++++--- .../ParserService/ReflectionProjectContent.cs | 8 +++- 10 files changed, 143 insertions(+), 44 deletions(-) diff --git a/src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs b/src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs index 8efd8c44f9..56cef63f44 100644 --- a/src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Output/CSharp/CSharpOutputVisitor.cs @@ -999,7 +999,7 @@ namespace ICSharpCode.NRefactory.PrettyPrinter outputFormatter.Indent(); } OutputModifier(localVariableDeclaration.Modifier); - nodeTracker.TrackedVisit(localVariableDeclaration.GetTypeForVariable(i), data); + nodeTracker.TrackedVisit(localVariableDeclaration.GetTypeForVariable(i) ?? new TypeReference("object"), data); outputFormatter.Space(); nodeTracker.TrackedVisit(v, data); outputFormatter.PrintToken(Tokens.Semicolon); @@ -1303,9 +1303,18 @@ namespace ICSharpCode.NRefactory.PrettyPrinter if (doLoopStatement.ConditionType == ConditionType.Until) { outputFormatter.PrintToken(Tokens.Not); + outputFormatter.PrintToken(Tokens.OpenParenthesis); } - nodeTracker.TrackedVisit(doLoopStatement.Condition, null); + if (doLoopStatement.Condition.IsNull) { + outputFormatter.PrintToken(Tokens.True); + } else { + nodeTracker.TrackedVisit(doLoopStatement.Condition, null); + } + + if (doLoopStatement.ConditionType == ConditionType.Until) { + outputFormatter.PrintToken(Tokens.CloseParenthesis); + } outputFormatter.PrintToken(Tokens.CloseParenthesis); } @@ -1321,11 +1330,10 @@ namespace ICSharpCode.NRefactory.PrettyPrinter outputFormatter.PrintToken(Tokens.Do); } - ++outputFormatter.IndentationLevel; WriteEmbeddedStatement(doLoopStatement.EmbeddedStatement); - --outputFormatter.IndentationLevel; if (doLoopStatement.ConditionPosition == ConditionPosition.End) { + outputFormatter.Indent(); PrintLoopCheck(doLoopStatement); outputFormatter.PrintToken(Tokens.Semicolon); outputFormatter.NewLine(); diff --git a/src/Libraries/NRefactory/Project/Src/Output/CodeDOM/CodeDOMOutputVisitor.cs b/src/Libraries/NRefactory/Project/Src/Output/CodeDOM/CodeDOMOutputVisitor.cs index 348170f27c..08df734e50 100644 --- a/src/Libraries/NRefactory/Project/Src/Output/CodeDOM/CodeDOMOutputVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Output/CodeDOM/CodeDOMOutputVisitor.cs @@ -287,7 +287,7 @@ namespace ICSharpCode.NRefactory.Parser CodeVariableDeclarationStatement declStmt = null; for (int i = 0; i < localVariableDeclaration.Variables.Count; ++i) { - CodeTypeReference type = ConvType(localVariableDeclaration.GetTypeForVariable(i)); + CodeTypeReference type = ConvType(localVariableDeclaration.GetTypeForVariable(i) ?? new TypeReference("object")); VariableDeclaration var = (VariableDeclaration)localVariableDeclaration.Variables[i]; if (!var.Initializer.IsNull) { declStmt = new CodeVariableDeclarationStatement(type, diff --git a/src/Libraries/NRefactory/Project/Src/Output/VBNet/VBNetOutputVisitor.cs b/src/Libraries/NRefactory/Project/Src/Output/VBNet/VBNetOutputVisitor.cs index 4bc529eea8..208d0798e2 100644 --- a/src/Libraries/NRefactory/Project/Src/Output/VBNet/VBNetOutputVisitor.cs +++ b/src/Libraries/NRefactory/Project/Src/Output/VBNet/VBNetOutputVisitor.cs @@ -488,6 +488,9 @@ namespace ICSharpCode.NRefactory.PrettyPrinter if (fieldDeclaration.Modifier == Modifier.None) { outputFormatter.PrintToken(Tokens.Private); outputFormatter.Space(); + } else if (fieldDeclaration.Modifier == Modifier.Dim) { + outputFormatter.PrintToken(Tokens.Dim); + outputFormatter.Space(); } else { OutputModifier(fieldDeclaration.Modifier); } @@ -503,13 +506,18 @@ namespace ICSharpCode.NRefactory.PrettyPrinter public object Visit(VariableDeclaration variableDeclaration, object data) { outputFormatter.PrintIdentifier(variableDeclaration.Name); - outputFormatter.Space(); - outputFormatter.PrintToken(Tokens.As); - outputFormatter.Space(); - if (variableDeclaration.TypeReference.IsNull && currentVariableType != null) { - nodeTracker.TrackedVisit(currentVariableType, data); + if (variableDeclaration.TypeReference.IsNull) { + if (currentVariableType != null && !currentVariableType.IsNull) { + outputFormatter.Space(); + outputFormatter.PrintToken(Tokens.As); + outputFormatter.Space(); + nodeTracker.TrackedVisit(currentVariableType, data); + } } else { + outputFormatter.Space(); + outputFormatter.PrintToken(Tokens.As); + outputFormatter.Space(); nodeTracker.TrackedVisit(variableDeclaration.TypeReference, data); } @@ -1440,6 +1448,8 @@ namespace ICSharpCode.NRefactory.PrettyPrinter exitTokenStack.Push(Tokens.Select); outputFormatter.PrintToken(Tokens.Select); outputFormatter.Space(); + outputFormatter.PrintToken(Tokens.Case); + outputFormatter.Space(); nodeTracker.TrackedVisit(switchStatement.SwitchExpression, data); outputFormatter.NewLine(); ++outputFormatter.IndentationLevel; @@ -1596,15 +1606,9 @@ namespace ICSharpCode.NRefactory.PrettyPrinter PrintIndentedBlock(doLoopStatement.EmbeddedStatement); outputFormatter.Indent(); - if (doLoopStatement.ConditionType == ConditionType.While) { - outputFormatter.PrintToken(Tokens.End); - outputFormatter.Space(); - outputFormatter.PrintToken(Tokens.While); - } else { - outputFormatter.PrintToken(Tokens.Loop); - } + outputFormatter.PrintToken(Tokens.Loop); - if (doLoopStatement.ConditionPosition == ConditionPosition.End) { + if (doLoopStatement.ConditionPosition == ConditionPosition.End && !doLoopStatement.Condition.IsNull) { outputFormatter.Space(); switch (doLoopStatement.ConditionType) { case ConditionType.While: diff --git a/src/Libraries/NRefactory/Project/Src/Parser/AST/TypeReference.cs b/src/Libraries/NRefactory/Project/Src/Parser/AST/TypeReference.cs index 3841c1d3e0..8fb7870885 100644 --- a/src/Libraries/NRefactory/Project/Src/Parser/AST/TypeReference.cs +++ b/src/Libraries/NRefactory/Project/Src/Parser/AST/TypeReference.cs @@ -306,7 +306,7 @@ namespace ICSharpCode.NRefactory.Parser.AST } public override object AcceptVisitor(IAstVisitor visitor, object data) { - return data; + return null; } public static NullTypeReference Instance { get { diff --git a/src/Libraries/NRefactory/Test/General/UnitTest.cs b/src/Libraries/NRefactory/Test/General/UnitTest.cs index 850505f066..e594abc308 100644 --- a/src/Libraries/NRefactory/Test/General/UnitTest.cs +++ b/src/Libraries/NRefactory/Test/General/UnitTest.cs @@ -29,11 +29,29 @@ namespace ICSharpCode.NRefactory.Tests } } + [Test] + public void TestUnitTests() + { + Type[] allTypes = typeof(StructuralTest).Assembly.GetTypes(); + + foreach (Type type in allTypes) { + if (type.GetCustomAttributes(typeof(TestFixtureAttribute), true).Length > 0) { + foreach (MethodInfo m in type.GetMethods()) { + if (m.IsPublic && m.ReturnType == typeof(void) && m.GetParameters().Length == 0) { + if (m.GetCustomAttributes(typeof(TestAttribute), true).Length == 0) { + Assert.Fail(type.Name + "." + m.Name + " should have the [Test] attribute!"); + } + } + } + } + } + } + // [Test] // public void TestAcceptVisitorMethods() // { // Type[] allTypes = typeof(AbstractNode).Assembly.GetTypes(); -// +// // foreach (Type type in allTypes) { // if (type.IsClass && !type.IsAbstract && type.GetInterface(typeof(INode).FullName) != null) { // MethodInfo methodInfo = type.GetMethod("AcceptVisitor", BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public); diff --git a/src/Libraries/NRefactory/Test/Output/CSharp/VBToCSharpConverterTest.cs b/src/Libraries/NRefactory/Test/Output/CSharp/VBToCSharpConverterTest.cs index 2388809fa2..dd738819e0 100644 --- a/src/Libraries/NRefactory/Test/Output/CSharp/VBToCSharpConverterTest.cs +++ b/src/Libraries/NRefactory/Test/Output/CSharp/VBToCSharpConverterTest.cs @@ -299,5 +299,18 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter "for (long l = 10; l >= 0; l += -1) {\n" + "}"); } + + [Test] + public void DoLoop() + { + TestStatement("Do \n Loop", + "do {\n" + + "}\n" + + "while (true);"); + TestStatement("Do \n Loop Until i = 10000", + "do {\n" + + "}\n" + + "while (!(i == 10000));"); + } } } diff --git a/src/Libraries/NRefactory/Test/Output/VBNet/VBNetOutputTest.cs b/src/Libraries/NRefactory/Test/Output/VBNet/VBNetOutputTest.cs index ecb38cd73a..b7bd58bc11 100644 --- a/src/Libraries/NRefactory/Test/Output/VBNet/VBNetOutputTest.cs +++ b/src/Libraries/NRefactory/Test/Output/VBNet/VBNetOutputTest.cs @@ -135,6 +135,37 @@ namespace ICSharpCode.NRefactory.Tests.PrettyPrinter "Next"); } + [Test] + public void DoLoop() + { + TestStatement("Do\n" + + "Loop"); + TestStatement("Do\n" + + "Loop While Not (i = 10)"); + } + + [Test] + public void SelectCase() + { + TestStatement(@"Select Case i + Case 0 + Case 1 To 4 + Case Else +End Select"); + } + + [Test] + public void UntypedVariable() + { + TestStatement("Dim x = 0"); + } + + [Test] + public void UntypedField() + { + TestTypeMember("Dim x = 0"); + } + [Test] public void Assignment() { diff --git a/src/Main/Base/Project/Src/Services/ParserService/DefaultProjectContent.cs b/src/Main/Base/Project/Src/Services/ParserService/DefaultProjectContent.cs index af61cd208a..96bad3d23f 100644 --- a/src/Main/Base/Project/Src/Services/ParserService/DefaultProjectContent.cs +++ b/src/Main/Base/Project/Src/Services/ParserService/DefaultProjectContent.cs @@ -190,10 +190,12 @@ namespace ICSharpCode.Core if (desc != null) { return desc; } - foreach (IProjectContent referencedContent in referencedContents) { - desc = referencedContent.XmlDoc.GetDocumentation(memberTag); - if (desc != null) { - return desc; + lock (referencedContents) { + foreach (IProjectContent referencedContent in referencedContents) { + desc = referencedContent.XmlDoc.GetDocumentation(memberTag); + if (desc != null) { + return desc; + } } } return null; @@ -543,13 +545,15 @@ namespace ICSharpCode.Core // Search in references: if (lookInReferences) { - foreach (IProjectContent content in referencedContents) { - IClass contentClass = content.GetClass(typeName, typeParameterCount, language, false); - if (contentClass != null) { - if (contentClass.TypeParameters.Count == typeParameterCount) { - return contentClass; - } else { - c = contentClass; + lock (referencedContents) { + foreach (IProjectContent content in referencedContents) { + IClass contentClass = content.GetClass(typeName, typeParameterCount, language, false); + if (contentClass != null) { + if (contentClass.TypeParameters.Count == typeParameterCount) { + return contentClass; + } else { + c = contentClass; + } } } } @@ -598,8 +602,10 @@ namespace ICSharpCode.Core } if (lookInReferences) { - foreach (IProjectContent content in referencedContents) { - content.AddNamespaceContents(list, nameSpace, language, false); + lock (referencedContents) { + foreach (IProjectContent content in referencedContents) { + content.AddNamespaceContents(list, nameSpace, language, false); + } } } @@ -665,9 +671,11 @@ namespace ICSharpCode.Core } if (lookInReferences) { - foreach (IProjectContent content in referencedContents) { - if (content.NamespaceExists(name, language, false)) { - return true; + lock (referencedContents) { + foreach (IProjectContent content in referencedContents) { + if (content.NamespaceExists(name, language, false)) { + return true; + } } } } diff --git a/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs b/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs index 828a1c59a4..318d8e68a8 100644 --- a/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs +++ b/src/Main/Base/Project/Src/Services/ParserService/ParseProjectContent.cs @@ -74,7 +74,11 @@ namespace ICSharpCode.Core void UpdateReferenceInterDependencies() { // Use ToArray because the collection could be modified inside the loop - foreach (IProjectContent referencedContent in this.referencedContents.ToArray()) { + IProjectContent[] referencedContents; + lock (this.referencedContents) { + referencedContents = this.referencedContents.ToArray(); + } + foreach (IProjectContent referencedContent in referencedContents) { if (referencedContent is ReflectionProjectContent) { ((ReflectionProjectContent)referencedContent).InitializeReferences(); } @@ -86,7 +90,9 @@ namespace ICSharpCode.Core try { IProjectContent referencedContent = ProjectContentRegistry.GetProjectContentForReference(reference); if (referencedContent != null) { - ReferencedContents.Add(referencedContent); + lock (this.referencedContents) { + this.referencedContents.Add(referencedContent); + } } if (updateInterDependencies) { UpdateReferenceInterDependencies(); @@ -130,7 +136,9 @@ namespace ICSharpCode.Core try { IProjectContent referencedContent = ProjectContentRegistry.GetExistingProjectContentForReference(reference); if (referencedContent != null) { - ReferencedContents.Remove(referencedContent); + lock (ReferencedContents) { + ReferencedContents.Remove(referencedContent); + } OnReferencedContentsChanged(EventArgs.Empty); } } catch (Exception ex) { @@ -192,7 +200,12 @@ namespace ICSharpCode.Core try { StatusBarService.ProgressMonitor.TaskName = "Parsing " + project.Name + "..."; - foreach (IProjectContent referencedContent in ReferencedContents) { + IProjectContent[] referencedContents; + lock (this.referencedContents) { + referencedContents = this.referencedContents.ToArray(); + } + + foreach (IProjectContent referencedContent in referencedContents) { if (referencedContent is ReflectionProjectContent) { ((ReflectionProjectContent)referencedContent).InitializeReferences(); } @@ -222,10 +235,10 @@ namespace ICSharpCode.Core initializing = false; base.Dispose(); } - + void OnEndBuild(object source, EventArgs e) { - AddComReferences(); + AddComReferences(); } void AddComReferences() diff --git a/src/Main/Base/Project/Src/Services/ParserService/ReflectionProjectContent.cs b/src/Main/Base/Project/Src/Services/ParserService/ReflectionProjectContent.cs index ce885fd7f7..09aa51a4b7 100644 --- a/src/Main/Base/Project/Src/Services/ParserService/ReflectionProjectContent.cs +++ b/src/Main/Base/Project/Src/Services/ParserService/ReflectionProjectContent.cs @@ -129,7 +129,9 @@ namespace ICSharpCode.SharpDevelop.Dom IProjectContent content = ProjectContentRegistry.GetExistingProjectContent((AssemblyName)missingNames[i]); if (content != null) { changed = true; - ReferencedContents.Add(content); + lock (ReferencedContents) { + ReferencedContents.Add(content); + } missingNames.RemoveAt(i--); } } @@ -146,7 +148,9 @@ namespace ICSharpCode.SharpDevelop.Dom IProjectContent content = ProjectContentRegistry.GetExistingProjectContent(name); if (content != null) { changed = true; - ReferencedContents.Add(content); + lock (ReferencedContents) { + ReferencedContents.Add(content); + } } else { if (missingNames == null) missingNames = new ArrayList();