diff options
Diffstat (limited to 'main')
84 files changed, 932 insertions, 1246 deletions
diff --git a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/BraceMatcher.fs b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/BraceMatcher.fs new file mode 100644 index 0000000000..06898484ea --- /dev/null +++ b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/BraceMatcher.fs @@ -0,0 +1,32 @@ +namespace MonoDevelopTests + +open NUnit.Framework +open FsUnit +open MonoDevelop.FSharp + +[<TestFixture>] +module ``Brace matcher tests`` = + let getMatchingParens (input:string) = + let offset = input.LastIndexOf "|" + if offset = -1 then + failwith "Input must contain a |" + let input = input.Remove(offset, 1) + let doc = TestHelpers.createDoc input "" + let editor = doc.Editor + editor.CaretOffset <- offset-1 + let res = + braceMatcher.getMatchingBraces doc.Editor doc (offset-1) + |> Async.RunSynchronously + res.Value + + [<Test>] + let ``should find matching left parens``() = + let source = "let square (x: int)| = x * x" + let result = getMatchingParens source + result.IsCaretInLeft |> should equal false + + [<Test>] + let ``should find matching right parens``() = + let source = "let square (|x: int) = x * x" + let result = getMatchingParens source + result.IsCaretInLeft |> should equal true diff --git a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/MonoDevelop.FSharp.Tests.fsproj b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/MonoDevelop.FSharp.Tests.fsproj index 2447755ba1..8a65cf5c53 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/MonoDevelop.FSharp.Tests.fsproj +++ b/main/external/fsharpbinding/MonoDevelop.FSharp.Tests/MonoDevelop.FSharp.Tests.fsproj @@ -215,15 +215,21 @@ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </None> <Content Include="Samples\Xamarin.iOS.fsproj" /> + <Compile Include="BraceMatcher.fs" /> </ItemGroup> <Import Project="..\.paket\paket.targets" /> <ProjectExtensions> <MonoDevelop> <Properties> <Policies> - <TextStylePolicy TabWidth="4" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" FileWidth="80" TabsToSpaces="True" scope="text/x-fsharp" /> + <TextStylePolicy TabWidth="4" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" FileWidth="80" TabsToSpaces="True" scope="text/x-fsharp"> + <inheritsSet /> + <inheritsScope /> + </TextStylePolicy> <FSharpFormattingPolicy scope="text/x-fsharp"> <DefaultFormat IndentOnTryWith="False" ReorderOpenDeclaration="False" SpaceAfterComma="True" SpaceAfterSemicolon="True" SpaceAroundDelimiter="True" SpaceBeforeArgument="True" SpaceBeforeColon="True" __added="0" /> + <inheritsSet /> + <inheritsScope /> </FSharpFormattingPolicy> <TextStylePolicy inheritsSet="null" scope="application/fsproject+xml" /> <XmlFormattingPolicy inheritsSet="null" scope="application/fsproject+xml" /> diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpBraceMatcher.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpBraceMatcher.fs index c1ee4584b3..ddfb7340f5 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpBraceMatcher.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpBraceMatcher.fs @@ -6,6 +6,39 @@ open MonoDevelop.Core.Text open MonoDevelop.Ide.Editor open Microsoft.FSharp.Compiler +module braceMatcher = + let getMatchingBraces (editor:IReadonlyTextDocument) (context:DocumentContext) caretOffset = + async { + let getOffset (range:Range.range) = + editor.LocationToOffset (range.StartLine, range.StartColumn+1) + + let projectFileName = + if isNull context.Project then + editor.FileName + else + context.Project.FileName + let location = editor.OffsetToLocation caretOffset + let range = Range.mkRange (context.Name) (Range.mkPos location.Line (location.Column-1)) (Range.mkPos location.Line location.Column) + let! braces = languageService.MatchingBraces(context.Name, projectFileName.ToString(), editor.Text) + let matching = + braces + |> Seq.tryPick + (function + | (startRange, endRange) when startRange = range -> + Some (startRange, endRange, true) + | (startRange, endRange) when endRange = range -> + Some (startRange, endRange, false) + | _ -> None) + + return + match matching with + | Some (startBrace, endBrace, isLeft) -> + let startOffset = getOffset startBrace + let endOffset = getOffset endBrace + Nullable(new BraceMatchingResult(new TextSegment(startOffset, 1), new TextSegment(endOffset, 1), isLeft)) + | None -> Nullable() + } + type FSharpBraceMatcher() = inherit AbstractBraceMatcher() let defaultMatcher = new DefaultBraceMatcher() @@ -21,37 +54,6 @@ type FSharpBraceMatcher() = match editor.GetCharAt(caretOffset), isFsi with | '(', false | ')', false -> - let computation = async { - let getOffset (range:Range.range) = - editor.LocationToOffset (range.StartLine, range.StartColumn+1) - - let projectFileName = - if isNull context.Project then - editor.FileName - else - context.Project.FileName - - let! braces = languageService.MatchingBraces(context.Name, projectFileName.ToString(), editor.Text) - let matching = - braces |> Seq.choose - (fun (startRange, endRange) -> - let startOffset = getOffset startRange - let endOffset = getOffset endRange - match (startOffset, endOffset) with - | (startOffset, endOffset) when startOffset = caretOffset - -> Some (startOffset, endOffset, true) - | (startOffset, endOffset) when endOffset = caretOffset - -> Some (startOffset, endOffset, false) - | _ -> None) - |> Seq.tryHead - - return - match matching with - | Some (startBrace, endBrace, isLeft) -> - Nullable(new BraceMatchingResult(new TextSegment(startBrace, 1), new TextSegment(endBrace, 1), isLeft)) - | None -> Nullable() - - } + let computation = braceMatcher.getMatchingBraces editor context caretOffset Async.StartAsTask (computation = computation, cancellationToken = cancellationToken) | _ -> defaultMatcher.GetMatchingBracesAsync (editor, context, caretOffset, cancellationToken) - diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpHighlightUsagesExtension.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpHighlightUsagesExtension.fs index be9a1b8fe5..728494f0fe 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpHighlightUsagesExtension.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpHighlightUsagesExtension.fs @@ -6,6 +6,7 @@ open MonoDevelop open MonoDevelop.Core open MonoDevelop.Ide open MonoDevelop.Ide.Editor.Extension +open MonoDevelop.Ide.FindInFiles open MonoDevelop.Projects open Microsoft.FSharp.Compiler.SourceCodeServices @@ -50,7 +51,16 @@ type HighlightUsagesExtension() = //TODO: Can we use the DisplayName from the symbol rather than the last element in ident islands? // If we could then we could remove the Parsing.findLongIdents in GetUsesOfSymbolAtLocationInFile. references - |> Seq.map (fun symbolUse -> NRefactory.createMemberReference(x.Editor, symbolUse, fsSymbolName)) + |> Seq.map (fun symbolUse -> + let start, finish = Symbol.trimSymbolRegion symbolUse fsSymbolName + let startOffset = x.Editor.LocationToOffset (start.Line, start.Column+1) + let endOffset = x.Editor.LocationToOffset (finish.Line, finish.Column+1) + let referenceType = + if symbolUse.IsFromDefinition then + ReferenceUsageType.Declaration + else + ReferenceUsageType.Unknown + new MemberReference (symbolUse, symbolUse.FileName, startOffset, endOffset-startOffset, ReferenceUsageType=referenceType)) | _ -> Seq.empty with diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpResolverProvider.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpResolverProvider.fs index eda9b08393..3f9b65a104 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpResolverProvider.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/FSharpResolverProvider.fs @@ -74,7 +74,7 @@ type FSharpResolverProvider() = Symbols.getTrimmedTextSpanForDeclarations lastIdent symbolUse |> Seq.map (fun (fileName, ts, ls) -> Microsoft.CodeAnalysis.Location.Create(fileName, ts, ls)) |> System.Collections.Immutable.ImmutableArray.ToImmutableArray - let roslynSymbol = Roslyn.FsharpSymbol (symbolUse, roslynLocs) + let roslynSymbol = RoslynHelpers.FsharpSymbol (symbolUse, roslynLocs) roslynSymbol :> _ | _ -> null diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/MonoDevelop.FSharp.fsproj b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/MonoDevelop.FSharp.fsproj index 61ddfb0ad8..34870659e2 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/MonoDevelop.FSharp.fsproj +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/MonoDevelop.FSharp.fsproj @@ -54,13 +54,6 @@ <FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath> </PropertyGroup> <Import Project="$(FSharpTargetsPath)" Condition="Exists('$(FSharpTargetsPath)')" /> - <Choose> - <When Condition="$(TargetFrameworkIdentifier) == '.NETFramework' And $(TargetFrameworkVersion) == 'v4.6.1'"> - <PropertyGroup> - <__paket__StrongNamer_targets>StrongNamer</__paket__StrongNamer_targets> - </PropertyGroup> - </When> - </Choose> <Target Name="BeforeBuild"> <ItemGroup> <NuGetPackage Include="FSharp.Core"> @@ -96,7 +89,7 @@ <Compile Include="Services\CompilerService.fs" /> <Compile Include="Services\FSharpConsoleView.fs" /> <Compile Include="Services\InteractiveSession.fs" /> - <Compile Include="Services\NRefactory.fs" /> + <Compile Include="Services\RoslynHelpers.fs" /> <Compile Include="FSharpParsedDocument.fs" /> <Compile Include="FSharpTokens.fs" /> <Compile Include="FSharpSymbolHelper.fs" /> @@ -169,10 +162,6 @@ <Private>False</Private> </ProjectReference> <Reference Include="monodoc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" /> - <Reference Include="ICSharpCode.NRefactory"> - <Private>False</Private> - <HintPath>..\..\..\build\bin\ICSharpCode.NRefactory.dll</HintPath> - </Reference> <ProjectReference Include="..\MonoDevelop.FSharp.Gui\MonoDevelop.FSharp.Gui.csproj"> <Project>{FD0D1033-9145-48E5-8ED8-E2365252878C}</Project> <Name>MonoDevelop.FSharp.Gui</Name> @@ -236,9 +225,14 @@ <MonoDevelop> <Properties> <Policies> - <TextStylePolicy FileWidth="80" TabWidth="4" TabsToSpaces="True" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" inheritsSet="VisualStudio" inheritsScope="text/plain" scope="text/x-fsharp" /> + <TextStylePolicy TabWidth="4" IndentWidth="4" RemoveTrailingWhitespace="True" NoTabsAfterNonTabs="False" EolMarker="Native" FileWidth="80" TabsToSpaces="True" scope="text/x-fsharp"> + <inheritsSet /> + <inheritsScope /> + </TextStylePolicy> <FSharpFormattingPolicy scope="text/x-fsharp"> - <DefaultFormat IndentOnTryWith="False" ReorderOpenDeclaration="False" SpaceAfterComma="True" SpaceAfterSemicolon="True" SpaceAroundDelimiter="True" SpaceBeforeArgument="True" SpaceBeforeColon="True" /> + <DefaultFormat IndentOnTryWith="False" ReorderOpenDeclaration="False" SpaceAfterComma="True" SpaceAfterSemicolon="True" SpaceAroundDelimiter="True" SpaceBeforeArgument="True" SpaceBeforeColon="True" __added="0" /> + <inheritsSet /> + <inheritsScope /> </FSharpFormattingPolicy> </Policies> </Properties> @@ -374,5 +368,5 @@ </ItemGroup> </When> </Choose> - <Import Project="..\packages\StrongNamer\build\$(__paket__StrongNamer_targets).targets" Condition="Exists('..\packages\StrongNamer\build\$(__paket__StrongNamer_targets).targets')" Label="Paket" /> + <Import Project="..\packages\StrongNamer\build\StrongNamer.targets" Condition="Exists('..\packages\StrongNamer\build\StrongNamer.targets')" Label="Paket" /> </Project>
\ No newline at end of file diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/NRefactory.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/NRefactory.fs deleted file mode 100644 index 6fbe679120..0000000000 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/NRefactory.fs +++ /dev/null @@ -1,240 +0,0 @@ -namespace MonoDevelop.FSharp - -open System -open System.Collections.Immutable -open MonoDevelop.Ide.FindInFiles -open ICSharpCode.NRefactory.TypeSystem -open ICSharpCode.NRefactory.TypeSystem.Implementation -open Microsoft.FSharp.Compiler.SourceCodeServices - -/// Utilities to produce NRefactory ISymbol, IEntity, IVariable etc. implementations based on FSharpSymbol -/// objects returned by FSharp.Compiler.Service. -module NRefactory = - /// If an NRefactory symbol implements this, it indicates it is associated with an FSharpSymbol from the - /// F# compiler. - type IHasFSharpSymbol = - abstract FSharpSymbol : FSharpSymbol - /// Last identifier used in the resolution that produced this symbol - abstract LastIdent : string - - /// An NRefactory symbol for an F# type definition, module or exception declaration. - type FSharpResolvedTypeDefinition(context,unresolvedTypeDef,symbol:FSharpSymbol, lastIdent) = - inherit DefaultResolvedTypeDefinition(context, [| unresolvedTypeDef |]) - - //by default the kind will always be class because unresolvedTypeDef.Kind is used in the DefaultResolvedTypeDefinition. - //The rename UI only makes a ditinction between class and interface, others such as Enum are seperate entities - override x.Kind = - match symbol with - | :? FSharpEntity as fse when fse.IsInterface -> TypeKind.Interface - | _ -> base.Kind - interface IHasFSharpSymbol with - member x.FSharpSymbol = symbol - member x.LastIdent = lastIdent - - /// An NRefactory symbol for an F# method, property or other member definition. - type FSharpResolvedMethod(unresolvedMember:DefaultUnresolvedMethod, context, symbol, lastIdent) = - inherit DefaultResolvedMethod(unresolvedMember, context) - interface IHasFSharpSymbol with - member x.FSharpSymbol = symbol - member x.LastIdent = lastIdent - - /// An NRefactory symbol for an unresolved F# method, property or other member definition. - type FSharpUnresolvedMethod(unresolvedTypeDef, name, symbol, lastIdent) = - inherit DefaultUnresolvedMethod(unresolvedTypeDef, name) - interface IHasFSharpSymbol with - member x.FSharpSymbol = symbol - member x.LastIdent = lastIdent - - /// An NRefactory symbol for a local F# symbol. - type FSharpResolvedVariable(name, region, symbol, lastIdent) as this = - interface IHasFSharpSymbol with - member x.FSharpSymbol = symbol - member x.LastIdent = lastIdent - interface ISymbol with - member x.SymbolKind = SymbolKind.Variable - member x.Name = name - member x.ToReference() = - { new ISymbolReference with - member x.Resolve(context) = this :> _} - interface IVariable with - member x.Name = name - member x.Region = region - member x.Type = (SpecialType.UnknownType :> _) - member x.IsConst = false - member x.ConstantValue = null - - /// Build an NRefactory symbol for an F# symbol. - let createSymbol (fsSymbol: FSharpSymbol, lastIdent, region) = - match fsSymbol with - - // Type Definitions, Type Abbreviations, Exception Definitions and Modules - | :? FSharpEntity as fsEntity -> - - // The accessibility used here can influence the scope of a renaming operation. - // For now we just use 'public' to rename across the whole solution (though really it will just be - // across the whole project because of the limits of the range of symbols returned by F.C.S). - let access = Accessibility.Public - - // The 'DefaultUnresolvedTypeDefinition' has an UnresolvedFile property. However it doesn't seem needed. - // let unresolvedFile = MonoDevelop.Ide.TypeSystem.DefaultParsedDocument(e.DeclarationLocation.FileName) - - // Create a resolution context for the resolved type definition. - let nsp = match fsEntity.Namespace with None -> "" | Some n -> n - let unresolvedTypeDef = DefaultUnresolvedTypeDefinition (nsp, Region=region, Name=lastIdent, Accessibility=access (* , UnresolvedFile=unresolvedFile *) ) - - // TODO: Add base type references, this will allow 'Go To Base' to work. - // It may also allow 'Find Derived Types' to work. This would require generating - // ITypeReference nodes to reference other type definitions in the assembly being edited. - // That is not easy. - // - //unresolvedTypeDef.BaseTypes <- [ for x in fsEntity.DeclaredInterfaces -> Def ] - - // Create an IUnresolveAssembly holding the type definition. - // For scripts, there is no assembly so avoid errors caused by null in XS - let assemblyFilename = - match fsEntity.Assembly.FileName with - | None -> "fakeassembly.dll" - | Some n -> n - let assemblyName = fsEntity.Assembly.QualifiedName - let unresolvedAssembly = DefaultUnresolvedAssembly(assemblyName, Location = assemblyFilename) - unresolvedAssembly.AddTypeDefinition(unresolvedTypeDef) - - // We create a fake 'Compilation' for the symbol to contain the unresolvedTypeDef - // - // TODO; this is surely not correct, we should be using the compilation retrieved from the - // appropriate document. However it doesn't seem to matter in practice. - - let comp = SimpleCompilation(unresolvedAssembly, [||]) //TODO get AssemblyReferences - - // Create a resolution context for the resolved type definition. - let resolvedAssembly = unresolvedAssembly.Resolve(comp.TypeResolveContext) - let context = SimpleTypeResolveContext(resolvedAssembly) - - // Finally, create the resolved type definition, which wraps the unresolved one - let resolvedTypeDef = FSharpResolvedTypeDefinition(context, unresolvedTypeDef, fsSymbol, lastIdent) - resolvedTypeDef :> ISymbol - - // Members, Module-defined functions and Module-defined values - | :? FSharpMemberOrFunctionOrValue as fsMember when fsMember.IsModuleValueOrMember && fsMember.CurriedParameterGroups.Count > 0 -> - - let getAssemblyFilename (assembly:FSharpAssembly) = - match assembly.FileName with - | Some name -> name - | _ -> "fakeassembly.dll" - - - // This is more or less like the case above for entities. - let access = Accessibility.Public - let nsp, name, assemblyFilename = - match fsMember.EnclosingEntitySafe with - | Some ent -> - let nsp = match ent.Namespace with None -> "" | Some n -> n - let name = ent.DisplayName - // For scripts, there is no assembly so avoid errors caused by null in XS - let assemblyFilename = getAssemblyFilename ent.Assembly - nsp, name, assemblyFilename - | _ -> "", fsMember.DisplayName, getAssemblyFilename fsMember.Assembly - - // We create a fake 'Compilation', 'TypeDefinition' and 'Assembly' for the symbol - let unresolvedTypeDef = DefaultUnresolvedTypeDefinition (nsp, name, Accessibility=access) - - // We use an IUnresolvedMethod for the symbol regardless of whether it is a property, event, - // method or function. For the operations we're implementing (Find-all references and rename refactoring) - // it doesn't seem to matter. - let unresolvedMember = FSharpUnresolvedMethod(unresolvedTypeDef, fsMember.DisplayName, fsSymbol, lastIdent, Region=region, Accessibility=access) - - let assemblyName = fsMember.Assembly.QualifiedName - let unresolvedAssembly = DefaultUnresolvedAssembly(assemblyName, Location = assemblyFilename) - - unresolvedTypeDef.Members.Add(unresolvedMember) - unresolvedAssembly.AddTypeDefinition(unresolvedTypeDef) - - // We create a fake 'Compilation' for the symbol to contain the unresolvedTypeDef - // - // TODO; this is surely not correct, we should be using the compilation retrieved from the - // appropriate document. However it doesn't seem to matter in practice. - let comp = SimpleCompilation(unresolvedAssembly, [||]) //TODO projectContent.AssemblyReferences - - // Create a resolution context for the resolved method definition. - let resolvedAssembly = unresolvedAssembly.Resolve(comp.TypeResolveContext) - let context = SimpleTypeResolveContext(resolvedAssembly) - let resolvedTypeDef = DefaultResolvedTypeDefinition(context, unresolvedTypeDef) - let context = context.WithCurrentTypeDefinition(resolvedTypeDef) - - // Finally, create the resolved method definition, which wraps the unresolved one - let resolvedMember = FSharpResolvedMethod(unresolvedMember, context, fsSymbol, lastIdent) - resolvedMember :> ISymbol - - | _ -> - // All other cases are treated as 'local variables'. This will not be renamed across files. - FSharpResolvedVariable(lastIdent, region, fsSymbol, lastIdent) :> ISymbol - - /// Create an NRefactory MemberReference for an F# symbol. - /// - /// symbolDeclLocOpt is used to modify the MemberReferences ReferenceUsageType in the case of highlight usages - let createMemberReference(doc:MonoDevelop.Ide.Editor.TextEditor, symbolUse: FSharpSymbolUse, lastIdentAtLoc:string) = - let start, finish = Symbol.trimSymbolRegion symbolUse lastIdentAtLoc - let filename = doc.FileName.ToString() - let offset = doc.LocationToOffset(start.Line, start.Column+1) - let domRegion = DomRegion(filename, start.Line, start.Column+1, finish.Line, finish.Column+1) - - let symbol = createSymbol(symbolUse.Symbol, lastIdentAtLoc, domRegion) - let memberRef = MemberReference(symbol, filename, offset, lastIdentAtLoc.Length) - - //if the current range is a symbol range and the fileNameOfRefs match change the ReferenceUsageType - if symbolUse.IsFromDefinition then - memberRef.ReferenceUsageType <- ReferenceUsageType.Write - - memberRef - - ///// Create an NRefactory ResolveResult for an F# symbol. - //let createResolveResult(doc: MonoDevelop.Ide.Gui.Document, fsSymbol: FSharpSymbol, lastIdent, region) = - // let sym = createSymbol(doc, fsSymbol, lastIdent, region) - // match sym with - // | :? IType as ty -> TypeResolveResult(ty) :> ResolveResult - // | :? IMember as memb -> - // let sym = FSharpResolvedVariable(lastIdent, region, fsSymbol, lastIdent) - // let thisRes = LocalResolveResult(sym) :> ResolveResult - // MemberResolveResult(thisRes, memb) :> ResolveResult - // | _ -> - // let sym = FSharpResolvedVariable(lastIdent, region, fsSymbol, lastIdent) - // LocalResolveResult(sym) :> ResolveResult - -module Roslyn = - - ///Barebones symbol - type FsharpSymbol (symbolUse:FSharpSymbolUse, locations) = - interface Microsoft.CodeAnalysis.ISymbol with - member x.Kind = Microsoft.CodeAnalysis.SymbolKind.Local - member x.Language = "F#" - member x.Name = symbolUse.Symbol.DisplayName - member x.MetadataName = symbolUse.Symbol.FullName - member x.ContainingSymbol = null //TODO - member x.ContainingAssembly = null //TODO - member x.ContainingModule = null //TODO - member x.ContainingType = null ////TODO for entities or functions this will be available - member x.ContainingNamespace = null //TODO - member x.IsDefinition = symbolUse.IsFromDefinition - member x.IsStatic = false //TODO - member x.IsVirtual = false //TODO - member x.IsOverride = false //TODO - member x.IsAbstract = false //TODO - member x.IsSealed = false //TODO - member x.IsExtern = false //TODO - member x.IsImplicitlyDeclared = false //TODO - member x.CanBeReferencedByName = true //TODO - member x.Locations = locations - member x.DeclaringSyntaxReferences = ImmutableArray.Empty //TODO - member x.GetAttributes () = ImmutableArray.Empty //TODO - member x.DeclaredAccessibility = Microsoft.CodeAnalysis.Accessibility.NotApplicable //TOdo - member x.OriginalDefinition = null //TODO - member x.Accept (_visitor:Microsoft.CodeAnalysis.SymbolVisitor) = () //TODO - member x.Accept<'a> (_visitor: Microsoft.CodeAnalysis.SymbolVisitor<'a>) = Unchecked.defaultof<'a> - member x.GetDocumentationCommentId () = "" //TODO - member x.GetDocumentationCommentXml (_culture, _expand, _token) = "" //TODO - member x.ToDisplayString _format = symbolUse.Symbol.DisplayName //TODO format? - member x.ToDisplayParts _format = ImmutableArray.Empty //TODO - member x.ToMinimalDisplayString (_semanticModel, _position, _format) = symbolUse.Symbol.DisplayName //TODO format? - member x.ToMinimalDisplayParts (_semanticModel, _position, _format) = ImmutableArray.Empty //TODO - member x.HasUnsupportedMetadata = false //TODO - member x.Equals (other:Microsoft.CodeAnalysis.ISymbol) = x.Equals(other) diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/RoslynHelpers.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/RoslynHelpers.fs new file mode 100644 index 0000000000..24d2c3c190 --- /dev/null +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/RoslynHelpers.fs @@ -0,0 +1,43 @@ +namespace MonoDevelop.FSharp + +open System +open System.Collections.Immutable +open Microsoft.FSharp.Compiler.SourceCodeServices + +module RoslynHelpers = + ///Barebones symbol + type FsharpSymbol (symbolUse:FSharpSymbolUse, locations) = + interface Microsoft.CodeAnalysis.ISymbol with + member x.Kind = Microsoft.CodeAnalysis.SymbolKind.Local + member x.Language = "F#" + member x.Name = symbolUse.Symbol.DisplayName + member x.MetadataName = symbolUse.Symbol.FullName + member x.ContainingSymbol = null //TODO + member x.ContainingAssembly = null //TODO + member x.ContainingModule = null //TODO + member x.ContainingType = null ////TODO for entities or functions this will be available + member x.ContainingNamespace = null //TODO + member x.IsDefinition = symbolUse.IsFromDefinition + member x.IsStatic = false //TODO + member x.IsVirtual = false //TODO + member x.IsOverride = false //TODO + member x.IsAbstract = false //TODO + member x.IsSealed = false //TODO + member x.IsExtern = false //TODO + member x.IsImplicitlyDeclared = false //TODO + member x.CanBeReferencedByName = true //TODO + member x.Locations = locations + member x.DeclaringSyntaxReferences = ImmutableArray.Empty //TODO + member x.GetAttributes () = ImmutableArray.Empty //TODO + member x.DeclaredAccessibility = Microsoft.CodeAnalysis.Accessibility.NotApplicable //TOdo + member x.OriginalDefinition = null //TODO + member x.Accept (_visitor:Microsoft.CodeAnalysis.SymbolVisitor) = () //TODO + member x.Accept<'a> (_visitor: Microsoft.CodeAnalysis.SymbolVisitor<'a>) = Unchecked.defaultof<'a> + member x.GetDocumentationCommentId () = "" //TODO + member x.GetDocumentationCommentXml (_culture, _expand, _token) = "" //TODO + member x.ToDisplayString _format = symbolUse.Symbol.DisplayName //TODO format? + member x.ToDisplayParts _format = ImmutableArray.Empty //TODO + member x.ToMinimalDisplayString (_semanticModel, _position, _format) = symbolUse.Symbol.DisplayName //TODO format? + member x.ToMinimalDisplayParts (_semanticModel, _position, _format) = ImmutableArray.Empty //TODO + member x.HasUnsupportedMetadata = false //TODO + member x.Equals (other:Microsoft.CodeAnalysis.ISymbol) = x.Equals(other) diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/TooltipHelpers.fs b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/TooltipHelpers.fs index 4e911ebb3b..6b465bf231 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/TooltipHelpers.fs +++ b/main/external/fsharpbinding/MonoDevelop.FSharpBinding/Services/TooltipHelpers.fs @@ -5,6 +5,7 @@ open System.IO open System.Text open System.Collections.Generic open System.Linq +open System.Threading open System.Xml open System.Xml.Linq open MonoDevelop.Core @@ -119,6 +120,23 @@ module TooltipsXml = |> singleOrDefault if par = null then None else Some((elementValue addStyle par).ToString()) +type FSharpXmlDocumentationProvider(xmlPath) = + inherit Microsoft.CodeAnalysis.XmlDocumentationProvider() + member x.XmlPath = xmlPath + member x.GetDocumentation documentationCommentId = + base.GetDocumentationForSymbol(documentationCommentId, Globalization.CultureInfo.CurrentCulture, CancellationToken.None) + + override x.GetSourceStream(_cancellationToken) = + new FileStream(xmlPath, FileMode.Open, FileAccess.Read) :> Stream + + override x.Equals(obj) = + obj + |> Option.tryCast<FSharpXmlDocumentationProvider> + |> Option.bind(fun d -> Some (d.XmlPath = xmlPath)) + |> Option.fill false + + override x.GetHashCode() = xmlPath.GetHashCode() + module TooltipXmlDoc = ///lru based memoize let private memoize f n = @@ -136,7 +154,7 @@ module TooltipXmlDoc = // @todo consider if this needs to be a weak table in some way let private xmlDocProvider = memoize (fun x -> - try Some (ICSharpCode.NRefactory.Documentation.XmlDocumentationProvider(x)) + try Some (FSharpXmlDocumentationProvider(x)) with exn -> None) 20u let private tryExt file ext = Option.condition File.Exists (Path.ChangeExtension(file,ext)) @@ -318,7 +336,7 @@ module TooltipFormatting = // For 'FSharpXmlDoc.XmlDocFileSignature' we can get documentation from 'xml' files, and via MonoDoc on Mono | FSharpXmlDoc.XmlDocFileSignature(file,key) -> maybe {let! docReader = TooltipXmlDoc.findXmlDocProviderForAssembly file - let doc = docReader.GetDocumentation(key) + let doc = docReader.GetDocumentation key if String.IsNullOrEmpty doc then return! None else let parameterTip = TooltipsXml.getParameterTip Styles.simpleMarkup doc paramName return! parameterTip} diff --git a/main/external/fsharpbinding/MonoDevelop.FSharpi.Service/MonoDevelop.FSharpInteractive.Service.fsproj b/main/external/fsharpbinding/MonoDevelop.FSharpi.Service/MonoDevelop.FSharpInteractive.Service.fsproj index c68841d1ad..cfda38b231 100644 --- a/main/external/fsharpbinding/MonoDevelop.FSharpi.Service/MonoDevelop.FSharpInteractive.Service.fsproj +++ b/main/external/fsharpbinding/MonoDevelop.FSharpi.Service/MonoDevelop.FSharpInteractive.Service.fsproj @@ -65,6 +65,14 @@ <Compile Include="Program.fs" /> <None Include="paket.references" /> <None Include="app.config" /> + <None Include="..\packages\FSharp.Core\lib\net45\FSharp.Core.optdata"> + <Link>FSharp.Core.optdata</Link> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> + <None Include="..\packages\FSharp.Core\lib\net45\FSharp.Core.sigdata"> + <Link>FSharp.Core.sigdata</Link> + <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> + </None> </ItemGroup> <Import Project="$(FSharpTargetsPath)" /> <Choose> diff --git a/main/external/fsharpbinding/paket.lock b/main/external/fsharpbinding/paket.lock index 58f5527689..c54da62cb5 100644 --- a/main/external/fsharpbinding/paket.lock +++ b/main/external/fsharpbinding/paket.lock @@ -2,7 +2,7 @@ FRAMEWORK: NET461 NUGET remote: https://www.nuget.org/api/v2 ExtCore (0.8.46) - FAKE (4.57.3) + FAKE (4.61.1) Fantomas (2.6.1) FSharp.Compiler.Service (>= 11.0.4) FSharp.Compiler.CodeDom (0.9.2) diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.ClassOutline/CSharpOutlineTextEditorExtension.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.ClassOutline/CSharpOutlineTextEditorExtension.cs index fb8d0f7abd..5740f2b508 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.ClassOutline/CSharpOutlineTextEditorExtension.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.ClassOutline/CSharpOutlineTextEditorExtension.cs @@ -68,7 +68,6 @@ namespace MonoDevelop.CSharp.ClassOutline TreeStore outlineTreeStore; TreeModelSort outlineTreeModelSort; Widget[] toolbarWidgets; - AstAmbience astAmbience; OutlineNodeComparer comparer; OutlineSettings settings; @@ -89,7 +88,6 @@ namespace MonoDevelop.CSharp.ClassOutline if (DocumentContext != null) DocumentContext.DocumentParsed += UpdateDocumentOutline; - astAmbience = new AstAmbience (TypeSystemService.Workspace.Options); } public override void Dispose () @@ -247,8 +245,9 @@ namespace MonoDevelop.CSharp.ClassOutline } } - void OutlineTreeTextFunc (TreeViewColumn column, CellRenderer cell, TreeModel model, TreeIter iter) + static void OutlineTreeTextFunc (TreeViewColumn column, CellRenderer cell, TreeModel model, TreeIter iter) { + var astAmbience = new AstAmbience (TypeSystemService.Workspace.Options); var txtRenderer = (CellRendererText)cell; object o = model.GetValue (iter, 0); var syntaxNode = o as SyntaxNode; diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/CSharpCompletionTextEditorExtension.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/CSharpCompletionTextEditorExtension.cs index d2b2cb44c3..8bdb0f963d 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/CSharpCompletionTextEditorExtension.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Completion/CSharpCompletionTextEditorExtension.cs @@ -115,26 +115,12 @@ namespace MonoDevelop.CSharp.Completion return "C#"; } } - - internal static Func<Microsoft.CodeAnalysis.Document, CancellationToken, Task<Microsoft.CodeAnalysis.Document>> WithFrozenPartialSemanticsAsync; + static List<CompletionData> snippets; static CSharpCompletionTextEditorExtension () { try { - var methodInfo = typeof (Microsoft.CodeAnalysis.Document).GetMethod ("WithFrozenPartialSemanticsAsync", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.InvokeMethod); - if (methodInfo == null) - LoggingService.LogError ("Error in completion set up: Document.WithFrozenPartialSemanticsAsync not found!"); - - WithFrozenPartialSemanticsAsync = delegate (Microsoft.CodeAnalysis.Document doc, CancellationToken token) { - try { - return (Task<Microsoft.CodeAnalysis.Document>)methodInfo.Invoke (doc, new object [] { token }); - } catch (TargetInvocationException ex) { - ExceptionDispatchInfo.Capture (ex.InnerException).Throw (); - return null; - } - }; - CompletionEngine.SnippetCallback = delegate (CancellationToken arg) { if (snippets != null) return Task.FromResult ((IEnumerable<CompletionData>)snippets); @@ -157,6 +143,11 @@ namespace MonoDevelop.CSharp.Completion } } + internal static Task<Document> WithFrozenPartialSemanticsAsync (Document doc, CancellationToken token)
+ {
+ return doc.WithFrozenPartialSemanticsAsync (token);
+ } + public CSharpCompletionTextEditorExtension () { try { @@ -223,12 +214,7 @@ namespace MonoDevelop.CSharp.Completion public override void Dispose () { - CancelParsedDocumentUpdate (); DocumentContext.DocumentParsed -= HandleDocumentParsed; - if (validTypeSystemSegmentTree != null) { - validTypeSystemSegmentTree.RemoveListener (); - validTypeSystemSegmentTree = null; - } base.Dispose (); } @@ -242,27 +228,8 @@ namespace MonoDevelop.CSharp.Completion return; var semanticModel = parsedDocument.GetAst<SemanticModel> (); if (semanticModel == null) - return; - CancelParsedDocumentUpdate (); - var token = documentParsedTokenSrc.Token; - Task.Run(delegate { - try { - var newTree = TypeSystemSegmentTree.Create (semanticModel, token); - if (validTypeSystemSegmentTree != null) - validTypeSystemSegmentTree.RemoveListener (); - validTypeSystemSegmentTree = newTree; - newTree.InstallListener (Editor); - if (TypeSegmentTreeUpdated != null) - TypeSegmentTreeUpdated (this, EventArgs.Empty); - } catch (OperationCanceledException) { - } - }); - } - - void CancelParsedDocumentUpdate () - { - documentParsedTokenSrc.Cancel (); - documentParsedTokenSrc = new CancellationTokenSource (); + return;
+ TypeSegmentTreeUpdated?.Invoke (this, EventArgs.Empty); } public event EventHandler TypeSegmentTreeUpdated; @@ -289,7 +256,7 @@ namespace MonoDevelop.CSharp.Completion return null; triggerWordLength = 1; } - return InternalHandleCodeCompletion (completionContext, completionChar, false, triggerWordLength, token); + return InternalHandleCodeCompletion (completionContext, triggerInfo, triggerWordLength, token); } catch (Exception e) { LoggingService.LogError ("Unexpected code completion exception." + Environment.NewLine + "FileName: " + DocumentContext.Name + Environment.NewLine + @@ -310,7 +277,7 @@ namespace MonoDevelop.CSharp.Completion if (!IsIdentifierPart (ch) && !IsIdentifierPart (ch2)) return null; try { - return InternalHandleCodeCompletion (completionContext, ch, true, triggerWordLength, token).ContinueWith (t => { + return InternalHandleCodeCompletion (completionContext, new CompletionTriggerInfo (CompletionTriggerReason.BackspaceOrDeleteCommand, ch), triggerWordLength, token).ContinueWith (t => { var result = (CompletionDataList)t.Result; if (result == null) return null; @@ -331,7 +298,7 @@ namespace MonoDevelop.CSharp.Completion } default: ch = completionContext.TriggerOffset > 0 ? Editor.GetCharAt (completionContext.TriggerOffset - 1) : '\0'; - return InternalHandleCodeCompletion (completionContext, ch, true, triggerWordLength, default (CancellationToken)); + return InternalHandleCodeCompletion (completionContext, new CompletionTriggerInfo (CompletionTriggerReason.CompletionCommand, ch), triggerWordLength, default (CancellationToken)); } } @@ -457,7 +424,7 @@ namespace MonoDevelop.CSharp.Completion } } - Task<ICompletionDataList> InternalHandleCodeCompletion (CodeCompletionContext completionContext, char completionChar, bool ctrlSpace, int triggerWordLength, CancellationToken token, bool forceSymbolCompletion = false) + Task<ICompletionDataList> InternalHandleCodeCompletion (CodeCompletionContext completionContext, CompletionTriggerInfo triggerInfo, int triggerWordLength, CancellationToken token, bool forceSymbolCompletion = false) { if (Editor.EditMode == MonoDevelop.Ide.Editor.EditMode.CursorInsertion) return Task.FromResult ((ICompletionDataList)null); @@ -474,7 +441,8 @@ namespace MonoDevelop.CSharp.Completion return Task.FromResult ((ICompletionDataList)null); return Task.Run (async delegate { try { - var partialDoc = await WithFrozenPartialSemanticsAsync (analysisDocument, token).ConfigureAwait (false); + + var partialDoc = await analysisDocument.WithFrozenPartialSemanticsAsync (token).ConfigureAwait (false); var semanticModel = await partialDoc.GetSemanticModelAsync (token).ConfigureAwait (false); var roslynCodeCompletionFactory = new RoslynCodeCompletionFactory (this, semanticModel); @@ -484,14 +452,11 @@ namespace MonoDevelop.CSharp.Completion var ctx = new ICSharpCode.NRefactory6.CSharp.CompletionContext (partialDoc, offset, semanticModel); ctx.AdditionalContextHandlers = additionalContextHandlers; - var triggerInfo = new CompletionTriggerInfo (ctrlSpace ? CompletionTriggerReason.CompletionCommand : CompletionTriggerReason.CharTyped, completionChar); var completionResult = await engine.GetCompletionDataAsync (ctx, triggerInfo, token).ConfigureAwait (false); if (completionResult == CompletionResult.Empty) - return null; - - foreach (var symbol in completionResult) { - list.Add ((Ide.CodeCompletion.CompletionData)symbol); - } + return null;
+
+ list.AddRange (completionResult.Data); if (forceSymbolCompletion || (IdeApp.Preferences.AddImportedItemsToCompletionList.Value && list.OfType<RoslynSymbolCompletionData> ().Any (cd => (cd.GetType () == typeof (RoslynSymbolCompletionData)) && (cd.Symbol is ITypeSymbol || cd.Symbol is IMethodSymbol)))) { AddImportCompletionData (completionResult, list, roslynCodeCompletionFactory, semanticModel, offset, token); @@ -502,8 +467,7 @@ namespace MonoDevelop.CSharp.Completion list.AutoSelect = completionResult.AutoSelect; list.DefaultCompletionString = completionResult.DefaultCompletionString; // list.CloseOnSquareBrackets = completionResult.CloseOnSquareBrackets; - if (ctrlSpace) - list.AutoCompleteUniqueMatch = true; + list.AutoCompleteUniqueMatch = triggerInfo.CompletionTriggerReason == CompletionTriggerReason.CompletionCommand; } catch (OperationCanceledException) { return null; } catch (AggregateException e) { @@ -710,7 +674,7 @@ namespace MonoDevelop.CSharp.Completion if (analysisDocument == null) return null; return Task.Run (async delegate { - var partialDoc = await WithFrozenPartialSemanticsAsync (analysisDocument, token); + var partialDoc = await analysisDocument.WithFrozenPartialSemanticsAsync (token); var semanticModel = await partialDoc.GetSemanticModelAsync (); var engine = new ParameterHintingEngine (MonoDevelop.Ide.TypeSystem.TypeSystemService.Workspace, new RoslynParameterHintingFactory ()); var result = await engine.GetParameterDataProviderAsync (analysisDocument, semanticModel, offset, token); @@ -749,7 +713,7 @@ namespace MonoDevelop.CSharp.Completion var caretOffset = Editor.CaretOffset; if (analysisDocument == null || startOffset > caretOffset) return -1; - var partialDoc = await WithFrozenPartialSemanticsAsync (analysisDocument, token).ConfigureAwait (false); + var partialDoc = await analysisDocument.WithFrozenPartialSemanticsAsync (token).ConfigureAwait (false); var result = await ParameterUtil.GetCurrentParameterIndex (partialDoc, startOffset, caretOffset, token).ConfigureAwait (false); return result.ParameterIndex; } @@ -1183,148 +1147,6 @@ namespace MonoDevelop.CSharp.Completion #endregion - #region TypeSystemSegmentTree - - TypeSystemSegmentTree validTypeSystemSegmentTree; - - internal class TypeSystemTreeSegment : TreeSegment - { - public SyntaxNode Entity { - get; - private set; - } - - public TypeSystemTreeSegment (int offset, int length, SyntaxNode entity) : base (offset, length) - { - this.Entity = entity; - } - } - - internal TypeSystemTreeSegment GetMemberSegmentAt (int offset) - { - TypeSystemTreeSegment result = null; - if (result == null && validTypeSystemSegmentTree != null) - result = validTypeSystemSegmentTree.GetMemberSegmentAt (offset); - return result; - } - - internal class TypeSystemSegmentTree : SegmentTree<TypeSystemTreeSegment> - { - public SyntaxNode GetMemberAt (int offset) - { - // Members don't overlap - var seg = GetSegmentsAt (offset).FirstOrDefault (); - if (seg == null) - return null; - return seg.Entity; - } - - public TypeSystemTreeSegment GetMemberSegmentAt (int offset) - { - return GetSegmentsAt (offset).LastOrDefault (); - } - - - - internal static TypeSystemSegmentTree Create (SemanticModel semanticModel, CancellationToken token) - { - var visitor = new TreeVisitor (token); - visitor.Visit (semanticModel.SyntaxTree.GetRoot ()); - return visitor.Result; - } - - class TreeVisitor : CSharpSyntaxWalker - { - readonly CancellationToken token; - public TypeSystemSegmentTree Result = new TypeSystemSegmentTree (); - - public TreeVisitor (System.Threading.CancellationToken token) - { - this.token = token; - } - - public override void VisitClassDeclaration (Microsoft.CodeAnalysis.CSharp.Syntax.ClassDeclarationSyntax node) - { - Result.Add (new TypeSystemTreeSegment (node.SpanStart, node.Span.Length, node)); - base.VisitClassDeclaration (node); - } - public override void VisitStructDeclaration (Microsoft.CodeAnalysis.CSharp.Syntax.StructDeclarationSyntax node) - { - Result.Add (new TypeSystemTreeSegment (node.SpanStart, node.Span.Length, node)); - base.VisitStructDeclaration (node); - } - - public override void VisitInterfaceDeclaration (Microsoft.CodeAnalysis.CSharp.Syntax.InterfaceDeclarationSyntax node) - { - Result.Add (new TypeSystemTreeSegment (node.SpanStart, node.Span.Length, node)); - base.VisitInterfaceDeclaration (node); - } - - public override void VisitEnumDeclaration (Microsoft.CodeAnalysis.CSharp.Syntax.EnumDeclarationSyntax node) - { - Result.Add (new TypeSystemTreeSegment (node.SpanStart, node.Span.Length, node)); - } - - public override void VisitPropertyDeclaration (Microsoft.CodeAnalysis.CSharp.Syntax.PropertyDeclarationSyntax node) - { - Result.Add (new TypeSystemTreeSegment (node.SpanStart, node.Span.Length, node)); - } - - public override void VisitMethodDeclaration (Microsoft.CodeAnalysis.CSharp.Syntax.MethodDeclarationSyntax node) - { - Result.Add (new TypeSystemTreeSegment (node.SpanStart, node.Span.Length, node)); - } - - public override void VisitConstructorDeclaration (Microsoft.CodeAnalysis.CSharp.Syntax.ConstructorDeclarationSyntax node) - { - Result.Add (new TypeSystemTreeSegment (node.SpanStart, node.Span.Length, node)); - } - - public override void VisitDestructorDeclaration (Microsoft.CodeAnalysis.CSharp.Syntax.DestructorDeclarationSyntax node) - { - Result.Add (new TypeSystemTreeSegment (node.SpanStart, node.Span.Length, node)); - } - - public override void VisitIndexerDeclaration (Microsoft.CodeAnalysis.CSharp.Syntax.IndexerDeclarationSyntax node) - { - Result.Add (new TypeSystemTreeSegment (node.SpanStart, node.Span.Length, node)); - } - - public override void VisitDelegateDeclaration (Microsoft.CodeAnalysis.CSharp.Syntax.DelegateDeclarationSyntax node) - { - Result.Add (new TypeSystemTreeSegment (node.SpanStart, node.Span.Length, node)); - } - - public override void VisitOperatorDeclaration (Microsoft.CodeAnalysis.CSharp.Syntax.OperatorDeclarationSyntax node) - { - Result.Add (new TypeSystemTreeSegment (node.SpanStart, node.Span.Length, node)); - } - - public override void VisitEventDeclaration (Microsoft.CodeAnalysis.CSharp.Syntax.EventDeclarationSyntax node) - { - Result.Add (new TypeSystemTreeSegment (node.SpanStart, node.Span.Length, node)); - } - - public override void VisitBlock (Microsoft.CodeAnalysis.CSharp.Syntax.BlockSyntax node) - { - token.ThrowIfCancellationRequested (); - } - } - - } - - public SyntaxNode GetMemberAt (int offset) - { - SyntaxNode member = null; - if (member == null && validTypeSystemSegmentTree != null) - member = validTypeSystemSegmentTree.GetMemberAt (offset); - - return member; - } - #endregion - - - [CommandHandler(RefactoryCommands.ImportSymbol)] async void ImportSymbolCommand () { @@ -1345,8 +1167,7 @@ namespace MonoDevelop.CSharp.Completion int triggerWordLength = 0; char ch = CurrentCompletionContext.TriggerOffset > 0 ? Editor.GetCharAt (CurrentCompletionContext.TriggerOffset - 1) : '\0'; - - var completionList = await InternalHandleCodeCompletion (CurrentCompletionContext, ch, true, triggerWordLength, default(CancellationToken), true); + var completionList = await InternalHandleCodeCompletion (CurrentCompletionContext, new CompletionTriggerInfo (CompletionTriggerReason.CompletionCommand, ch), triggerWordLength, default(CancellationToken), true); if (completionList != null) CompletionWindowManager.ShowWindow (this, (char)0, completionList, CompletionWidget, CurrentCompletionContext); else diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/CompletionEngine.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/CompletionEngine.cs index ff5de56ea1..c4a92d3064 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/CompletionEngine.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/CompletionEngine.cs @@ -119,7 +119,7 @@ namespace ICSharpCode.NRefactory6.CSharp.Completion } foreach (var handler in handlerList) { - if (info.CompletionTriggerReason == CompletionTriggerReason.CompletionCommand || handler.IsTriggerCharacter (text, position - 1)) { + if (info.CompletionTriggerReason == CompletionTriggerReason.CompletionCommand || info.CompletionTriggerReason == CompletionTriggerReason.BackspaceOrDeleteCommand || handler.IsTriggerCharacter (text, position - 1)) { if (await handler.IsExclusiveAsync (completionContext, ctx, info, cancellationToken)) { exclusiveHandlers.Add (handler); } else { @@ -131,7 +131,7 @@ namespace ICSharpCode.NRefactory6.CSharp.Completion } foreach (var handler in exclusiveHandlers) { - var handlerResult = handler.GetCompletionDataAsync (result, this, completionContext, info, ctx, cancellationToken).Result; + var handlerResult = await handler.GetCompletionDataAsync (result, this, completionContext, info, ctx, cancellationToken); //if (handlerResult != null) { // Console.WriteLine ("-----" + handler); // foreach (var item in handlerResult) { diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/CompletionResult.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/CompletionResult.cs index c6c2d1a2fa..9809a8e7f4 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/CompletionResult.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/CompletionResult.cs @@ -30,11 +30,12 @@ using MonoDevelop.Ide.CodeCompletion; namespace ICSharpCode.NRefactory6.CSharp.Completion { - class CompletionResult : IReadOnlyList<CompletionData> + class CompletionResult { public static readonly CompletionResult Empty = new CompletionResult (); readonly List<CompletionData> data = new List<CompletionData> (); + Dictionary<CompletionData, CompletionData> hashData = new Dictionary<CompletionData, CompletionData> (new CompletionOverloadEqualityComparer ()); public string DefaultCompletionString { get; @@ -66,52 +67,27 @@ namespace ICSharpCode.NRefactory6.CSharp.Completion internal SyntaxContext SyntaxContext; public readonly List<IMethodSymbol> PossibleDelegates = new List<IMethodSymbol>(); - - public List<CompletionData>.Enumerator GetEnumerator () - { - return data.GetEnumerator (); - } - - #region IReadOnlyList<ICompletionData> implemenation - IEnumerator<CompletionData> IEnumerable<CompletionData>.GetEnumerator () - { - return data.GetEnumerator (); - } - - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() - { - return data.GetEnumerator(); - } - - public CompletionData this[int index] { - get { - return data [index]; - } - } - - public int Count { - get { - return data.Count; - } - } - #endregion internal CompletionResult() { AutoSelect = true; AutoCompleteEmptyMatchOnCurlyBracket = true; } + + public int Count => data.Count; + + public CompletionData this[int index] => data[index]; + + public List<CompletionData>.Enumerator GetEnumerator () => data.GetEnumerator (); internal void AddData (CompletionData completionData) { - var displayText = completionData.DisplayText; - foreach (var od in data) { - if (od.IsOverload (completionData) && completionData.IsOverload (od)) { - od.AddOverload (completionData); - return; - } + if (hashData.TryGetValue (completionData, out CompletionData od)) {
+ od.AddOverload (completionData);
+ return;
} - data.Add(completionData); + hashData[completionData] = completionData; + data.Add (completionData); } internal void AddRange (IEnumerable<CompletionData> completionData) @@ -121,11 +97,19 @@ namespace ICSharpCode.NRefactory6.CSharp.Completion } } - public static CompletionResult Create(IEnumerable<CompletionData> data) - { - var result = new CompletionResult(); - result.data.AddRange(data); - return result; + internal IReadOnlyList<CompletionData> Data => data; + + class CompletionOverloadEqualityComparer : IEqualityComparer<CompletionData>
+ {
+ public bool Equals (CompletionData x, CompletionData y)
+ {
+ return x.OverloadGroupEquals (y) && y.OverloadGroupEquals(x);
+ }
+
+ public int GetHashCode (CompletionData obj)
+ {
+ return obj.GetOverloadGroupHashCode ();
+ }
} } } diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/ContextHandler/FormatItemContextHandler.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/ContextHandler/FormatItemContextHandler.cs index e59dfbb359..c37a7d2e0d 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/ContextHandler/FormatItemContextHandler.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/ContextHandler/FormatItemContextHandler.cs @@ -228,7 +228,7 @@ namespace ICSharpCode.NRefactory6.CSharp.Completion case "System.Guid": return GenerateGuidFormatitems(engine); } - return CompletionResult.Empty; + return CompletionResult.Empty.Data; } IEnumerable<CompletionData> GetFormatCompletionData(CompletionEngine engine, SemanticModel semanticModel, InvocationExpressionSyntax invocationExpression, int formatArgument, char currentChar) diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/ContextHandler/SpeculativeNameContextHandler.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/ContextHandler/SpeculativeNameContextHandler.cs index 9a0e55628b..ceaa9bd8a5 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/ContextHandler/SpeculativeNameContextHandler.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/ContextHandler/SpeculativeNameContextHandler.cs @@ -45,9 +45,10 @@ namespace ICSharpCode.NRefactory6.CSharp.Completion protected async override Task<IEnumerable<CompletionData>> GetItemsWorkerAsync (CompletionResult completionResult, CompletionEngine engine, CompletionContext completionContext, CompletionTriggerInfo info, SyntaxContext ctx, CancellationToken cancellationToken) { var tree = await completionContext.Document.GetCSharpSyntaxTreeAsync(cancellationToken).ConfigureAwait(false); - if (tree.IsInNonUserCode(completionContext.Position, cancellationToken) || - tree.IsPreProcessorDirectiveContext(completionContext.Position, cancellationToken) || - info.CompletionTriggerReason != CompletionTriggerReason.CompletionCommand) + if (tree.IsInNonUserCode (completionContext.Position, cancellationToken) || + tree.IsPreProcessorDirectiveContext (completionContext.Position, cancellationToken) || + info.CompletionTriggerReason != CompletionTriggerReason.CompletionCommand && + info.CompletionTriggerReason != CompletionTriggerReason.BackspaceOrDeleteCommand) return Enumerable.Empty<CompletionData>(); var token = tree.FindTokenOnLeftOfPosition(completionContext.Position, cancellationToken); diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/ContextHandler/XmlDocCommentContextHandler.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/ContextHandler/XmlDocCommentContextHandler.cs index a7aedc555a..024e7f337d 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/ContextHandler/XmlDocCommentContextHandler.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/Completion/ContextHandler/XmlDocCommentContextHandler.cs @@ -49,6 +49,8 @@ namespace ICSharpCode.NRefactory6.CSharp.Completion { return null; } + if (info.CompletionTriggerReason == CompletionTriggerReason.BackspaceOrDeleteCommand) + return null; var document = completionContext.Document; var position = completionContext.Position; diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/GotoDefinition/GotoDefinitionService.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/GotoDefinition/GotoDefinitionService.cs index 8e5fd10ad2..c25ac90c4d 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/GotoDefinition/GotoDefinitionService.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/GotoDefinition/GotoDefinitionService.cs @@ -62,7 +62,7 @@ namespace ICSharpCode.NRefactory6.CSharp.Features.GotoDefinition var semanticModel = await document.GetSemanticModelAsync (cancellationToken).ConfigureAwait (false); //var symbol = SymbolFinder.FindSymbolAtPosition(semanticModel, position, workspace, bindLiteralsToUnderlyingType: true, cancellationToken: cancellationToken); - var symbol = SymbolFinder.FindSymbolAtPosition (semanticModel, position, workspace, cancellationToken: cancellationToken); + var symbol = await SymbolFinder.FindSymbolAtPositionAsync (semanticModel, position, workspace, cancellationToken: cancellationToken).ConfigureAwait (false); return FindRelatedExplicitlyDeclaredSymbol (symbol, semanticModel.Compilation); } diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/ParameterHinting/ParameterHintingEngine.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/ParameterHinting/ParameterHintingEngine.cs index 6d505edcfd..058afecdfa 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/ParameterHinting/ParameterHintingEngine.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/ParameterHinting/ParameterHintingEngine.cs @@ -122,7 +122,6 @@ namespace ICSharpCode.NRefactory6.CSharp.Completion ParameterHintingResult HandleInvocationExpression(SemanticModel semanticModel, InvocationExpressionSyntax node, CancellationToken cancellationToken) { - var info = semanticModel.GetSymbolInfo (node, cancellationToken); var result = new ParameterHintingResult(node.SpanStart); var targetTypeInfo = semanticModel.GetTypeInfo (node.Expression); @@ -131,110 +130,62 @@ namespace ICSharpCode.NRefactory6.CSharp.Completion return result; } - var within = semanticModel.GetEnclosingNamedTypeOrAssembly(node.SpanStart, cancellationToken); - ITypeSymbol type; - string name = null; - bool staticLookup = false; - var ma = node.Expression as MemberAccessExpressionSyntax; - var mb = node.Expression as MemberBindingExpressionSyntax; - if (mb != null) { - info = semanticModel.GetSymbolInfo (mb, cancellationToken); - type = (info.Symbol ?? info.CandidateSymbols.FirstOrDefault ())?.ContainingType; - name = mb.Name.Identifier.ValueText; - } else if (ma != null) { - staticLookup = semanticModel.GetSymbolInfo (ma.Expression).Symbol is ITypeSymbol; - type = semanticModel.GetTypeInfo (ma.Expression).Type; - name = info.Symbol?.Name ?? ma.Name.Identifier.ValueText; - } else { - type = within as ITypeSymbol; - name = info.Symbol?.Name ?? node.Expression.ToString (); - var sym = semanticModel.GetEnclosingSymbol (node.SpanStart, cancellationToken); - staticLookup = sym.IsStatic; - } - var addedMethods = new List<IMethodSymbol> (); - var filterMethod = new HashSet<IMethodSymbol> (); - for (;type != null; type = type.BaseType) { - foreach (var method in type.GetMembers (name).OfType<IMethodSymbol> ().Concat (GetExtensionMethods(semanticModel, type, node, name, cancellationToken))) { - if (staticLookup && !method.IsStatic) - continue; - if (method.OverriddenMethod != null) - filterMethod.Add (method.OverriddenMethod); - if (filterMethod.Contains (method)) - continue; - if (addedMethods.Any (added => SignatureComparer.Instance.HaveSameSignature (method, added, true))) - continue; - if (method.IsAccessibleWithin (within)) { - if (info.Symbol != null) { - var smethod = (IMethodSymbol)info.Symbol; - if (smethod != null && smethod.OriginalDefinition == method) { - continue; - } - } - addedMethods.Add (method); - result.AddData (factory.CreateMethodDataProvider (method)); - } - } - } - if (info.Symbol != null && !addedMethods.Contains (info.Symbol)) { - if (!staticLookup || info.Symbol.IsStatic) - result.AddData (factory.CreateMethodDataProvider ((IMethodSymbol)info.Symbol)); - } - return result; - } + var within = semanticModel.GetEnclosingNamedTypeOrAssembly (node.SpanStart, cancellationToken); + if (within == null) + return result; - IEnumerable<IMethodSymbol> GetExtensionMethods (SemanticModel semanticModel, ITypeSymbol typeToExtend, InvocationExpressionSyntax node, string name, CancellationToken cancellationToken) - { - var usedNamespaces = new List<string> (); - foreach (var un in semanticModel.GetUsingNamespacesInScope (node)) { - usedNamespaces.Add (MonoDevelop.Ide.TypeSystem.NR5CompatibiltyExtensions.GetFullName (un)); + var memberGroup = semanticModel.GetMemberGroup (node.Expression, cancellationToken).OfType<IMethodSymbol> (); + var matchedMethodSymbol = semanticModel.GetSymbolInfo (node, cancellationToken).Symbol as IMethodSymbol;
+ // if the symbol could be bound, replace that item in the symbol list
+ if (matchedMethodSymbol != null && matchedMethodSymbol.IsGenericMethod) {
+ memberGroup = memberGroup.Select (m => matchedMethodSymbol.OriginalDefinition == m ? matchedMethodSymbol : m);
+ }
+
+ ITypeSymbol throughType = null;
+ if (node.Expression is MemberAccessExpressionSyntax) {
+ var throughExpression = ((MemberAccessExpressionSyntax)node.Expression).Expression;
+ var throughSymbol = semanticModel.GetSymbolInfo (throughExpression, cancellationToken).GetAnySymbol ();
+
+ // if it is via a base expression "base.", we know the "throughType" is the base class but
+ // we need to be able to tell between "base.M()" and "new Base().M()".
+ // currently, Access check methods do not differentiate between them.
+ // so handle "base." primary-expression here by nulling out "throughType"
+ if (!(throughExpression is BaseExpressionSyntax)) {
+ throughType = semanticModel.GetTypeInfo (throughExpression, cancellationToken).Type;
+ }
+
+ var includeInstance = !throughExpression.IsKind (SyntaxKind.IdentifierName) ||
+ semanticModel.LookupSymbols (throughExpression.SpanStart, name: throughSymbol.Name).Any (s => !(s is INamedTypeSymbol)) ||
+ (!(throughSymbol is INamespaceOrTypeSymbol) && semanticModel.LookupSymbols (throughExpression.SpanStart, container: throughSymbol.ContainingType).Any (s => !(s is INamedTypeSymbol)));
+
+ var includeStatic = throughSymbol is INamedTypeSymbol ||
+ (throughExpression.IsKind (SyntaxKind.IdentifierName) &&
+ semanticModel.LookupNamespacesAndTypes (throughExpression.SpanStart, name: throughSymbol.Name).Any (t => t.GetSymbolType () == throughType));
+
+ memberGroup = memberGroup.Where (m => (m.IsStatic && includeStatic) || (!m.IsStatic && includeInstance));
+ } else if (node.Expression is SimpleNameSyntax && node.IsInStaticContext ()) {
+ memberGroup = memberGroup.Where (m => m.IsStatic);
} - var enclosingNamespaceName = MonoDevelop.Ide.TypeSystem.NR5CompatibiltyExtensions.GetFullName (semanticModel.GetEnclosingNamespace (node.SpanStart, cancellationToken)); - - var stack = new Stack<INamespaceOrTypeSymbol> (); - stack.Push (semanticModel.Compilation.GlobalNamespace); - - while (stack.Count > 0) { - if (cancellationToken.IsCancellationRequested) - break; - var current = stack.Pop (); - var currentNs = current as INamespaceSymbol; - if (currentNs != null) { - - foreach (var member in currentNs.GetNamespaceMembers ()) { - var currentNsName = MonoDevelop.Ide.TypeSystem.NR5CompatibiltyExtensions.GetFullName (member); - if (usedNamespaces.Any (u => u.StartsWith (currentNsName, StringComparison.Ordinal)) || - enclosingNamespaceName == currentNsName || - (enclosingNamespaceName.StartsWith (currentNsName, StringComparison.Ordinal) && - enclosingNamespaceName [currentNsName.Length] == '.')) { - stack.Push (member); - } - } - foreach (var member in currentNs.GetTypeMembers ()) - stack.Push (member); + var methodList = memberGroup.Where (member => member.IsAccessibleWithin (within, throughType)).ToList(); - } else { - var type = (INamedTypeSymbol)current; - if (type.IsImplicitClass || type.IsScriptClass) - continue; - if (type.DeclaredAccessibility != Accessibility.Public) { - if (type.DeclaredAccessibility != Accessibility.Internal) - continue; - if (!type.IsAccessibleWithin (semanticModel.Compilation.Assembly)) - continue; - } - if (!type.MightContainExtensionMethods) - continue; - foreach (var extMethod in type.GetMembers (name).OfType<IMethodSymbol> ().Where (method => method.IsExtensionMethod)) { - if (!extMethod.IsAccessibleWithin (semanticModel.Compilation.Assembly)) - continue; - var reducedMethod = extMethod.ReduceExtensionMethod (typeToExtend); - if (reducedMethod != null) { - yield return reducedMethod; - } - } - } + memberGroup = methodList.Where (m => !IsHiddenByOtherMethod (m, methodList)); + foreach (var member in memberGroup) {
+ result.AddData (factory.CreateMethodDataProvider (member));
} + return result; + }
+
+ bool IsHiddenByOtherMethod (IMethodSymbol method, List<IMethodSymbol> methodSet)
+ {
+ foreach (var m in methodSet) {
+ if (m != method) {
+ if (m.IsMoreSpecificThan (method) == true)
+ return true;
+ }
+ }
+
+ return false;
} ParameterHintingResult HandleTypeParameterCase(SemanticModel semanticModel, SyntaxNode node, CancellationToken cancellationToken) diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/SemanticHighlighting/SemanticHighlightingVisitor.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/SemanticHighlighting/SemanticHighlightingVisitor.cs index b8d6cd0be5..34b3302672 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/SemanticHighlighting/SemanticHighlightingVisitor.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Features/SemanticHighlighting/SemanticHighlightingVisitor.cs @@ -535,15 +535,13 @@ namespace ICSharpCode.NRefactory6.CSharp.Analysis Colorize(node.Span, varKeywordTypeColor); return; } - } + }
+
+ // We don't need to lookup symbol information here, based on semantics.
var vds = node.Parent as VariableDeclarationSyntax; - if (vds != null && vds.Variables.Count == 1) {
- symbol = semanticModel.GetSymbolInfo (node, cancellationToken).Symbol; - // var sym = vds.Variables[0].Initializer != null ? vds.Variables[0].Initializer.Value as LiteralExpressionSyntax : null; - if (symbol == null || symbol.Name != "var") { - Colorize(node.Span, varKeywordTypeColor); - return; - } + if (vds != null && vds.Variables.Count == 1) { + Colorize(node.Span, varKeywordTypeColor); + return; } } diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Highlighting/HighlightUsagesExtension.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Highlighting/HighlightUsagesExtension.cs index be3485f27e..fd8caca149 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Highlighting/HighlightUsagesExtension.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Highlighting/HighlightUsagesExtension.cs @@ -155,7 +155,7 @@ namespace MonoDevelop.CSharp.Highlighting foreach (var loc in symbol.Locations) { if (loc.IsInSource && loc.SourceTree.FilePath == doc.FilePath) result.Add (new MemberReference (symbol, doc.FilePath, loc.SourceSpan.Start, loc.SourceSpan.Length) { - ReferenceUsageType = ReferenceUsageType.Declariton + ReferenceUsageType = ReferenceUsageType.Declaration }); } diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Parser/CSharpParsedDocument.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Parser/CSharpParsedDocument.cs index b1aa9f30ef..49eace75d5 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Parser/CSharpParsedDocument.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Parser/CSharpParsedDocument.cs @@ -462,37 +462,36 @@ namespace MonoDevelop.CSharp.Parser IReadOnlyList<Error> errors; SemaphoreSlim errorLock = new SemaphoreSlim (1, 1); - public override Task<IReadOnlyList<Error>> GetErrorsAsync (CancellationToken cancellationToken = default(CancellationToken)) + public override async Task<IReadOnlyList<Error>> GetErrorsAsync (CancellationToken cancellationToken = default(CancellationToken)) { var model = GetAst<SemanticModel> (); if (model == null) - return Task.FromResult (emptyErrors); + return emptyErrors; + + if (errors != null) + return errors; - if (errors == null) { - return Task.Run (async delegate { - bool locked = await errorLock.WaitAsync (Timeout.Infinite, cancellationToken).ConfigureAwait (false); + bool locked = await errorLock.WaitAsync (Timeout.Infinite, cancellationToken).ConfigureAwait (false); + try {
+ if (errors == null) {
try {
- if (errors == null) {
- try {
- errors = model
- .GetDiagnostics (null, cancellationToken)
- .Where (diag => diag.Severity == DiagnosticSeverity.Error || diag.Severity == DiagnosticSeverity.Warning)
- .Select ((Diagnostic diag) => new Error (GetErrorType (diag.Severity), diag.Id, diag.GetMessage (), GetRegion (diag)) { Tag = diag })
- .ToList ();
- } catch (OperationCanceledException) {
- errors = emptyErrors;
- } catch (Exception e) {
- LoggingService.LogError ("Error while getting diagnostics.", e);
- errors = emptyErrors;
- }
- }
- return errors; - } finally { - if (locked) - errorLock.Release ();
} - }); - } - return Task.FromResult (errors); + errors = model
+ .GetDiagnostics (null, cancellationToken)
+ .Where (diag => diag.Severity == DiagnosticSeverity.Error || diag.Severity == DiagnosticSeverity.Warning)
+ .Select ((Diagnostic diag) => new Error (GetErrorType (diag.Severity), diag.Id, diag.GetMessage (), GetRegion (diag)) { Tag = diag })
+ .ToList ();
+ } catch (OperationCanceledException) {
+ errors = emptyErrors;
+ } catch (Exception e) {
+ LoggingService.LogError ("Error while getting diagnostics.", e);
+ errors = emptyErrors;
+ }
+ } + } finally { + if (locked) + errorLock.Release ();
} + + return errors; } static DocumentRegion GetRegion (Diagnostic diagnostic) diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/CSharpFindReferencesProvider.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/CSharpFindReferencesProvider.cs index d230e2edef..1e80f6dbf0 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/CSharpFindReferencesProvider.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/CSharpFindReferencesProvider.cs @@ -228,7 +228,7 @@ namespace MonoDevelop.CSharp.Refactoring offset = projectedOffset; } var sr = new MemberReference (lookup.Symbol, fileName, offset, loc.SourceSpan.Length); - sr.ReferenceUsageType = ReferenceUsageType.Declariton; + sr.ReferenceUsageType = ReferenceUsageType.Declaration; antiDuplicatesSet.Add (sr); result.Add (sr); } diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/FindReferencesHandler.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/FindReferencesHandler.cs index 4147120c92..7d8044f33c 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/FindReferencesHandler.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp.Refactoring/FindReferencesHandler.cs @@ -66,7 +66,7 @@ namespace MonoDevelop.CSharp.Refactoring offset = projectedOffset; } var sr = new MemberReference (symbol, fileName, offset, loc.SourceSpan.Length); - sr.ReferenceUsageType = ReferenceUsageType.Declariton; + sr.ReferenceUsageType = ReferenceUsageType.Declaration; antiDuplicatesSet.Add (sr); monitor.ReportResult (sr); } diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp/AstAmbience.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp/AstAmbience.cs index 576d8c91f1..7162cd0abd 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp/AstAmbience.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp/AstAmbience.cs @@ -36,7 +36,7 @@ using Microsoft.CodeAnalysis.CSharp.Formatting; namespace MonoDevelop.CSharp { - class AstAmbience + struct AstAmbience { // OptionSet options; diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp/CSharpBraceMatcher.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp/CSharpBraceMatcher.cs index feaa639f8f..9a412ead19 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp/CSharpBraceMatcher.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp/CSharpBraceMatcher.cs @@ -57,7 +57,7 @@ namespace MonoDevelop.CSharp var analysisDocument = context.AnalysisDocument; if (analysisDocument == null) return null; - var partialDoc = await CSharpCompletionTextEditorExtension.WithFrozenPartialSemanticsAsync (analysisDocument, cancellationToken).ConfigureAwait (false); + var partialDoc = await analysisDocument.WithFrozenPartialSemanticsAsync (cancellationToken).ConfigureAwait (false); var root = await partialDoc.GetSyntaxRootAsync (cancellationToken).ConfigureAwait (false); if (offset < 0 || root.Span.End <= offset) return null; diff --git a/main/src/addins/CSharpBinding/MonoDevelop.CSharp/PathedDocumentTextEditorExtension.cs b/main/src/addins/CSharpBinding/MonoDevelop.CSharp/PathedDocumentTextEditorExtension.cs index 6febd4a3e8..b7301ee4f4 100644 --- a/main/src/addins/CSharpBinding/MonoDevelop.CSharp/PathedDocumentTextEditorExtension.cs +++ b/main/src/addins/CSharpBinding/MonoDevelop.CSharp/PathedDocumentTextEditorExtension.cs @@ -703,7 +703,7 @@ namespace MonoDevelop.CSharp SyntaxNode lastMember; string lastMemberMarkup; MonoDevelop.Projects.Project lastProject; - AstAmbience amb; + AstAmbience? amb; CancellationTokenSource src = new CancellationTokenSource (); bool caretPositionChangedSubscribed; uint updatePathTimeoutId; @@ -713,7 +713,7 @@ namespace MonoDevelop.CSharp { if (amb == null || node == null) return ""; - return amb.GetEntityMarkup (node); + return amb.Value.GetEntityMarkup (node); } diff --git a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserWidget.cs b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserWidget.cs index e19e1e6a8c..500d620447 100644 --- a/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserWidget.cs +++ b/main/src/addins/MonoDevelop.AssemblyBrowser/MonoDevelop.AssemblyBrowser/AssemblyBrowserWidget.cs @@ -54,6 +54,7 @@ using MonoDevelop.Ide.Editor; using MonoDevelop.Ide.Navigation; using MonoDevelop.Ide.Gui.Content; using System.IO; +using MonoDevelop.Core.Text; namespace MonoDevelop.AssemblyBrowser { @@ -278,19 +279,8 @@ namespace MonoDevelop.AssemblyBrowser notebook1.Page = 0; //this.searchWidget.Visible = false; - typeListStore = new Gtk.ListStore (typeof(Xwt.Drawing.Image), // type image - typeof(string), // name - typeof(string), // namespace - typeof(string), // assembly - typeof(IMember) - ); - - memberListStore = new Gtk.ListStore (typeof(Xwt.Drawing.Image), // member image - typeof(string), // name - typeof(string), // Declaring type full name - typeof(string), // assembly - typeof(IMember) - ); + resultListStore = new Gtk.ListStore (typeof(IUnresolvedEntity)); + CreateColumns (); // this.searchEntry.Changed += SearchEntryhandleChanged; this.searchTreeview.RowActivated += SearchTreeviewhandleRowActivated; @@ -362,7 +352,7 @@ namespace MonoDevelop.AssemblyBrowser { TreeIter selectedIter; if (searchTreeview.Selection.GetSelected (out selectedIter)) { - var member = (IUnresolvedEntity)(searchMode == SearchMode.Member ? memberListStore.GetValue (selectedIter, 4) : typeListStore.GetValue (selectedIter, 4)); + var member = (IUnresolvedEntity)resultListStore.GetValue (selectedIter, 0); var nav = SearchMember (member); if (nav != null) { @@ -656,14 +646,11 @@ namespace MonoDevelop.AssemblyBrowser { Type = 0, Member = 1, - Disassembler = 2, - Decompiler = 3, - TypeAndMembers = 4 + TypeAndMembers = 2 } SearchMode searchMode = SearchMode.Type; - Gtk.ListStore memberListStore; - Gtk.ListStore typeListStore; + Gtk.ListStore resultListStore; void CreateColumns () { @@ -674,26 +661,26 @@ namespace MonoDevelop.AssemblyBrowser Gtk.CellRenderer crp, crt; switch (searchMode) { case SearchMode.Member: - case SearchMode.Disassembler: - case SearchMode.Decompiler: col = new TreeViewColumn (); col.Title = GettextCatalog.GetString ("Member"); + col.FixedWidth = 400; + col.Sizing = TreeViewColumnSizing.Fixed; crp = new CellRendererImage (); crt = new Gtk.CellRendererText (); col.PackStart (crp, false); col.PackStart (crt, true); - col.AddAttribute (crp, "image", 0); - col.AddAttribute (crt, "text", 1); + col.SetCellDataFunc (crp, RenderImage); + col.SetCellDataFunc (crt, RenderText); col.SortColumnId = 1; searchTreeview.AppendColumn (col); col.Resizable = true; - col = searchTreeview.AppendColumn (GettextCatalog.GetString ("Declaring Type"), new Gtk.CellRendererText (), "text", 2); + col = searchTreeview.AppendColumn (GettextCatalog.GetString ("Declaring Type"), crt = new Gtk.CellRendererText ()); + col.FixedWidth = 300; + col.Sizing = TreeViewColumnSizing.Fixed; + col.SetCellDataFunc (crt, RenderDeclaringTypeOrNamespace); col.SortColumnId = 2; col.Resizable = true; - col = searchTreeview.AppendColumn (GettextCatalog.GetString ("Assembly"), new Gtk.CellRendererText (), "text", 3); - col.SortColumnId = 3; - col.Resizable = true; - searchTreeview.Model = memberListStore; + searchTreeview.Model = resultListStore; break; case SearchMode.TypeAndMembers: col = new TreeViewColumn (); @@ -702,21 +689,22 @@ namespace MonoDevelop.AssemblyBrowser crt = new Gtk.CellRendererText (); col.PackStart (crp, false); col.PackStart (crt, true); - col.AddAttribute (crp, "image", 0); - col.AddAttribute (crt, "text", 1); + col.SetCellDataFunc (crp, RenderImage); + col.SetCellDataFunc (crt, RenderText); col.SortColumnId = 1; searchTreeview.AppendColumn (col); + col.FixedWidth = 400; + col.Sizing = TreeViewColumnSizing.Fixed; col.Resizable = true; - col = searchTreeview.AppendColumn (GettextCatalog.GetString ("Parent"), new Gtk.CellRendererText (), "text", 2); + col = searchTreeview.AppendColumn (GettextCatalog.GetString ("Parent"), crt = new Gtk.CellRendererText ()); + col.SetCellDataFunc (crt, RenderDeclaringTypeOrNamespace); col.SortColumnId = 2; + col.FixedWidth = 300; + col.Sizing = TreeViewColumnSizing.Fixed; col.Resizable = true; - col = searchTreeview.AppendColumn (GettextCatalog.GetString ("Assembly"), new Gtk.CellRendererText (), "text", 3); - col.SortColumnId = 3; - - col.Resizable = true; - searchTreeview.Model = typeListStore; + searchTreeview.Model = resultListStore; break; case SearchMode.Type: col = new TreeViewColumn (); @@ -725,31 +713,62 @@ namespace MonoDevelop.AssemblyBrowser crt = new Gtk.CellRendererText (); col.PackStart (crp, false); col.PackStart (crt, true); - col.AddAttribute (crp, "image", 0); - col.AddAttribute (crt, "text", 1); + col.SetCellDataFunc (crp, RenderImage); + col.SetCellDataFunc (crt, RenderText); col.SortColumnId = 1; searchTreeview.AppendColumn (col); + col.FixedWidth = 400; + col.Sizing = TreeViewColumnSizing.Fixed; col.Resizable = true; - col = searchTreeview.AppendColumn (GettextCatalog.GetString ("Namespace"), new Gtk.CellRendererText (), "text", 2); + col = searchTreeview.AppendColumn (GettextCatalog.GetString ("Namespace"), crt = new Gtk.CellRendererText ()); + col.SetCellDataFunc (crt, RenderDeclaringTypeOrNamespace); col.SortColumnId = 2; + col.FixedWidth = 300; + col.Sizing = TreeViewColumnSizing.Fixed; col.Resizable = true; - - col = searchTreeview.AppendColumn (GettextCatalog.GetString ("Assembly"), new Gtk.CellRendererText (), "text", 3); - col.SortColumnId = 3; - col.Resizable = true; - searchTreeview.Model = typeListStore; + searchTreeview.Model = resultListStore; break; } } - System.ComponentModel.BackgroundWorker searchBackgoundWorker = null; + + void RenderDeclaringTypeOrNamespace (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter) + { + var ct = (Gtk.CellRendererText)cell; + var entity = tree_model.GetValue (iter, 0) as IUnresolvedEntity; + if (entity != null) { + if (entity.DeclaringTypeDefinition != null) { + ct.Text = entity.DeclaringTypeDefinition.FullName; + return; + } + ct.Text = entity.Namespace; + } + } + + void RenderText (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter) + { + var ct = (Gtk.CellRendererText)cell; + var entity = tree_model.GetValue (iter, 0) as IUnresolvedEntity; + if (entity != null) + ct.Text = entity.Name; + } + + void RenderImage (TreeViewColumn tree_column, CellRenderer cell, TreeModel tree_model, TreeIter iter) + { + var ct = (CellRendererImage)cell; + var entity = tree_model.GetValue (iter, 0) as IUnresolvedEntity; + if (entity != null) + ct.Image = ImageService.GetIcon (entity.GetStockIcon (), Gtk.IconSize.Menu); + } + + CancellationTokenSource searchTokenSource = new CancellationTokenSource (); public void StartSearch () { string query = searchentry1.Query; - if (searchBackgoundWorker != null && searchBackgoundWorker.IsBusy) - searchBackgoundWorker.CancelAsync (); - + searchTokenSource.Cancel (); + searchTokenSource = new CancellationTokenSource (); + if (string.IsNullOrEmpty (query)) { notebook1.Page = 0; return; @@ -761,12 +780,6 @@ namespace MonoDevelop.AssemblyBrowser case SearchMode.Member: IdeApp.Workbench.StatusBar.BeginProgress (GettextCatalog.GetString ("Searching member...")); break; - case SearchMode.Disassembler: - IdeApp.Workbench.StatusBar.BeginProgress (GettextCatalog.GetString ("Searching string in disassembled code...")); - break; - case SearchMode.Decompiler: - IdeApp.Workbench.StatusBar.BeginProgress (GettextCatalog.GetString ("Searching string in decompiled code...")); - break; case SearchMode.Type: IdeApp.Workbench.StatusBar.BeginProgress (GettextCatalog.GetString ("Searching type...")); break; @@ -774,213 +787,129 @@ namespace MonoDevelop.AssemblyBrowser IdeApp.Workbench.StatusBar.BeginProgress (GettextCatalog.GetString ("Searching types and members...")); break; } - memberListStore.Clear (); - typeListStore.Clear (); - - searchBackgoundWorker = new BackgroundWorker (); - searchBackgoundWorker.WorkerSupportsCancellation = true; - searchBackgoundWorker.WorkerReportsProgress = false; - searchBackgoundWorker.DoWork += SearchDoWork; - searchBackgoundWorker.RunWorkerCompleted += delegate { - searchBackgoundWorker = null; - }; - - searchBackgoundWorker.RunWorkerAsync (query); + resultListStore.Clear (); + var token = searchTokenSource.Token; + var publicOnly = PublicApiOnly; + var defArray = definitions.ToArray (); + Task.Run (delegate { + var memberList = SearchDoWork (defArray, query, publicOnly, token); + if (memberList == null || token.IsCancellationRequested) + return; + Runtime.RunInMainThread (delegate { + if (token.IsCancellationRequested) + return; + var updater = new Updater (this, memberList, token); + updater.Update (); + }); + }); } - - void SearchDoWork (object sender, DoWorkEventArgs e) + + class Updater { - var publicOnly = PublicApiOnly; - BackgroundWorker worker = sender as BackgroundWorker; - try { - string pattern = e.Argument.ToString (); - int types = 0, curType = 0; - foreach (var unit in this.definitions) { - types += unit.UnresolvedAssembly.TopLevelTypeDefinitions.Count (); + readonly AssemblyBrowserWidget assemblyBrowserWidget; + readonly List<IUnresolvedEntity> memberList; + readonly CancellationToken token; + int i = 0; + + public Updater (AssemblyBrowserWidget assemblyBrowserWidget, List<IUnresolvedEntity> memberList, CancellationToken token) + { + this.assemblyBrowserWidget = assemblyBrowserWidget; + this.memberList = memberList; + this.token = token; + } + + public void Update () + { + GLib.Idle.Add (IdleHandler); + } + + bool IdleHandler () + { + if (token.IsCancellationRequested || i >= memberList.Count) { + IdeApp.Workbench.StatusBar.EndProgress (); + IdeApp.Workbench.StatusBar.ShowReady (); + return false; } - var memberDict = new Dictionary<AssemblyLoader, List<IUnresolvedMember>> (); - switch (searchMode) { - case SearchMode.Member: - foreach (var unit in this.definitions) { - var members = new List<IUnresolvedMember> (); - foreach (var type in unit.UnresolvedAssembly.TopLevelTypeDefinitions) { - if (worker.CancellationPending) - return; - if (!type.IsPublic && publicOnly) + + assemblyBrowserWidget.searchTreeview.FreezeChildNotify (); + for (int j = 0; j < 100 && i < memberList.Count; j++) { + assemblyBrowserWidget.resultListStore.AppendValues (memberList [i++]); + } + assemblyBrowserWidget.searchTreeview.ThawChildNotify (); + return true; + } + } + + List<IUnresolvedEntity> SearchDoWork (AssemblyLoader[] definitions, string pattern, bool publicOnly, CancellationToken cancellationToken) + { + var result = new List<IUnresolvedEntity> (); + int types = 0, curType = 0; + foreach (var unit in definitions) { + types += unit.UnresolvedAssembly.TopLevelTypeDefinitions.Count (); + } + var matcher = StringMatcher.GetMatcher (pattern, true); + + switch (searchMode) { + case SearchMode.Member: + foreach (var unit in definitions) { + foreach (var type in unit.UnresolvedAssembly.TopLevelTypeDefinitions) { + if (cancellationToken.IsCancellationRequested) + return null; + if (!type.IsPublic && publicOnly) + continue; + curType++; + foreach (var member in type.Members) { + if (cancellationToken.IsCancellationRequested) + return null; + if (!member.IsPublic && publicOnly) continue; - curType++; - foreach (var member in type.Members) { - if (worker.CancellationPending) - return; - if (!member.IsPublic && publicOnly) - continue; - if (member.Name.IndexOf (pattern, StringComparison.OrdinalIgnoreCase) != -1) { - members.Add (member); - } - } - } - memberDict [unit] = members; - } - Gtk.Application.Invoke (delegate { - IdeApp.Workbench.StatusBar.SetProgressFraction ((double)curType / types); - foreach (var kv in memberDict) { - foreach (var member in kv.Value) { - if (worker.CancellationPending) - return; - memberListStore.AppendValues (ImageService.GetIcon (member.GetStockIcon (), Gtk.IconSize.Menu), - member.Name, - member.DeclaringTypeDefinition.FullName, - kv.Key.Assembly.FullName, - member); - } - } - } - ); - break; - case SearchMode.Disassembler: - Gtk.Application.Invoke (delegate { - IdeApp.Workbench.StatusBar.BeginProgress (GettextCatalog.GetString ("Searching string in disassembled code...")); - } - ); - foreach (var unit in this.definitions) { - foreach (var type in unit.UnresolvedAssembly.TopLevelTypeDefinitions) { - if (worker.CancellationPending) - return; - curType++; - foreach (var method in type.Methods) { - if (worker.CancellationPending) - return; -// if (DomMethodNodeBuilder.Disassemble (rd => rd.DisassembleMethod (method)).ToUpper ().Contains (pattern)) { -// members.Add (method); -// } - } - } - } - Gtk.Application.Invoke (delegate { - IdeApp.Workbench.StatusBar.SetProgressFraction ((double)curType / types); - foreach (var kv in memberDict) { - foreach (var member in kv.Value) { - if (worker.CancellationPending) - return; - memberListStore.AppendValues ("", //iImageService.GetIcon (member.StockIcon, Gtk.IconSize.Menu), - member.Name, - member.DeclaringTypeDefinition.FullName, - kv.Key.Assembly.FullName, - member); + if (matcher.IsMatch (member.Name)) { + result.Add (member); } } } - ); - break; - case SearchMode.Decompiler: - foreach (var unit in this.definitions) { - foreach (var type in unit.UnresolvedAssembly.TopLevelTypeDefinitions) { - if (worker.CancellationPending) - return; - curType++; - foreach (var method in type.Methods) { - if (worker.CancellationPending) - return; -/* if (DomMethodNodeBuilder.Decompile (domMethod, false).ToUpper ().Contains (pattern)) { - members.Add (method);*/ - } - } - } - Gtk.Application.Invoke (delegate { - IdeApp.Workbench.StatusBar.SetProgressFraction ((double)curType / types); - foreach (var kv in memberDict) { - foreach (var member in kv.Value) { - if (worker.CancellationPending) - return; - memberListStore.AppendValues ("", //ImageService.GetIcon (member.StockIcon, Gtk.IconSize.Menu), - member.Name, - member.DeclaringTypeDefinition.FullName, - kv.Key.Assembly.FullName, - member); - } - } + } + + break; + case SearchMode.Type: + foreach (var unit in definitions) { + var typeList = new List<IUnresolvedTypeDefinition> (); + foreach (var type in unit.UnresolvedAssembly.TopLevelTypeDefinitions) { + if (cancellationToken.IsCancellationRequested) + return null; + if (!type.IsPublic && publicOnly) + continue; + if (matcher.IsMatch (type.FullName)) + result.Add (type); } - ); - break; - case SearchMode.Type: - var typeDict = new Dictionary<AssemblyLoader, List<IUnresolvedTypeDefinition>> (); - foreach (var unit in this.definitions) { - var typeList = new List<IUnresolvedTypeDefinition> (); - foreach (var type in unit.UnresolvedAssembly.TopLevelTypeDefinitions) { - if (worker.CancellationPending) - return; - if (!type.IsPublic && publicOnly) + } + break; + case SearchMode.TypeAndMembers: + foreach (var unit in definitions) { + foreach (var type in unit.UnresolvedAssembly.TopLevelTypeDefinitions) { + if (cancellationToken.IsCancellationRequested) + return null; + if (!type.IsPublic && publicOnly) + continue; + var parent = type.FullName; + if (matcher.IsMatch (parent)) + result.Add (type); + + foreach (var member in type.Members) { + if (cancellationToken.IsCancellationRequested) + return null; + if (!member.IsPublic && publicOnly) continue; - if (type.FullName.ToUpper ().IndexOf (pattern, StringComparison.Ordinal) >= 0) - typeList.Add (type); - } - typeDict [unit] = typeList; - } - Gtk.Application.Invoke (delegate { - foreach (var kv in typeDict) { - foreach (var type in kv.Value) { - if (worker.CancellationPending) - return; - typeListStore.AppendValues (ImageService.GetIcon (type.GetStockIcon (), Gtk.IconSize.Menu), - type.Name, - type.Namespace, - kv.Key.Assembly.FullName, - type); - } + if (matcher.IsMatch (member.Name)) + result.Add (member); } - }); - - break; - case SearchMode.TypeAndMembers: - var typeDict2 = new Dictionary<AssemblyLoader, List<Tuple<IUnresolvedEntity, string>>> (); - foreach (var unit in this.definitions) { - var typeList = new List<Tuple<IUnresolvedEntity, string>> (); - foreach (var type in unit.UnresolvedAssembly.TopLevelTypeDefinitions) { - if (worker.CancellationPending) - return; - if (!type.IsPublic && publicOnly) - continue; - var parent = type.FullName; - if (parent.IndexOf (pattern, StringComparison.OrdinalIgnoreCase) >= 0) - typeList.Add (Tuple.Create ((IUnresolvedEntity)type, type.Namespace)); - - foreach (var member in type.Members) { - if (worker.CancellationPending) - return; - if (!member.IsPublic && publicOnly) - continue; - if (member.Name.IndexOf (pattern, StringComparison.OrdinalIgnoreCase) != -1) { - typeList.Add (Tuple.Create ((IUnresolvedEntity)member, parent)); - } - } - } - typeDict2 [unit] = typeList; } - - Gtk.Application.Invoke (delegate { - foreach (var kv in typeDict2) { - foreach (var tuple in kv.Value) { - if (worker.CancellationPending) - return; - var type = tuple.Item1; - typeListStore.AppendValues (ImageService.GetIcon (type.GetStockIcon (), Gtk.IconSize.Menu), - type.Name, - tuple.Item2, - kv.Key.Assembly.FullName, - type); - } - } - }); - - break; } - } finally { - Gtk.Application.Invoke (delegate { - IdeApp.Workbench.StatusBar.EndProgress (); - IdeApp.Workbench.StatusBar.ShowReady (); - }); + break; } + + return result; } static bool preformat = false; @@ -1484,12 +1413,8 @@ namespace MonoDevelop.AssemblyBrowser protected override void OnDestroyed () { ClearReferenceSegment (); - if (searchBackgoundWorker != null && searchBackgoundWorker.IsBusy) { - searchBackgoundWorker.CancelAsync (); - searchBackgoundWorker.Dispose (); - searchBackgoundWorker = null; - } - + searchTokenSource.Cancel (); + if (this.TreeView != null) { // Dispose (TreeView.GetRootNode ()); TreeView.SelectionChanged -= HandleCursorChanged; @@ -1505,8 +1430,7 @@ namespace MonoDevelop.AssemblyBrowser } ActiveMember = null; - memberListStore = null; - typeListStore = null; + resultListStore = null; if (documentationPanel != null) { documentationPanel.Destroy (); diff --git a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeDebuggerSession.cs b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeDebuggerSession.cs index f141f89b7c..eb01340c05 100644 --- a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeDebuggerSession.cs +++ b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VSCodeDebuggerSession.cs @@ -87,12 +87,10 @@ namespace MonoDevelop.Debugger.VsCodeDebugProtocol var threadsResponse = protocolClient.SendRequestSync (new ThreadsRequest ()); var threads = new ThreadInfo [threadsResponse.Threads.Count]; for (int i = 0; i < threads.Length; i++) { - var backtrace = this.GetThreadBacktrace (threadsResponse.Threads [i].Id); threads [i] = new ThreadInfo (processId, - threadsResponse.Threads [i].Id, + threadsResponse.Threads [i].Id, threadsResponse.Threads [i].Name, - backtrace.FrameCount > 0 ? backtrace.GetFrame (0).ToString () : "", - backtrace); + null); } return threads; } @@ -280,8 +278,8 @@ namespace MonoDevelop.Debugger.VsCodeDebugProtocol } currentThreadId = body.ThreadId ?? -1; //TODO: what happens if thread is not specified? - args.Process = OnGetProcesses () [0]; - args.Thread = GetThread (args.Process, (long)body.ThreadId); + args.Process = GetProcesses () [0]; + args.Thread = args.Process.GetThreads ().Single (t => t.Id == currentThreadId); args.Backtrace = args.Thread.Backtrace; OnTargetEvent (args); @@ -312,15 +310,6 @@ namespace MonoDevelop.Debugger.VsCodeDebugProtocol }); } - ThreadInfo GetThread (ProcessInfo process, long threadId) - { - foreach (var threadInfo in OnGetThreads (process.Id)) { - if (threadInfo.Id == threadId) - return threadInfo; - } - return null; - } - List<string> pathsWithBreakpoints = new List<string> (); void UpdateBreakpoints () diff --git a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeObjectSource.cs b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeObjectSource.cs index 418e302312..d61f6f3627 100644 --- a/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeObjectSource.cs +++ b/main/src/addins/MonoDevelop.Debugger.VSCodeDebugProtocol/MonoDevelop.Debugger.VsCodeDebugProtocol/VsCodeObjectSource.cs @@ -22,7 +22,7 @@ namespace MonoDevelop.Debugger.VsCodeDebugProtocol public VSCodeObjectSource (VSCodeDebuggerSession vsCodeDebuggerSession, int variablesReference, int parentVariablesReference, string name, string type, string evalName, int frameId, string val) { - this.type = type; + this.type = type ?? string.Empty; this.frameId = frameId; this.evalName = evalName; this.name = name; @@ -84,17 +84,11 @@ namespace MonoDevelop.Debugger.VsCodeDebugProtocol public ObjectValue GetValue (ObjectPath path, EvaluationOptions options) { - string shortName = name; - var indexOfSpace = name.IndexOf (' '); - if (indexOfSpace != -1)//Remove " [TypeName]" from variable name - shortName = name.Remove (indexOfSpace); - if (type == null) - return ObjectValue.CreateError (null, new ObjectPath (shortName), "", val, ObjectValueFlags.None); if (val == "null") - return ObjectValue.CreateNullObject (this, shortName, type, parentVariablesReference > 0 ? ObjectValueFlags.None : ObjectValueFlags.ReadOnly); + return ObjectValue.CreateNullObject (this, name, type, parentVariablesReference > 0 ? ObjectValueFlags.None : ObjectValueFlags.ReadOnly); if (variablesReference == 0)//This is some kind of primitive... - return ObjectValue.CreatePrimitive (this, new ObjectPath (shortName), type, new EvaluationResult (val), parentVariablesReference > 0 ? ObjectValueFlags.None : ObjectValueFlags.ReadOnly); - return ObjectValue.CreateObject (this, new ObjectPath (shortName), type, new EvaluationResult (val), parentVariablesReference > 0 ? ObjectValueFlags.None : ObjectValueFlags.ReadOnly, null); + return ObjectValue.CreatePrimitive (this, new ObjectPath (name), type, new EvaluationResult (val), parentVariablesReference > 0 ? ObjectValueFlags.None : ObjectValueFlags.ReadOnly); + return ObjectValue.CreateObject (this, new ObjectPath (name), type, new EvaluationResult (val), parentVariablesReference > 0 ? ObjectValueFlags.None : ObjectValueFlags.ReadOnly, null); } public void SetRawValue (ObjectPath path, object value, EvaluationOptions options) diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionEditorExtension.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionEditorExtension.cs index d48ee28be4..6de7886776 100644 --- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionEditorExtension.cs +++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeActionEditorExtension.cs @@ -82,7 +82,6 @@ namespace MonoDevelop.CodeActions CancelQuickFixTimer (); RefactoringPreviewTooltipWindow.HidePreviewTooltip (); Editor.CaretPositionChanged -= HandleCaretPositionChanged; - Editor.SelectionChanged -= HandleSelectionChanged; DocumentContext.DocumentParsed -= HandleDocumentDocumentParsed; Editor.MouseMoved -= HandleBeginHover; Editor.TextChanged -= Editor_TextChanged; @@ -162,7 +161,11 @@ namespace MonoDevelop.CodeActions return CodeActionContainer.Empty; var provider = cfp.GetCodeFixProvider (); if (!provider.FixableDiagnosticIds.Any (diagnosticIds.Contains)) - continue; + continue;
+
+ // These two delegates were factored out, as using them as lambdas in the inner loop creates more captures than declaring them here.
+ Func<Diagnostic, bool> providerIdsContain = d => provider.FixableDiagnosticIds.Contains (d.Id); + Action<Microsoft.CodeAnalysis.CodeActions.CodeAction, ImmutableArray<Diagnostic>> codeFixRegistration = (ca, d) => codeIssueFixes.Add (new ValidCodeDiagnosticAction (cfp, ca, d, d[0].Location.SourceSpan)); try { var groupedDiagnostics = diagnosticsAtCaret .Concat (errorList.Select (em => em.Error.Tag) @@ -173,12 +176,12 @@ namespace MonoDevelop.CodeActions return CodeActionContainer.Empty; var diagnosticSpan = g.Key; - var validDiagnostics = g.Where (d => provider.FixableDiagnosticIds.Contains (d.Id)).ToImmutableArray (); + var validDiagnostics = g.Where (providerIdsContain).ToImmutableArray (); if (validDiagnostics.Length == 0) continue; if (diagnosticSpan.Start < 0 || diagnosticSpan.End > root.Span.End) continue; - await provider.RegisterCodeFixesAsync (new CodeFixContext (ad, diagnosticSpan, validDiagnostics, (ca, d) => codeIssueFixes.Add (new ValidCodeDiagnosticAction (cfp, ca, validDiagnostics, diagnosticSpan)), token)); + await provider.RegisterCodeFixesAsync (new CodeFixContext (ad, diagnosticSpan, validDiagnostics, codeFixRegistration, token)); // TODO: Is that right ? Currently it doesn't really make sense to run one code fix provider on several overlapping diagnostics at the same location // However the generate constructor one has that case and if I run it twice the same code action is generated twice. So there is a dupe check problem there. @@ -374,7 +377,6 @@ namespace MonoDevelop.CodeActions { base.Initialize (); DocumentContext.DocumentParsed += HandleDocumentDocumentParsed; - Editor.SelectionChanged += HandleSelectionChanged; Editor.MouseMoved += HandleBeginHover; Editor.CaretPositionChanged += HandleCaretPositionChanged; Editor.TextChanged += Editor_TextChanged; @@ -384,7 +386,6 @@ namespace MonoDevelop.CodeActions void Editor_EndAtomicUndoOperation (object sender, EventArgs e) { RemoveWidget (); - HandleCaretPositionChanged (null, EventArgs.Empty); } void Editor_TextChanged (object sender, MonoDevelop.Core.Text.TextChangeEventArgs e) @@ -400,11 +401,6 @@ namespace MonoDevelop.CodeActions CancelSmartTagPopupTimeout (); } - void HandleSelectionChanged (object sender, EventArgs e) - { - HandleCaretPositionChanged (null, EventArgs.Empty); - } - void HandleDocumentDocumentParsed (object sender, EventArgs e) { HandleCaretPositionChanged (null, EventArgs.Empty); diff --git a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeRefactoringService.cs b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeRefactoringService.cs index c738ec0eae..cb53d0a708 100644 --- a/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeRefactoringService.cs +++ b/main/src/addins/MonoDevelop.Refactoring/MonoDevelop.CodeActions/CodeRefactoringService.cs @@ -99,8 +99,12 @@ namespace MonoDevelop.CodeActions var parsedDocument = doc.ParsedDocument; var actions = new List<ValidCodeAction> (); if (parsedDocument == null) + return actions;
+ var analysisDocument = doc.AnalysisDocument; + if (analysisDocument == null) return actions; - var model = await doc.AnalysisDocument.GetSemanticModelAsync (cancellationToken); + + var model = await analysisDocument.GetSemanticModelAsync (cancellationToken); if (model == null) return actions; var root = await model.SyntaxTree.GetRootAsync (cancellationToken).ConfigureAwait (false); @@ -117,7 +121,6 @@ namespace MonoDevelop.CodeActions foreach (var descriptor in codeRefactoringCache) { if (!descriptor.IsEnabled) continue; - var analysisDocument = doc.AnalysisDocument; if (cancellationToken.IsCancellationRequested || analysisDocument == null) return Enumerable.Empty<ValidCodeAction> (); try { diff --git a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs index c970d1e4a4..9a261c644e 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/Mono.TextEditor/Gui/TextViewMargin.cs @@ -984,7 +984,7 @@ namespace Mono.TextEditor } char[] lineChars = lineText.ToCharArray (); //int startOffset = offset, endOffset = offset + length; - uint curIndex = 0; + uint curIndex = 0, byteIndex = 0; uint curChunkIndex = 0, byteChunkIndex = 0; uint oldEndIndex = 0; @@ -1000,7 +1000,7 @@ namespace Mono.TextEditor disableHighlighting = true; atts.Dispose (); atts = new FastPangoAttrList (); - curIndex = 0; + curIndex = byteIndex = 0; curChunkIndex = byteChunkIndex = 0; oldEndIndex = 0; goto restart; @@ -1024,8 +1024,8 @@ namespace Mono.TextEditor if (textEditor.preeditOffset < end) end += (int)preeditLength; } - var si = TranslateToUTF8Index (lineChars, (uint)(startIndex + start - chunk.Offset), ref curIndex); - var ei = TranslateToUTF8Index (lineChars, (uint)(startIndex + end - chunk.Offset), ref curIndex); + var si = TranslateToUTF8Index (lineChars, (uint)(startIndex + start - chunk.Offset), ref curIndex, ref byteIndex); + var ei = TranslateToUTF8Index (lineChars, (uint)(startIndex + end - chunk.Offset), ref curIndex, ref byteIndex); var color = (Cairo.Color)EditorTheme.GetForeground (chunkStyle); foreach (var marker in markers) { var chunkMarker = marker as IChunkMarker; @@ -1056,8 +1056,8 @@ namespace Mono.TextEditor if (textEditor.preeditOffset < end) end += (int)preeditLength; } - var si = TranslateToUTF8Index (lineChars, (uint)(startIndex + start - chunk.Offset), ref curIndex); - var ei = TranslateToUTF8Index (lineChars, (uint)(startIndex + end - chunk.Offset), ref curIndex); + var si = TranslateToUTF8Index (lineChars, (uint)(startIndex + start - chunk.Offset), ref curIndex, ref byteIndex); + var ei = TranslateToUTF8Index (lineChars, (uint)(startIndex + end - chunk.Offset), ref curIndex, ref byteIndex); var color = (Cairo.Color)EditorTheme.GetForeground (chunkStyle); foreach (var marker in markers) { var chunkMarker = marker as IChunkMarker; @@ -1072,8 +1072,8 @@ namespace Mono.TextEditor wrapper.SelectionEndIndex = (int)ei; }); - var translatedStartIndex = TranslateToUTF8Index (lineChars, (uint)startIndex, ref curChunkIndex); - var translatedEndIndex = TranslateToUTF8Index (lineChars, (uint)endIndex, ref curChunkIndex); + var translatedStartIndex = TranslateToUTF8Index (lineChars, (uint)startIndex, ref curChunkIndex, ref byteChunkIndex); + var translatedEndIndex = TranslateToUTF8Index (lineChars, (uint)endIndex, ref curChunkIndex, ref byteChunkIndex); if (chunkStyle.FontWeight != Xwt.Drawing.FontWeight.Normal) atts.AddWeightAttribute ((Pango.Weight)chunkStyle.FontWeight, translatedStartIndex, translatedEndIndex); @@ -1086,8 +1086,8 @@ namespace Mono.TextEditor } } if (containsPreedit) { - var si = TranslateToUTF8Index (lineChars, (uint)(textEditor.preeditOffset - offset), ref curIndex); - var ei = TranslateToUTF8Index (lineChars, (uint)(textEditor.preeditOffset - offset + preeditLength), ref curIndex); + var si = TranslateToUTF8Index (lineChars, (uint)(textEditor.preeditOffset - offset), ref curIndex, ref byteIndex); + var ei = TranslateToUTF8Index (lineChars, (uint)(textEditor.preeditOffset - offset + preeditLength), ref curIndex, ref byteIndex); if (textEditor.GetTextEditorData ().IsCaretInVirtualLocation) { uint len = (uint)textEditor.GetTextEditorData ().GetIndentationString (textEditor.Caret.Location).Length; @@ -1356,18 +1356,17 @@ namespace Mono.TextEditor } } - public static uint TranslateToUTF8Index (char[] charArray, uint textIndex, ref uint curIndex) + public static uint TranslateToUTF8Index (char[] charArray, uint textIndex, ref uint curIndex, ref uint byteIndex) { if (textIndex > charArray.Length) throw new ArgumentOutOfRangeException (nameof (textIndex), " must be <= charArrayLength (" + charArray.Length + ") was :" + textIndex); - uint byteIndex = 0; if (textIndex < curIndex) { byteIndex = (uint)Encoding.UTF8.GetByteCount (charArray, 0, (int)textIndex); } else { int count = System.Math.Min ((int)(textIndex - curIndex), charArray.Length - (int)curIndex); if (count > 0) - byteIndex = curIndex + (uint)Encoding.UTF8.GetByteCount (charArray, (int)curIndex, count); + byteIndex += (uint)Encoding.UTF8.GetByteCount (charArray, (int)curIndex, count); } curIndex = textIndex; return byteIndex; @@ -1498,9 +1497,9 @@ namespace Mono.TextEditor BackgroundColors.Add (new BackgroundColor (color, fromIdx, toIdx)); } - public uint TranslateToUTF8Index (uint textIndex, ref uint curIndex) + public uint TranslateToUTF8Index (uint textIndex, ref uint curIndex, ref uint byteIndex) { - return TextViewMargin.TranslateToUTF8Index (LineChars, textIndex, ref curIndex); + return TextViewMargin.TranslateToUTF8Index (LineChars, textIndex, ref curIndex, ref byteIndex); } public bool FastPath { get; internal set; } @@ -1588,7 +1587,7 @@ namespace Mono.TextEditor if (chunks == null) return; - uint curIndex = 0; + uint curIndex = 0, byteIndex = 0; bool first = true, oldSelected = false; var curchunk = 0; @@ -1631,12 +1630,12 @@ namespace Mono.TextEditor if (lastIndex == i) { posX = lastPosX; } else { - layout.IndexToLineX ((int)TranslateToUTF8Index (chars, (uint)i, ref curIndex), false, out line, out posX); + layout.IndexToLineX ((int)TranslateToUTF8Index (chars, (uint)i, ref curIndex, ref byteIndex), false, out line, out posX); } double xpos = x + posX / Pango.Scale.PangoScale; if (xpos > textEditorWidth) break; - layout.IndexToLineX ((int)TranslateToUTF8Index (chars, (uint)i + 1, ref curIndex), false, out line, out posX); + layout.IndexToLineX ((int)TranslateToUTF8Index (chars, (uint)i + 1, ref curIndex, ref byteIndex), false, out line, out posX); lastPosX = posX; lastIndex = i + 1; double xpos2 = x + posX / Pango.Scale.PangoScale; @@ -1911,7 +1910,7 @@ namespace Mono.TextEditor // highlight search results ISegment firstSearch; int o = offset; - uint curIndex = 0; + uint curIndex = 0, byteIndex = 0; if (textEditor.HighlightSearchPattern) { while (!(firstSearch = GetFirstSearchResult (o, offset + length)).IsInvalid ()) { double x = position; @@ -1919,8 +1918,8 @@ namespace Mono.TextEditor uint startIndex = (uint)(start - offset); uint endIndex = (uint)(end - offset); if (startIndex < endIndex && endIndex <= layout.LineChars.Length) { - uint startTranslated = TranslateToUTF8Index (layout.LineChars, startIndex, ref curIndex); - uint endTranslated = TranslateToUTF8Index (layout.LineChars, endIndex, ref curIndex); + uint startTranslated = TranslateToUTF8Index (layout.LineChars, startIndex, ref curIndex, ref byteIndex); + uint endTranslated = TranslateToUTF8Index (layout.LineChars, endIndex, ref curIndex, ref byteIndex); int l, x1, x2; layout.IndexToLineX ((int)startTranslated, false, out l, out x1); @@ -2010,20 +2009,19 @@ namespace Mono.TextEditor SetVisibleCaretPosition (x, y, x, y); } else if (index >= 0 && index <= length) { Pango.Rectangle strong_pos, weak_pos; - curIndex = 0; - int utf8ByteIndex = (int)TranslateToUTF8Index (layout.LineChars, (uint)index, ref curIndex); + curIndex = byteIndex = 0; + int utf8ByteIndex = (int)TranslateToUTF8Index (layout.LineChars, (uint)index, ref curIndex, ref byteIndex); layout.GetCursorPos (utf8ByteIndex, out strong_pos, out weak_pos); - - var cx = xPos + (weak_pos.X / Pango.Scale.PangoScale); - var cy = y + (weak_pos.Y / Pango.Scale.PangoScale); + var cx = xPos + (strong_pos.X / Pango.Scale.PangoScale); + var cy = y + (strong_pos.Y / Pango.Scale.PangoScale); if (textEditor.preeditCursorCharIndex == 0) { SetVisibleCaretPosition (cx, cy, cx, cy); } else { var preeditIndex = (uint)(index + textEditor.preeditCursorCharIndex); - utf8ByteIndex = (int)TranslateToUTF8Index (layout.LineChars, preeditIndex, ref curIndex); + utf8ByteIndex = (int)TranslateToUTF8Index (layout.LineChars, preeditIndex, ref curIndex, ref byteIndex); layout.GetCursorPos (utf8ByteIndex, out strong_pos, out weak_pos); - var pcx = xPos + (weak_pos.X / Pango.Scale.PangoScale); - var pcy = y + (weak_pos.Y / Pango.Scale.PangoScale); + var pcx = xPos + (strong_pos.X / Pango.Scale.PangoScale); + var pcy = y + (strong_pos.Y / Pango.Scale.PangoScale); SetVisibleCaretPosition (pcx, pcy, cx, cy); } } @@ -3396,10 +3394,11 @@ namespace Mono.TextEditor var wrapper = GetLayout (line); uint curIndex = 0; + uint byteIndex = 0; int index; Pango.Rectangle pos; try { - index = (int)TranslateToUTF8Index (wrapper.LineChars, (uint)System.Math.Min (System.Math.Max (0, column), wrapper.LineChars.Length), ref curIndex); + index = (int)TranslateToUTF8Index (wrapper.LineChars, (uint)System.Math.Min (System.Math.Max (0, column), wrapper.LineChars.Length), ref curIndex, ref byteIndex); pos = wrapper.IndexToPos (index); } catch { return 0; diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskOverviewMode.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskOverviewMode.cs index 819508a2ff..cf3c851451 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskOverviewMode.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.QuickTasks/QuickTaskOverviewMode.cs @@ -728,7 +728,7 @@ namespace MonoDevelop.SourceEditor.QuickTasks var usageColor = (Cairo.Color)SyntaxHighlightingService.GetColor (TextEditor.EditorTheme, EditorThemeColors.Foreground); usageColor.A = 0.4; HslColor color; - if ((usage.UsageType & MonoDevelop.Ide.FindInFiles.ReferenceUsageType.Declariton) != 0) { + if ((usage.UsageType & MonoDevelop.Ide.FindInFiles.ReferenceUsageType.Declaration) != 0) { color = SyntaxHighlightingService.GetColor (TextEditor.EditorTheme, EditorThemeColors.ChangingUsagesRectangle); if (color.Alpha == 0.0) color = SyntaxHighlightingService.GetColor (TextEditor.EditorTheme, EditorThemeColors.UsagesRectangle); diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.Wrappers/SemanticHighlightingSyntaxMode.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.Wrappers/SemanticHighlightingSyntaxMode.cs index 18963643f2..47c0406402 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.Wrappers/SemanticHighlightingSyntaxMode.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor.Wrappers/SemanticHighlightingSyntaxMode.cs @@ -39,7 +39,7 @@ using MonoDevelop.Core; namespace MonoDevelop.SourceEditor.Wrappers { - sealed class SemanticHighlightingSyntaxMode : ISyntaxHighlighting, IDisposable + sealed class SemanticHighlightingSyntaxMode : ISyntaxHighlighting { readonly ExtensibleTextEditor editor; readonly ISyntaxHighlighting syntaxMode; @@ -140,8 +140,9 @@ namespace MonoDevelop.SourceEditor.Wrappers { if (isDisposed) return; - isDisposed = true; + // Unregister before setting isDisposed=true, as that causes the method to bail out early. UnregisterLineSegmentTrees (); + isDisposed = true; lineSegments = null; semanticHighlighting.SemanticHighlightingUpdated -= SemanticHighlighting_SemanticHighlightingUpdated; } @@ -162,8 +163,16 @@ namespace MonoDevelop.SourceEditor.Wrappers var segments = new List<ColoredSegment> (syntaxLine.Segments); int endOffset = segments [segments.Count - 1].EndOffset; try { - var tree = lineSegments.FirstOrDefault (t => t.Item1 == line); + Tuple<IDocumentLine, HighlightingSegmentTree> tree = null; + + // This code should not have any lambda capture linq, as it is a hot loop. int lineOffset = line.Offset; + foreach (var segment in lineSegments) {
+ if (segment.Item1.Offset == lineOffset) {
+ tree = segment;
+ break;
+ }
+ }
if (tree == null) { tree = Tuple.Create (line, new HighlightingSegmentTree ()); tree.Item2.InstallListener (editor.Document); diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/ExtensibleTextEditor.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/ExtensibleTextEditor.cs index e56ff655a1..31b6d3bf91 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/ExtensibleTextEditor.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/ExtensibleTextEditor.cs @@ -208,12 +208,8 @@ namespace MonoDevelop.SourceEditor { IsDestroyed = true; UnregisterAdjustments (); - view = null; - var disposableSyntaxMode = Document.SyntaxMode as IDisposable; - if (disposableSyntaxMode != null) { - disposableSyntaxMode.Dispose (); - Document.SyntaxMode = null; - } + view = null;
+ Document.SyntaxMode = null; base.OnDestroyed (); if (Options != null) { Options.Dispose (); diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/MessageBubbleTextMarker.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/MessageBubbleTextMarker.cs index ef0af29210..9d5c65c262 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/MessageBubbleTextMarker.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/MessageBubbleTextMarker.cs @@ -697,7 +697,7 @@ namespace MonoDevelop.SourceEditor void DrawErrorMarkers (MonoTextEditor editor, Cairo.Context g, LineMetrics metrics, double y) { - uint curIndex = 0; + uint curIndex = 0, byteIndex = 0; var o = metrics.LineSegment.Offset; @@ -711,7 +711,7 @@ namespace MonoDevelop.SourceEditor } if (column >= metrics.Layout.LineChars.Length) continue; - int index = (int)metrics.Layout.TranslateToUTF8Index (column, ref curIndex); + int index = (int)metrics.Layout.TranslateToUTF8Index (column, ref curIndex, ref byteIndex); var pos = metrics.Layout.IndexToPos (index); var co = o + task.Column - 1; g.SetSourceColor (GetMarkerColor (false, metrics.SelectionStart <= co && co < metrics.SelectionEnd)); diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SearchInSelectionMarker.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SearchInSelectionMarker.cs index a0116094dc..270180388c 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SearchInSelectionMarker.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SearchInSelectionMarker.cs @@ -30,13 +30,13 @@ namespace MonoDevelop.SourceEditor int end = endOffset < markerEnd ? endOffset : markerEnd; uint curIndex = 0, byteIndex = 0; - byteIndex = TextViewMargin.TranslateToUTF8Index (metrics.Layout.LineChars, (uint)(start - startOffset), ref curIndex); + TextViewMargin.TranslateToUTF8Index (metrics.Layout.LineChars, (uint)(start - startOffset), ref curIndex, ref byteIndex); int x_pos = metrics.Layout.IndexToPos ((int)byteIndex).X; @from = startXPos + (int)(x_pos / Pango.Scale.PangoScale); - byteIndex = TextViewMargin.TranslateToUTF8Index (metrics.Layout.LineChars, (uint)(end - startOffset), ref curIndex); + TextViewMargin.TranslateToUTF8Index (metrics.Layout.LineChars, (uint)(end - startOffset), ref curIndex, ref byteIndex); x_pos = metrics.Layout.IndexToPos ((int)byteIndex).X; to = startXPos + (int)(x_pos / Pango.Scale.PangoScale); diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorView.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorView.cs index 46a83d4d26..06edfcc2ac 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorView.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/SourceEditorView.cs @@ -3147,13 +3147,13 @@ namespace MonoDevelop.SourceEditor int end = this.EndOffset; uint curIndex = 0, byteIndex = 0; - byteIndex = TextViewMargin.TranslateToUTF8Index (metrics.Layout.LineChars, (uint)Math.Min (start - startOffset, metrics.Layout.LineChars.Length), ref curIndex); + TextViewMargin.TranslateToUTF8Index (metrics.Layout.LineChars, (uint)Math.Min (start - startOffset, metrics.Layout.LineChars.Length), ref curIndex, ref byteIndex); int x_pos = metrics.Layout.IndexToPos ((int)byteIndex).X; fromX = startXPos + (int)(x_pos / Pango.Scale.PangoScale); - byteIndex = TextViewMargin.TranslateToUTF8Index (metrics.Layout.LineChars, (uint)Math.Min (end - startOffset, metrics.Layout.LineChars.Length), ref curIndex); + TextViewMargin.TranslateToUTF8Index (metrics.Layout.LineChars, (uint)Math.Min (end - startOffset, metrics.Layout.LineChars.Length), ref curIndex, ref byteIndex); x_pos = metrics.Layout.IndexToPos ((int)byteIndex).X; toX = startXPos + (int)(x_pos / Pango.Scale.PangoScale); diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/TextMarker/DebugTextMarker.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/TextMarker/DebugTextMarker.cs index 810c84a7e6..1212a48640 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/TextMarker/DebugTextMarker.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/TextMarker/DebugTextMarker.cs @@ -120,13 +120,13 @@ namespace MonoDevelop.SourceEditor int end = endOffset < markerEnd ? endOffset : markerEnd; uint curIndex = 0, byteIndex = 0; - byteIndex = TextViewMargin.TranslateToUTF8Index (metrics.Layout.LineChars, (uint)(start - startOffset), ref curIndex); + TextViewMargin.TranslateToUTF8Index (metrics.Layout.LineChars, (uint)(start - startOffset), ref curIndex, ref byteIndex); int x_pos = metrics.Layout.IndexToPos ((int)byteIndex).X; @from = startXPos + (int)(x_pos / Pango.Scale.PangoScale); - byteIndex = TextViewMargin.TranslateToUTF8Index (metrics.Layout.LineChars, (uint)(end - startOffset), ref curIndex); + TextViewMargin.TranslateToUTF8Index (metrics.Layout.LineChars, (uint)(end - startOffset), ref curIndex, ref byteIndex); x_pos = metrics.Layout.IndexToPos ((int)byteIndex).X; to = startXPos + (int)(x_pos / Pango.Scale.PangoScale); diff --git a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/TextMarker/UsageSegmentMarker.cs b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/TextMarker/UsageSegmentMarker.cs index a388baded8..37bdcbbda5 100644 --- a/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/TextMarker/UsageSegmentMarker.cs +++ b/main/src/addins/MonoDevelop.SourceEditor2/MonoDevelop.SourceEditor/TextMarker/UsageSegmentMarker.cs @@ -63,14 +63,14 @@ namespace MonoDevelop.SourceEditor int start = startOffset < markerStart ? markerStart : startOffset; int end = endOffset < markerEnd ? endOffset : markerEnd; - uint curIndex = 0; - var byteIndex = TextViewMargin.TranslateToUTF8Index (metrics.Layout.LineChars, (uint)(start - startOffset), ref curIndex); + uint curIndex = 0, byteIndex = 0; + TextViewMargin.TranslateToUTF8Index (metrics.Layout.LineChars, (uint)(start - startOffset), ref curIndex, ref byteIndex); int x_pos = metrics.Layout.IndexToPos ((int)byteIndex).X; @from = startXPos + (int)(x_pos / Pango.Scale.PangoScale); - byteIndex = TextViewMargin.TranslateToUTF8Index (metrics.Layout.LineChars, (uint)(end - startOffset), ref curIndex); + TextViewMargin.TranslateToUTF8Index (metrics.Layout.LineChars, (uint)(end - startOffset), ref curIndex, ref byteIndex); x_pos = metrics.Layout.IndexToPos ((int)byteIndex).X; to = startXPos + (int)(x_pos / Pango.Scale.PangoScale); @@ -81,7 +81,7 @@ namespace MonoDevelop.SourceEditor if (@from < to) { HslColor colorStyle; if ((usage.UsageType & ReferenceUsageType.Write) == ReferenceUsageType.Write || - (usage.UsageType & ReferenceUsageType.Declariton) == ReferenceUsageType.Declariton) { + (usage.UsageType & ReferenceUsageType.Declaration) == ReferenceUsageType.Declaration) { colorStyle = SyntaxHighlightingService.GetColor (editor.EditorTheme, EditorThemeColors.ChangingUsagesRectangle); if (colorStyle.Alpha == 0.0) diff --git a/main/src/addins/VBNetBinding/MonoDevelop.VBNet/VBNetTextEditorExtension.cs b/main/src/addins/VBNetBinding/MonoDevelop.VBNet/VBNetTextEditorExtension.cs index 4aee67be78..6672666554 100644 --- a/main/src/addins/VBNetBinding/MonoDevelop.VBNet/VBNetTextEditorExtension.cs +++ b/main/src/addins/VBNetBinding/MonoDevelop.VBNet/VBNetTextEditorExtension.cs @@ -196,6 +196,10 @@ namespace MonoDevelop.VBNet { return Task.FromResult (vbScope); } + + public void Dispose()
+ {
+ } } } } diff --git a/main/src/core/Mono.TextEditor.Platform/TagBasedSyntaxHighlighting.cs b/main/src/core/Mono.TextEditor.Platform/TagBasedSyntaxHighlighting.cs index 8b62ac774e..203375e1a4 100644 --- a/main/src/core/Mono.TextEditor.Platform/TagBasedSyntaxHighlighting.cs +++ b/main/src/core/Mono.TextEditor.Platform/TagBasedSyntaxHighlighting.cs @@ -221,5 +221,9 @@ namespace Microsoft.VisualStudio.Platform return styleName;
}
+
+ public void Dispose()
+ {
+ }
}
}
\ No newline at end of file diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Actions/CaretMoveActions.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Actions/CaretMoveActions.cs index c8d725dea6..ff898c56b5 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Actions/CaretMoveActions.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Actions/CaretMoveActions.cs @@ -70,8 +70,8 @@ namespace Mono.TextEditor if (!foundFolding) { var layout = data.Parent?.TextViewMargin?.GetLayout (line); if (layout != null && data.Caret.Column < line.Length) { - uint curIndex = 0; - int utf8ByteIndex = (int)layout.TranslateToUTF8Index ((uint)(offset - line.Offset), ref curIndex); + uint curIndex = 0, byteIndex = 0; + int utf8ByteIndex = (int)layout.TranslateToUTF8Index ((uint)(offset - line.Offset), ref curIndex, ref byteIndex); layout.Layout.GetCursorPos (utf8ByteIndex, out var strong_pos, out var weak_pos); if (strong_pos.X != weak_pos.X) { offset--; @@ -148,8 +148,8 @@ namespace Mono.TextEditor data.Caret.Column++; var layout = data.Parent?.TextViewMargin?.GetLayout (line); if (layout != null && data.Caret.Column < line.Length) { - uint curIndex = 0; - int utf8ByteIndex = (int)layout.TranslateToUTF8Index ((uint)data.Caret.Column - 1, ref curIndex); + uint curIndex = 0, byteIndex = 0; + int utf8ByteIndex = (int)layout.TranslateToUTF8Index ((uint)data.Caret.Column - 1, ref curIndex, ref byteIndex); layout.Layout.GetCursorPos (utf8ByteIndex, out var strong_pos, out var weak_pos); if (strong_pos.X != weak_pos.X) { data.Caret.Column++; diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/TextDocument.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/TextDocument.cs index 1a8468606a..ef451e7bbf 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/TextDocument.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/Document/TextDocument.cs @@ -45,7 +45,7 @@ using Microsoft.VisualStudio.Text.Tagging; namespace Mono.TextEditor {
- class TextDocument : ITextDocument
+ class TextDocument : ITextDocument, IDisposable
{
public Microsoft.VisualStudio.Text.ITextDocument VsTextDocument { get; }
public Microsoft.VisualStudio.Text.ITextBuffer TextBuffer { get { return this.VsTextDocument.TextBuffer; } }
@@ -132,8 +132,10 @@ namespace Mono.TextEditor ISyntaxHighlighting old;
lock (syncObject) {
old = syntaxMode;
- if (old != null && old != DefaultSyntaxHighlighting.Instance)
+ if (old != null && old != DefaultSyntaxHighlighting.Instance) {
old.HighlightingStateChanged -= SyntaxMode_HighlightingStateChanged;
+ old.Dispose ();
+ }
syntaxMode = value;
if (syntaxMode != null && syntaxMode != DefaultSyntaxHighlighting.Instance)
@@ -220,6 +222,15 @@ namespace Mono.TextEditor this.diffTracker.SetTrackDocument(this);
}
+ public void Dispose()
+ {
+ this.TextBuffer.Changed -= this.OnTextBufferChanged;
+ this.TextBuffer.ContentTypeChanged -= this.OnTextBufferContentTypeChanged;
+ this.TextBuffer.Properties.RemoveProperty(typeof(ITextDocument));
+ this.VsTextDocument.FileActionOccurred -= this.OnTextDocumentFileActionOccured;
+ SyntaxMode = null;
+ }
+
void OnTextBufferChanged(object sender, Microsoft.VisualStudio.Text.TextContentChangedEventArgs args) { if (args.Changes == null) @@ -2240,13 +2251,13 @@ namespace Mono.TextEditor public int LineCount { get { return this.Span.Snapshot.LineCount; } }
- public int LocationToOffset(int line, int column)
- {
- if (line > this.LineCount || line < DocumentLocation.MinLine)
- return -1;
- IDocumentLine documentLine = GetLine(line);
- return System.Math.Min(Length, documentLine.Offset + System.Math.Max(0, System.Math.Min(documentLine.Length, column - 1)));
- }
+ public int LocationToOffset (int line, int column) + { + if (line > this.LineCount || line < DocumentLocation.MinLine) + return -1; + IDocumentLine documentLine = GetLine (line); + return System.Math.Min (Length, documentLine.Offset + System.Math.Max (0, System.Math.Min (documentLine.Length, column - 1))); + } public DocumentLocation OffsetToLocation(int offset)
{
diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/TextEditorData.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/TextEditorData.cs index 32d7e98a92..682556bdbe 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/TextEditorData.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/TextEditorData.cs @@ -634,6 +634,7 @@ namespace Mono.TextEditor document.Folded -= HandleTextEditorDataDocumentFolded; document.FoldTreeUpdated -= HandleFoldTreeUpdated; document.HeightChanged -= Document_HeightChanged; + document.Dispose (); document = null; } diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/TextSegmentMarker.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/TextSegmentMarker.cs index 76cda0b75a..d655942566 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/TextSegmentMarker.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/TextSegmentMarker.cs @@ -145,12 +145,13 @@ namespace Mono.TextEditor int end = endOffset < markerEnd ? endOffset : markerEnd; int /*lineNr,*/ x_pos; uint curIndex = 0;
- var byteIndex = metrics.Layout.TranslateToUTF8Index ((uint)(start - startOffset), ref curIndex); + uint byteIndex = 0;
+ metrics.Layout.TranslateToUTF8Index ((uint)(start - startOffset), ref curIndex, ref byteIndex); x_pos = layout.IndexToPos (System.Math.Max (0, (int)byteIndex)).X; @from = startXPos + (int)(x_pos / Pango.Scale.PangoScale);
- byteIndex = metrics.Layout.TranslateToUTF8Index ((uint)(end - startOffset), ref curIndex); + metrics.Layout.TranslateToUTF8Index ((uint)(end - startOffset), ref curIndex, ref byteIndex); x_pos = layout.IndexToPos (System.Math.Max (0, (int)byteIndex)).X; diff --git a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/UrlMarker.cs b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/UrlMarker.cs index 40f9e58e85..6e2a52e04f 100644 --- a/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/UrlMarker.cs +++ b/main/src/core/Mono.TextEditor.Shared/Mono.TextEditor/UrlMarker.cs @@ -129,12 +129,12 @@ namespace Mono.TextEditor int start = startOffset < markerStart ? markerStart : startOffset; int end = endOffset < markerEnd ? endOffset : markerEnd; - uint curIndex = 0 ; - int x_pos = layout.IndexToPos ((int)metrics.Layout.TranslateToUTF8Index ((uint)(start - startOffset), ref curIndex)).X; + uint curIndex = 0, byteIndex = 0; + int x_pos = layout.IndexToPos ((int)metrics.Layout.TranslateToUTF8Index ((uint)(start - startOffset), ref curIndex, ref byteIndex)).X; @from = startXPos + (int)(x_pos / Pango.Scale.PangoScale); - x_pos = layout.IndexToPos ((int)metrics.Layout.TranslateToUTF8Index ((uint)(end - startOffset), ref curIndex)).X; + x_pos = layout.IndexToPos ((int)metrics.Layout.TranslateToUTF8Index ((uint)(end - startOffset), ref curIndex, ref byteIndex)).X; to = startXPos + (int)(x_pos / Pango.Scale.PangoScale); } diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs index 913b396c09..1526b395eb 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildEvaluationContext.cs @@ -957,7 +957,7 @@ namespace MonoDevelop.Projects.MSBuild int pc = 0; while (i < str.Length) { var c = str [i]; - if (pc == 0 && closeChar.IndexOf (c) != -1) + if (pc == 0 && Array.IndexOf (closeChar, c) != -1) return i; if (c == '(' || c == '[') pc++; diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectService.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectService.cs index 99ca4eb9da..5f6ef685bd 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectService.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects.MSBuild/MSBuildProjectService.cs @@ -517,7 +517,7 @@ namespace MonoDevelop.Projects.MSBuild internal static MSBuildSupport GetMSBuildSupportForFlavors (IEnumerable<string> flavorGuids) { foreach (var fid in flavorGuids) { - var node = WorkspaceObject.GetModelExtensions (null).OfType<SolutionItemExtensionNode> ().FirstOrDefault (n => n.Guid.Equals (fid, StringComparison.InvariantCultureIgnoreCase)); + var node = WorkspaceObject.GetModelExtensions (null).OfType<SolutionItemExtensionNode> ().FirstOrDefault (n => n.Guid != null && n.Guid.Equals (fid, StringComparison.InvariantCultureIgnoreCase)); if (node != null) { if (node.MSBuildSupport != MSBuildSupport.Supported) return node.MSBuildSupport; @@ -532,7 +532,7 @@ namespace MonoDevelop.Projects.MSBuild var list = new List<SolutionItemExtensionNode> (); foreach (var fid in flavorGuids) { foreach (var node in WorkspaceObject.GetModelExtensions (null).OfType<SolutionItemExtensionNode> ()) { - if (node.SupportsMigration && node.Guid.Equals (fid, StringComparison.InvariantCultureIgnoreCase)) + if (node.SupportsMigration && node.Guid != null && node.Guid.Equals (fid, StringComparison.InvariantCultureIgnoreCase)) list.Add (node); } } @@ -633,7 +633,7 @@ namespace MonoDevelop.Projects.MSBuild internal static bool IsKnownFlavorGuid (string guid) { - return WorkspaceObject.GetModelExtensions (null).OfType<SolutionItemExtensionNode> ().Any (n => n.Guid.Equals (guid, StringComparison.InvariantCultureIgnoreCase)); + return WorkspaceObject.GetModelExtensions (null).OfType<SolutionItemExtensionNode> ().Any (n => n.Guid != null && n.Guid.Equals (guid, StringComparison.InvariantCultureIgnoreCase)); } internal static bool IsKnownTypeGuid (string guid) diff --git a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ExtensionChain.cs b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ExtensionChain.cs index e0e48e7ad9..cf0ffb64a8 100644 --- a/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ExtensionChain.cs +++ b/main/src/core/MonoDevelop.Core/MonoDevelop.Projects/ExtensionChain.cs @@ -71,13 +71,13 @@ namespace MonoDevelop.Projects { int index; if (insertBefore != null) { - index = extensions.IndexOf (insertBefore); + index = Array.IndexOf (extensions, insertBefore); } else if (insertAfter != null) { - index = extensions.IndexOf (insertAfter); + index = Array.IndexOf (extensions, insertAfter); if (index != -1) index++; } else if (defaultInsertBefore != null) { - index = extensions.IndexOf (defaultInsertBefore); + index = Array.IndexOf (extensions, defaultInsertBefore); } else index = extensions.Length; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/KeyBindingService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/KeyBindingService.cs index 3d57d0d26c..62f9eac511 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/KeyBindingService.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Commands/KeyBindingService.cs @@ -168,7 +168,12 @@ namespace MonoDevelop.Components.Commands public static void LoadCurrentBindings (string defaultSchemaId) { XmlTextReader reader = null; - + + if (!File.Exists (ConfigFileName)) { + ResetCurrent (defaultSchemaId); + return; + } + try { reader = new XmlTextReader (ConfigFileName); current.LoadScheme (reader, "current"); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/DockNotebook.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/DockNotebook.cs index c06a73ef6b..eac94c4102 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/DockNotebook.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/DockNotebook.cs @@ -36,7 +36,7 @@ using MonoDevelop.Core; namespace MonoDevelop.Components.DockNotebook { - delegate void TabsReorderedHandler (Widget widget, int oldPlacement, int newPlacement); + delegate void TabsReorderedHandler (DockNotebookTab tab, int oldPlacement, int newPlacement); class DockNotebook : Gtk.VBox { @@ -135,8 +135,8 @@ namespace MonoDevelop.Components.DockNotebook public event EventHandler<TabEventArgs> TabClosed; public event EventHandler<TabEventArgs> TabActivated; - public event EventHandler PageAdded; - public event EventHandler PageRemoved; + public event EventHandler<TabEventArgs> PageAdded; + public event EventHandler<TabEventArgs> PageRemoved; public event EventHandler SwitchPage; public event EventHandler PreviousButtonClicked { @@ -315,8 +315,7 @@ namespace MonoDevelop.Components.DockNotebook tabStrip.Update (); tabStrip.DropDownButton.Sensitive = pages.Count > 0; - if (PageAdded != null) - PageAdded (this, EventArgs.Empty); + PageAdded?.Invoke (this, new TabEventArgs { Tab = tab, }); NotebookChanged?.Invoke (this, EventArgs.Empty); @@ -352,8 +351,7 @@ namespace MonoDevelop.Components.DockNotebook tabStrip.Update (); tabStrip.DropDownButton.Sensitive = pages.Count > 0; - if (PageRemoved != null) - PageRemoved (this, EventArgs.Empty); + PageRemoved?.Invoke (this, new TabEventArgs { Tab = tab }); NotebookChanged?.Invoke (this, EventArgs.Empty); } @@ -370,7 +368,8 @@ namespace MonoDevelop.Components.DockNotebook pages.Insert (targetPos + 1, tab); pages.RemoveAt (tab.Index); } - IdeApp.Workbench.ReorderDocuments (tab.Index, targetPos); + if (TabsReordered != null) + TabsReordered (tab, tab.Index, targetPos); UpdateIndexes (Math.Min (tab.Index, targetPos)); tabStrip.Update (); } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/TabStrip.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/TabStrip.cs index 1014b8fd9e..9896c5d2a8 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/TabStrip.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.DockNotebook/TabStrip.cs @@ -71,7 +71,6 @@ namespace MonoDevelop.Components.DockNotebook int animationTarget; Dictionary<int, DockNotebookTab> closingTabs; - List<DockNotebookTab> allTabs; public Button PreviousButton; public Button NextButton; @@ -218,16 +217,14 @@ namespace MonoDevelop.Components.DockNotebook QueueDraw (); } }; - - // Create a copy of the tabs so we can track which tabs have been added or removed - // for accessibility purposes. - allTabs = new List<DockNotebookTab> (); + foreach (var tab in notebook.Tabs) { - allTabs.Add (tab); Accessible.AddAccessibleElement (tab.Accessible); - } + }
+ UpdateAccessibilityTabs (); notebook.PageAdded += PageAddedHandler; notebook.PageRemoved += PageRemovedHandler; + notebook.TabsReordered += PageReorderedHandler; closingTabs = new Dictionary<int, DockNotebookTab> (); } @@ -240,60 +237,46 @@ namespace MonoDevelop.Components.DockNotebook base.OnDestroyed (); } - void PageAddedHandler (object sender, EventArgs args) + void PageAddedHandler (object sender, TabEventArgs args) { - int idx = 0; - foreach (var tab in notebook.Tabs) { - if (idx >= allTabs.Count || tab != allTabs [idx]) { - allTabs.Insert (idx, tab); - Accessible.AddAccessibleElement (tab.Accessible); - - tab.AccessibilityPressTab += OnAccessibilityPressTab; - tab.AccessibilityPressCloseButton += OnAccessibilityPressCloseButton; - tab.AccessibilityShowMenu += OnAccessibilityShowMenu; - break; - } - - idx++; - } + var tab = args.Tab;
+
+ Accessible.AddAccessibleElement (tab.Accessible);
+
+ tab.AccessibilityPressTab += OnAccessibilityPressTab;
+ tab.AccessibilityPressCloseButton += OnAccessibilityPressCloseButton;
+ tab.AccessibilityShowMenu += OnAccessibilityShowMenu; QueueResize (); UpdateAccessibilityTabs (); } - void PageRemovedHandler (object sender, EventArgs args) + void PageRemovedHandler (object sender, TabEventArgs args) { - int idx = 0; - foreach (var tab in notebook.Tabs) { - if (tab != allTabs [idx]) { - tab.AccessibilityPressTab -= OnAccessibilityPressTab; - tab.AccessibilityPressCloseButton -= OnAccessibilityPressCloseButton; - tab.AccessibilityShowMenu -= OnAccessibilityShowMenu; - - Accessible.RemoveAccessibleElement (tab.Accessible); - allTabs.RemoveAt (idx); - break; - } - - idx++; - } + var tab = args.Tab;
+
+ tab.AccessibilityPressTab -= OnAccessibilityPressTab;
+ tab.AccessibilityPressCloseButton -= OnAccessibilityPressCloseButton;
+ tab.AccessibilityShowMenu -= OnAccessibilityShowMenu;
+
+ Accessible.RemoveAccessibleElement (tab.Accessible); QueueResize (); UpdateAccessibilityTabs (); } - void UpdateAccessibilityTabs () + void PageReorderedHandler (DockNotebookTab tab, int oldPlacement, int newPlacement)
{ - int idx = 0; - var tabs = new AtkCocoaHelper.AccessibilityElementProxy [allTabs.Count]; + QueueResize (); - foreach (var tab in allTabs) { - tabs [idx] = tab.Accessible; - idx++; - } + UpdateAccessibilityTabs ();
+ } + void UpdateAccessibilityTabs () + { + var tabs = notebook.Tabs.OrderBy (x => x.Index).Select (x => x.Accessible).ToArray (); Accessible.SetTabs (tabs); } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Docking/DockItemTitleTab.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Docking/DockItemTitleTab.cs index 6836185999..1e385e7637 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Docking/DockItemTitleTab.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components.Docking/DockItemTitleTab.cs @@ -51,10 +51,12 @@ namespace MonoDevelop.Components.Docking int minWidth; DockVisualStyle visualStyle; ImageView tabIcon; + Gtk.HBox box; DockFrame frame; string label; ImageButton btnDock; ImageButton btnClose; + Gtk.Alignment al; DockItem item; bool allowPlaceholderDocking; bool mouseOver; @@ -141,7 +143,7 @@ namespace MonoDevelop.Components.Docking else inactiveIconAlpha = 0.6; - if (labelWidget != null && label != null) { + if (labelWidget?.Visible == true && label != null) { if (visualStyle.UppercaseTitles.Value) labelWidget.Text = label.ToUpper (); else @@ -152,13 +154,14 @@ namespace MonoDevelop.Components.Docking if (!(Parent is TabStrip.TabStripBox)) labelWidget.Xalign = 0; - } - - if (tabIcon != null) { - tabIcon.Image = tabIcon.Image.WithAlpha (active ? 1.0 : inactiveIconAlpha); + }
+
+ if (tabIcon != null) {
+ tabIcon.Image = tabIcon.Image.WithAlpha (active ? 1.0 : inactiveIconAlpha);
tabIcon.Visible = visualStyle.ShowPadTitleIcon.Value; } - if (IsRealized && labelWidget != null) { + + if (IsRealized && labelWidget?.Visible == true) { var font = FontService.SansFont.CopyModified (null, Pango.Weight.Bold); font.AbsoluteSize = Pango.Units.FromPixels (11); labelWidget.ModifyFont (font); @@ -178,12 +181,84 @@ namespace MonoDevelop.Components.Docking { string labelNoSpaces = label != null ? label.Replace (' ', '-') : null; this.label = label; - this.page = page; - if (Child != null) { - Gtk.Widget oc = Child; - Remove (oc); - oc.Destroy (); - } + this.page = page;
+
+ if (icon == null)
+ icon = ImageService.GetIcon ("md-empty"); + + if (box == null) {
+ box = new HBox ();
+ box.Accessible.SetShouldIgnore (true);
+ box.Spacing = -2;
+
+ tabIcon = new ImageView ();
+ tabIcon.Accessible.SetShouldIgnore (true);
+ tabIcon.Show ();
+ box.PackStart (tabIcon, false, false, 3);
+
+ labelWidget = new ExtendedLabel (label);
+ // Ignore the label because the title tab already contains its name
+ labelWidget.Accessible.SetShouldIgnore (true);
+ labelWidget.UseMarkup = true;
+ var alignLabel = new Alignment (0.0f, 0.5f, 1, 1);
+ alignLabel.Accessible.SetShouldIgnore (true);
+ alignLabel.BottomPadding = 0;
+ alignLabel.RightPadding = 15;
+ alignLabel.Add (labelWidget);
+ box.PackStart (alignLabel, false, false, 0);
+
+ btnDock = new ImageButton ();
+ btnDock.Image = pixAutoHide;
+ btnDock.TooltipText = GettextCatalog.GetString ("Auto Hide");
+ btnDock.CanFocus = false;
+ // btnDock.WidthRequest = btnDock.HeightRequest = 17;
+ btnDock.Clicked += OnClickDock;
+ btnDock.ButtonPressEvent += (o, args) => args.RetVal = true;
+ btnDock.WidthRequest = btnDock.SizeRequest ().Width;
+ UpdateDockButtonAccessibilityLabels ();
+
+ btnClose = new ImageButton ();
+ btnClose.Image = pixClose;
+ btnClose.TooltipText = GettextCatalog.GetString ("Close");
+ btnClose.CanFocus = false;
+ // btnClose.WidthRequest = btnClose.HeightRequest = 17;
+ btnClose.WidthRequest = btnDock.SizeRequest ().Width;
+ btnClose.Clicked += delegate {
+ item.Visible = false;
+ };
+ btnClose.ButtonPressEvent += (o, args) => args.RetVal = true;
+
+ al = new Alignment (0, 0.5f, 1, 1);
+ al.Accessible.SetShouldIgnore (true);
+ HBox btnBox = new HBox (false, 0);
+ btnBox.Accessible.SetShouldIgnore (true);
+ btnBox.PackStart (btnDock, false, false, 3);
+ btnBox.PackStart (btnClose, false, false, 1);
+ al.Add (btnBox);
+ box.PackEnd (al, false, false, 3);
+
+ Add (box); + }
+
+ tabIcon.Image = icon;
+
+ string realLabel, realHelp;
+ if (!string.IsNullOrEmpty (label)) {
+ labelWidget.Parent.Show ();
+ labelWidget.Name = label;
+ btnDock.Name = string.Format ("btnDock_{0}", labelNoSpaces ?? string.Empty);
+ btnClose.Name = string.Format ("btnClose_{0}", labelNoSpaces ?? string.Empty);
+ realLabel = GettextCatalog.GetString ("Close {0}", label);
+ realHelp = GettextCatalog.GetString ("Close the {0} pad", label);
+ }
+ else {
+ labelWidget.Parent.Hide ();
+ realLabel = GettextCatalog.GetString ("Close pad");
+ realHelp = GettextCatalog.GetString ("Close the pad");
+ }
+
+ btnClose.Accessible.SetLabel (realLabel);
+ btnClose.Accessible.Description = realHelp; if (label != null) { Accessible.Name = $"DockTab.{labelNoSpaces}"; @@ -191,78 +266,6 @@ namespace MonoDevelop.Components.Docking Accessible.SetTitle (label); Accessible.SetLabel (label); } - - Gtk.HBox box = new HBox (); - box.Accessible.SetShouldIgnore (true); - box.Spacing = -2; - - if (icon == null) - icon = ImageService.GetIcon ("md-empty"); - - tabIcon = new ImageView (icon); - tabIcon.Accessible.SetShouldIgnore (true); - tabIcon.Show (); - box.PackStart (tabIcon, false, false, 3); - - if (!string.IsNullOrEmpty (label)) { - labelWidget = new ExtendedLabel (label); - // Ignore the label because the title tab already contains its name - labelWidget.Accessible.SetShouldIgnore (true); - labelWidget.UseMarkup = true; - labelWidget.Name = label; - var alignLabel = new Alignment (0.0f, 0.5f, 1, 1); - alignLabel.Accessible.SetShouldIgnore (true); - alignLabel.BottomPadding = 0; - alignLabel.RightPadding = 15; - alignLabel.Add (labelWidget); - box.PackStart (alignLabel, false, false, 0); - } else { - labelWidget = null; - } - - btnDock = new ImageButton (); - btnDock.Image = pixAutoHide; - btnDock.TooltipText = GettextCatalog.GetString ("Auto Hide"); - btnDock.CanFocus = false; -// btnDock.WidthRequest = btnDock.HeightRequest = 17; - btnDock.Clicked += OnClickDock; - btnDock.ButtonPressEvent += (o, args) => args.RetVal = true; - btnDock.WidthRequest = btnDock.SizeRequest ().Width; - btnDock.Name = string.Format("btnDock_{0}", labelNoSpaces ?? string.Empty); - UpdateDockButtonAccessibilityLabels (); - - btnClose = new ImageButton (); - btnClose.Image = pixClose; - btnClose.TooltipText = GettextCatalog.GetString ("Close"); - btnClose.CanFocus = false; -// btnClose.WidthRequest = btnClose.HeightRequest = 17; - btnClose.WidthRequest = btnDock.SizeRequest ().Width; - btnClose.Clicked += delegate { - item.Visible = false; - }; - btnClose.ButtonPressEvent += (o, args) => args.RetVal = true; - btnClose.Name = string.Format ("btnClose_{0}", labelNoSpaces ?? string.Empty); - string realLabel, realHelp; - if (string.IsNullOrEmpty (label)) { - realLabel = GettextCatalog.GetString ("Close pad"); - realHelp = GettextCatalog.GetString ("Close the pad"); - } else { - realLabel = GettextCatalog.GetString ("Close {0}", label); - realHelp = GettextCatalog.GetString ("Close the {0} pad", label); - } - btnClose.Accessible.SetLabel (realLabel); - btnClose.Accessible.Description = realHelp; - - Gtk.Alignment al = new Alignment (0, 0.5f, 1, 1); - al.Accessible.SetShouldIgnore (true); - HBox btnBox = new HBox (false, 0); - btnBox.Accessible.SetShouldIgnore (true); - btnBox.PackStart (btnDock, false, false, 3); - btnBox.PackStart (btnClose, false, false, 1); - al.Add (btnBox); - box.PackEnd (al, false, false, 3); - - Add (box); // Get the required size before setting the ellipsize property, since ellipsized labels // have a width request of 0 diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Tabstrip.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Tabstrip.cs index ca25c7f6da..8e383e352a 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Tabstrip.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Components/Tabstrip.cs @@ -113,7 +113,7 @@ namespace MonoDevelop.Components void OnTabPressed (object sender, EventArgs args) { - ActiveTab = tabs.IndexOf (sender); + ActiveTab = tabs.IndexOf ((Tab)sender); } void UpdateAccessibilityTabs () diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionData.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionData.cs index 49f8cb7982..5dd6936f7a 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionData.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeCompletion/CompletionData.cs @@ -192,11 +192,24 @@ namespace MonoDevelop.Ide.CodeCompletion return ApplyDiplayFlagsFormatting (GLib.Markup.EscapeText (DisplayText)); } + [Obsolete("Use OverloadGroupEquals and GetOverloadGroupHashCode")] public virtual bool IsOverload (CompletionData other) { + return true; + } + + public virtual bool OverloadGroupEquals (CompletionData other) + { + if (!IsOverload (other)) + return false; return DisplayText == other.DisplayText; } + public virtual int GetOverloadGroupHashCode ()
+ {
+ return DisplayText.GetHashCode ();
+ } + const string commitChars = " <>()[]{}=+-*/%~&^|!.,;:?\"'"; public virtual bool IsCommitCharacter (char keyChar, string partialWord) diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeTemplates/EditTemplateDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeTemplates/EditTemplateDialog.cs index 9f0c799351..e02b80ba35 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeTemplates/EditTemplateDialog.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.CodeTemplates/EditTemplateDialog.cs @@ -115,6 +115,13 @@ namespace MonoDevelop.Ide.CodeTemplates UpdateVariables (); } + protected override void OnDestroyed ()
+ {
+ textEditor.TextChanged -= DocumentTextReplaced;
+ textEditor.CaretPositionChanged -= CaretPositionChanged;
+ base.OnDestroyed ();
+ } + void ComboboxVariablesChanged (object sender, EventArgs e) { if (comboboxVariables.Active < 0) { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CompletionTextEditorExtension.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CompletionTextEditorExtension.cs index 99fecd0ea8..6e53da2cfb 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CompletionTextEditorExtension.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Extension/CompletionTextEditorExtension.cs @@ -154,8 +154,8 @@ namespace MonoDevelop.Ide.Editor.Extension return res; // Handle code completion if (descriptor.KeyChar != '\0' && CompletionWidget != null && !CompletionWindowManager.IsVisible) { - CurrentCompletionContext = CompletionWidget.CurrentCodeCompletionContext; completionTokenSrc.Cancel (); + CurrentCompletionContext = CompletionWidget.CurrentCodeCompletionContext; completionTokenSrc = new CancellationTokenSource (); var caretOffset = Editor.CaretOffset; var token = completionTokenSrc.Token; @@ -177,7 +177,7 @@ namespace MonoDevelop.Ide.Editor.Extension if (result != null) { int triggerWordLength = result.TriggerWordLength + (Editor.CaretOffset - caretOffset); if (triggerWordLength > 0 && (triggerWordLength < Editor.CaretOffset - || (triggerWordLength == 1 && Editor.CaretOffset == 1))) { + || (triggerWordLength == 1 && Editor.CaretOffset == 1))) { CurrentCompletionContext = CompletionWidget.CreateCodeCompletionContext (Editor.CaretOffset - triggerWordLength); if (result.TriggerWordStart >= 0) CurrentCompletionContext.TriggerOffset = result.TriggerWordStart; @@ -195,9 +195,7 @@ namespace MonoDevelop.Ide.Editor.Extension CurrentCompletionContext = null; } } catch (TaskCanceledException) { - CurrentCompletionContext = null; } catch (AggregateException) { - CurrentCompletionContext = null; } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/EditorTheme.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/EditorTheme.cs index 58ef5ade2c..0c5d86fe4f 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/EditorTheme.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/EditorTheme.cs @@ -179,7 +179,8 @@ namespace MonoDevelop.Ide.Editor.Highlighting return new FontColorStyle (foreground, background, fontStyle); } - foreach (var setting in settings.Skip (1)) { + for (int i = 1; i < settings.Count; ++i) { + var setting = settings[i]; string compatibleScope = null; int depth = 0; if (IsValidScope (setting, scopeStack, ref compatibleScope, ref depth)) { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/Formats/TextMateFormat.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/Formats/TextMateFormat.cs index ff0cb03a32..fb565ca9d3 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/Formats/TextMateFormat.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/Formats/TextMateFormat.cs @@ -477,10 +477,10 @@ namespace MonoDevelop.Ide.Editor.Highlighting case "string": return new PString (f.Value); case "array": - return new PArray (new List<PObject> (f.Nodes ().OfType<XElement> ().Select (Convert))); + return new PArray (new List<PObject> (f.Elements ().Select (Convert))); case "object": var val = new PDictionary (); - foreach (var subElement in f.Nodes ().OfType<XElement> ()) { + foreach (var subElement in f.Elements ()) { var name = subElement.Name.LocalName; if (name == "item") name = subElement.Attribute ("item").Value; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/ISyntaxHighlighting.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/ISyntaxHighlighting.cs index ba9e47fd10..74e555813b 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/ISyntaxHighlighting.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/ISyntaxHighlighting.cs @@ -51,7 +51,7 @@ namespace MonoDevelop.Ide.Editor.Highlighting /// <summary> /// The basic interface for all syntax modes /// </summary> - public interface ISyntaxHighlighting + public interface ISyntaxHighlighting : IDisposable { /// <summary> /// Gets colorized segments (aka chunks) from offset to offset + length. @@ -84,5 +84,9 @@ namespace MonoDevelop.Ide.Editor.Highlighting } public event EventHandler<LineEventArgs> HighlightingStateChanged; + + public void Dispose()
+ {
+ } } }
\ No newline at end of file diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/ScopeStack.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/ScopeStack.cs index 5f37982e07..b3f5d1dbda 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/ScopeStack.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/ScopeStack.cs @@ -33,7 +33,7 @@ namespace MonoDevelop.Ide.Editor.Highlighting { public sealed class ScopeStack : IEnumerable<string> { - public static readonly ScopeStack Empty = new ScopeStack (null, ImmutableStack<string>.Empty, 0); + public static readonly ScopeStack Empty = new ScopeStack (null, ImmutableStack<string>.Empty, 0, null); public string FirstElement { get; @@ -52,30 +52,39 @@ namespace MonoDevelop.Ide.Editor.Highlighting } ImmutableStack<string> stack; - + ScopeStack parent; public ScopeStack (string first) { FirstElement = first; stack = ImmutableStack<string>.Empty.Push (first); + parent = ScopeStack.Empty; Count = 1; - } - - ScopeStack (string first, ImmutableStack<string> immutableStack, int count) + }
+
+ // The reasoning for having a constructor which takes a parent is that we want to make allocations
+ // only onthe less common operation - Push. Having the allocation of the parent ScopeStack happening
+ // on Pop, rather than retaining the one on Push, would yield an allocation hot loop, given that:
+ // We already allocate it once on push.
+ // We pass the same scope stack multiple times.
+ ScopeStack (string first, ImmutableStack<string> immutableStack, int count, ScopeStack parent) { this.FirstElement = first; this.stack = immutableStack; this.Count = count; + this.parent = parent; } public ScopeStack Push (string item) { - return new ScopeStack (FirstElement, stack.Push (item), Count + 1); + return new ScopeStack (FirstElement, stack.Push (item), Count + 1, this); } public ScopeStack Pop () { - return new ScopeStack (FirstElement, stack.Pop (), Count - 1); + if (parent == null) + throw new InvalidOperationException ("ScopeStack is empty"); + return parent; } public string Peek () diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlighting.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlighting.cs index f5ab7db6e6..2a8f10f15f 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlighting.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/SyntaxHighlighting.cs @@ -36,6 +36,12 @@ namespace MonoDevelop.Ide.Editor.Highlighting ((ITextDocument)document).TextChanged += Handle_TextChanged; } + public void Dispose()
+ { + if (Document is ITextDocument) + ((ITextDocument)Document).TextChanged -= Handle_TextChanged;
+ } + async void Handle_TextChanged (object sender, Core.Text.TextChangeEventArgs e) { foreach (var change in e.TextChanges) { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/syntaxes/CSharp/C#.sublime-syntax b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/syntaxes/CSharp/C#.sublime-syntax index 1ee21e10b9..67de212f9f 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/syntaxes/CSharp/C#.sublime-syntax +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.Highlighting/syntaxes/CSharp/C#.sublime-syntax @@ -74,6 +74,10 @@ contexts: numbers: - match: '((\b\d+\.?\d+)|(\.\d+))([eE][+-]?\d*)?(F|f|D|d|M|m)?\b' scope: constant.numeric.float.source.cs + - match: '\d+(([eE][+-]?\d*)?(F|f|D|d|M|m)|([eE][+-]?\d*))\b' + scope: constant.numeric.float.source.cs + - match: '\b0[bB][01_]+(U|u|L|l|UL|Ul|uL|ul|LU|Lu|lU|lu)?\b' + scope: constant.numeric.binary.source.cs - match: '\b(0[xX][0-9a-fA-F]+?|\d+)(U|u|L|l|UL|Ul|uL|ul|LU|Lu|lU|lu)?\b' scope: constant.numeric.source.cs strings: diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.TextMate/TextMateCompletionTextEditorExtension.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.TextMate/TextMateCompletionTextEditorExtension.cs index c340828871..fb5cca77ca 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.TextMate/TextMateCompletionTextEditorExtension.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor.TextMate/TextMateCompletionTextEditorExtension.cs @@ -67,6 +67,7 @@ namespace MonoDevelop.Ide.Editor.TextMate public override void Dispose () { DocumentContext.DocumentParsed -= DocumentContext_DocumentParsed; + base.Dispose (); } void DocumentContext_DocumentParsed (object sender, EventArgs e) diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditor.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditor.cs index d00bcdf9df..643d2d9331 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditor.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Editor/TextEditor.cs @@ -962,6 +962,9 @@ namespace MonoDevelop.Ide.Editor { if (isDisposed) return; + + // Break fileTypeCondition circular event handling reference. + fileTypeCondition = null; isDisposed = true; DetachExtensionChain (); FileNameChanged -= TextEditor_FileNameChanged; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FileProvider.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FileProvider.cs index 0c57a7c40e..5b8b035080 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FileProvider.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FileProvider.cs @@ -60,6 +60,8 @@ namespace MonoDevelop.Ide.FindInFiles set; } + public Encoding CurrentEncoding { get; private set; } + public FileProvider(string fileName) : this(fileName, null) { } @@ -107,7 +109,9 @@ namespace MonoDevelop.Ide.FindInFiles return null; if (!readBinaryFiles && TextFileUtility.IsBinary (FileName)) return null; - return TextFileUtility.OpenStream (FileName); + var sr = TextFileUtility.OpenStream (FileName); + CurrentEncoding = sr.CurrentEncoding; + return sr; } catch (Exception e) { LoggingService.LogError ("Error while opening " + FileName, e); return null; @@ -126,11 +130,12 @@ namespace MonoDevelop.Ide.FindInFiles IDisposable undoGroup; Encoding encoding; - public async void BeginReplace (string content) + public async void BeginReplace (string content, Encoding encoding) { somethingReplaced = false; buffer = new StringBuilder (content); document = await SearchDocument (); + this.encoding = encoding; if (document != null) { Gtk.Application.Invoke (delegate { undoGroup = document.Editor.OpenUndoGroup (); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindReplace.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindReplace.cs index f70545988b..2a90d12253 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindReplace.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/FindReplace.cs @@ -85,6 +85,7 @@ namespace MonoDevelop.Ide.FindInFiles public TextReader Reader; public List<SearchResult> Results; public string Text { get; internal set; } + public System.Text.Encoding Encoding { get; internal set; } public FileSearchResult (FileProvider provider, TextReader reader, List<SearchResult> results) { @@ -172,6 +173,7 @@ namespace MonoDevelop.Ide.FindInFiles Interlocked.Increment (ref searchedFilesCount); if (replacePattern != null) { content.Text = content.Reader.ReadToEnd (); + content.Encoding = content.Provider.CurrentEncoding; content.Reader = new StringReader (content.Text); } content.Results.AddRange(FindAll (monitor, content.Provider, content.Reader, pattern, replacePattern, filter)); @@ -193,7 +195,7 @@ namespace MonoDevelop.Ide.FindInFiles if (content.Results.Count == 0) continue; try { - content.Provider.BeginReplace (content.Text); + content.Provider.BeginReplace (content.Text, content.Encoding); Replace (content.Provider, content.Results, replacePattern); content.Provider.EndReplace (); } catch (Exception e) { @@ -248,7 +250,7 @@ namespace MonoDevelop.Ide.FindInFiles continue; matches.Add(match); } - provider.BeginReplace (content); + provider.BeginReplace (content, provider.CurrentEncoding); int delta = 0; for (int i = 0; !monitor.CancellationToken.IsCancellationRequested && i < matches.Count; i++) { Match match = matches[i]; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/MemberReference.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/MemberReference.cs index 436ebdf1c4..defaf19ef2 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/MemberReference.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.FindInFiles/MemberReference.cs @@ -35,7 +35,9 @@ namespace MonoDevelop.Ide.FindInFiles Unknown = 0, Read = 1, Write = 2, + [Obsolete("Please use Declaration")] Declariton = 4, + Declaration = 4, Keyword = 8, ReadWrite = Read | Write } @@ -84,7 +86,7 @@ namespace MonoDevelop.Ide.FindInFiles public override Components.HslColor GetBackgroundMarkerColor (EditorTheme style) { var key = (ReferenceUsageType & ReferenceUsageType.Write) != 0 || - (ReferenceUsageType & ReferenceUsageType.Declariton) != 0 ? + (ReferenceUsageType & ReferenceUsageType.Declaration) != 0 ? EditorThemeColors.ChangingUsagesRectangle : EditorThemeColors.UsagesRectangle; return SyntaxHighlightingService.GetColor (style, key); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads/SolutionPad.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads/SolutionPad.cs index cc86da7b60..19311a195d 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads/SolutionPad.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Pads/SolutionPad.cs @@ -28,6 +28,8 @@ using System; +using MonoDevelop.Components.AtkCocoaHelper; +using MonoDevelop.Core; using MonoDevelop.Projects; using MonoDevelop.Ide.Gui.Components; @@ -47,6 +49,10 @@ namespace MonoDevelop.Ide.Gui.Pads foreach (WorkspaceItem it in IdeApp.Workspace.Items) treeView.AddChild (it); base.TreeView.Tree.Name = "solutionBrowserTree"; + + base.TreeView.Tree.SetCommonAccessibilityAttributes ("SolutionBrowserTree", + GettextCatalog.GetString ("Solution"), + GettextCatalog.GetString ("Explore the current solution's files and structure")); } protected virtual void OnOpenWorkspace (object sender, WorkspaceItemEventArgs e) diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Wizard/WizardDialogController.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Wizard/WizardDialogController.cs index 8272d504ba..0579001cc5 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Wizard/WizardDialogController.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui.Wizard/WizardDialogController.cs @@ -169,7 +169,7 @@ namespace MonoDevelop.Ide.Gui.Wizard } public override bool CurrentPageIsLast { - get { return Pages.IndexOf (CurrentPage) == Pages.Count - 1; } + get { return pages.IndexOf (CurrentPage) == Pages.Count - 1; } } public WizardDialogController (string title, Image icon, Control rightSideWidget, IWizardDialogPage page) @@ -187,8 +187,8 @@ namespace MonoDevelop.Ide.Gui.Wizard protected override async Task<IWizardDialogPage> OnGoNext (CancellationToken token) { - var currentIndex = Pages.IndexOf (CurrentPage); - if (currentIndex == Pages.Count - 1) + var currentIndex = pages.IndexOf (CurrentPage); + if (currentIndex == pages.Count - 1) throw new InvalidOperationException (); else return pages [currentIndex + 1]; @@ -196,7 +196,7 @@ namespace MonoDevelop.Ide.Gui.Wizard protected override Task<IWizardDialogPage> OnGoBack (CancellationToken token) { - var currentIndex = Pages.IndexOf (CurrentPage); + var currentIndex = pages.IndexOf (CurrentPage); return Task.FromResult (pages [currentIndex - 1]); } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/DefaultWorkbench.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/DefaultWorkbench.cs index b1d65b5ebb..663be3e3d0 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/DefaultWorkbench.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/DefaultWorkbench.cs @@ -1104,7 +1104,7 @@ namespace MonoDevelop.Ide.Gui IdeApp.CommandService.ShowContextMenu (notebook, evt, "/MonoDevelop/Ide/ContextMenu/DocumentTab"); } - internal void OnTabsReordered (Widget widget, int oldPlacement, int newPlacement) + internal void OnTabsReordered (DockNotebookTab widget, int oldPlacement, int newPlacement) { IdeApp.Workbench.ReorderDocuments (oldPlacement, newPlacement); } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Navigation/NavigationHistoryService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Navigation/NavigationHistoryService.cs index be001978cb..0fb3a59b0c 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Navigation/NavigationHistoryService.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Navigation/NavigationHistoryService.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; +using System.Linq; using MonoDevelop.Ide.Gui.Content; using MonoDevelop.Ide.Gui; @@ -40,7 +41,7 @@ namespace MonoDevelop.Ide.Navigation public static class NavigationHistoryService { static HistoryList history = new HistoryList (); - static Stack<Tuple<NavigationPoint, int>> closedHistory = new Stack<Tuple<NavigationPoint, int>> (); + static List<Tuple<NavigationPoint, int>> closedHistory = new List<Tuple<NavigationPoint, int>> (); //used to prevent re-logging the current point during a switch static bool switching; @@ -58,16 +59,22 @@ namespace MonoDevelop.Ide.Navigation { IdeApp.Workspace.LastWorkspaceItemClosed += delegate { history.Clear (); - closedHistory.Clear (); OnHistoryChanged (); + closedHistory.Clear (); + OnClosedHistoryChanged (); + }; + + IdeApp.Workbench.DocumentOpened += delegate (object sender, DocumentEventArgs e) {
+ closedHistory.RemoveAll(np => (np.Item1 as DocumentNavigationPoint)?.FileName == e.Document.FileName);
+ OnClosedHistoryChanged ();
}; IdeApp.Workbench.DocumentClosing += delegate(object sender, DocumentEventArgs e) { - NavigationPoint point = GetNavPointForDoc (e.Document); + NavigationPoint point = GetNavPointForDoc (e.Document, true) as DocumentNavigationPoint; if (point == null) return; - - closedHistory.Push (new Tuple<NavigationPoint, int> (point, IdeApp.Workbench.Documents.IndexOf (e.Document))); + + closedHistory.Add (new Tuple<NavigationPoint, int> (point, IdeApp.Workbench.Documents.IndexOf (e.Document))); OnClosedHistoryChanged (); }; @@ -90,7 +97,7 @@ namespace MonoDevelop.Ide.Navigation if (switching) return; - NavigationPoint point = GetNavPointForActiveDoc (); + NavigationPoint point = GetNavPointForActiveDoc (false); if (point == null) return; @@ -135,17 +142,17 @@ namespace MonoDevelop.Ide.Navigation currentIsTransient = transient; } else - point.Dispose (); + item.Dispose (); OnHistoryChanged (); } - static NavigationPoint GetNavPointForActiveDoc () + static NavigationPoint GetNavPointForActiveDoc (bool forClosedHistory) { - return GetNavPointForDoc (IdeApp.Workbench.ActiveDocument); + return GetNavPointForDoc (IdeApp.Workbench.ActiveDocument, forClosedHistory); } - static NavigationPoint GetNavPointForDoc (Document doc) + static NavigationPoint GetNavPointForDoc (Document doc, bool forClosedHistory) { if (doc == null) return null; @@ -161,7 +168,11 @@ namespace MonoDevelop.Ide.Navigation var editBuf = doc.Editor; if (editBuf != null) { - point = new TextFileNavigationPoint (doc, editBuf); + if (forClosedHistory) {
+ point = new TextFileNavigationPoint (doc.FileName, editBuf.CaretLine, editBuf.CaretColumn);
+ } else {
+ point = new TextFileNavigationPoint (doc, editBuf);
+ } if (point != null) return point; } @@ -226,9 +237,13 @@ namespace MonoDevelop.Ide.Navigation public static async void OpenLastClosedDocument () { if (HasClosedDocuments) { - var tuple = closedHistory.Pop (); + int closedHistoryIndex = closedHistory.Count - 1; + var tuple = closedHistory[closedHistoryIndex]; + closedHistory.RemoveAt (closedHistoryIndex); + OnClosedHistoryChanged (); var doc = await tuple.Item1.ShowDocument (); - IdeApp.Workbench.ReorderTab (IdeApp.Workbench.Documents.IndexOf (doc), tuple.Item2); + if (doc != null) + IdeApp.Workbench.ReorderTab (IdeApp.Workbench.Documents.IndexOf (doc), tuple.Item2); } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewConfigurationDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewConfigurationDialog.cs index 39d4104a4e..64888728c7 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewConfigurationDialog.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewConfigurationDialog.cs @@ -26,6 +26,7 @@ // using System.Collections.Generic; +using MonoDevelop.Components.AtkCocoaHelper; using MonoDevelop.Core; using MonoDevelop.Projects; using MonoDevelop.Ide.Gui.Dialogs; @@ -59,8 +60,28 @@ namespace MonoDevelop.Ide.Projects createChildrenCheck.Visible = false; DefaultHeight = 0; } + + SetupAccessibility (); } - + + void SetupAccessibility () + { + comboName.SetCommonAccessibilityAttributes ("NewConfiguration.Name", + GettextCatalog.GetString ("Name"), + GettextCatalog.GetString ("Select or enter the name of the new configuration")); + comboName.Accessible.SetTitleUIElement (label1.Accessible); + label1.Accessible.SetTitleFor (comboName.Accessible); + + comboPlatform.SetCommonAccessibilityAttributes ("NewConfiguration.Platform", + GettextCatalog.GetString ("Platform"), + GettextCatalog.GetString ("Select or enter the platform for the new configuration")); + comboPlatform.Accessible.SetTitleUIElement (label2.Accessible); + label2.Accessible.SetTitleFor (comboPlatform.Accessible); + + createChildrenCheck.SetCommonAccessibilityAttributes ("NewConfiguration.CreateCheck", null, + GettextCatalog.GetString ("Check to create configurations for all the solution items")); + } + public string ConfigName { get { string plat = MultiConfigItemOptionsPanel.GetPlatformId (comboPlatform.Entry.Text.Trim ()); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewFileDialog.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewFileDialog.cs index c9cd9eb305..54d1a3e1d5 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewFileDialog.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Projects/NewFileDialog.cs @@ -104,8 +104,9 @@ namespace MonoDevelop.Ide.Projects iconView.Accessible.Description = GettextCatalog.GetString ("Select a template for the new file"); iconView.Accessible.SetTitle (GettextCatalog.GetString ("Templates")); - nameEntry.Accessible.Name = "NewFileDialog.NameEntry"; - nameEntry.Accessible.Description = GettextCatalog.GetString ("Enter the name of the new file"); + nameEntry.SetCommonAccessibilityAttributes ("NewFileDialog.NameEntry", + GettextCatalog.GetString ("Name"), + GettextCatalog.GetString ("Enter the name of the new file")); nameEntry.Accessible.SetTitleUIElement (label1.Accessible); label1.Accessible.Name = "NewFileDialog.NameLabel"; diff --git a/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests/SmartIndentModeTests.cs b/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests/SmartIndentModeTests.cs index 201239ee2f..6fc9c9d6cd 100644 --- a/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests/SmartIndentModeTests.cs +++ b/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests/SmartIndentModeTests.cs @@ -41,6 +41,12 @@ namespace Mono.TextEditor.Tests { string indentString; + public override IndentationTrackerFeatures SupportedFeatures { + get { + return IndentationTrackerFeatures.All; + } + } + public TestIndentTracker (string indentString = "\t\t") { this.indentString = indentString; diff --git a/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests/SyntaxHighlightingTests.cs b/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests/SyntaxHighlightingTests.cs index f9ebce11a9..6effd06efd 100644 --- a/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests/SyntaxHighlightingTests.cs +++ b/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests/SyntaxHighlightingTests.cs @@ -177,5 +177,26 @@ namespace Mono.TextEditor.Tests "<span foreground=\"#e5da73\">$@\"test\"</span><span foreground=\"#eeeeec\"> </span><span foreground=\"#888a85\">// test</span>"); } + /// <summary> + /// Bug 55670 - color scheme not working on floating point literals without decimal points + /// </summary> + [Test] + public void Test55670 () + { + TestOutput ("0.5f", + "<span foreground=\"#8ae232\">0.5f</span>"); + TestOutput ("5f", + "<span foreground=\"#8ae232\">5f</span>"); + TestOutput ("2e64", + "<span foreground=\"#8ae232\">2e64</span>"); + } + + [Test] + public void TestBinaryLiteral () + { + TestOutput ("0b1111_0000", + "<span foreground=\"#8ae232\">0b1111_0000</span>"); + } + } } diff --git a/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests/VirtualIndentModeTests.cs b/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests/VirtualIndentModeTests.cs index ea522bb845..0398540887 100644 --- a/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests/VirtualIndentModeTests.cs +++ b/main/src/core/MonoDevelop.TextEditor.Tests/Mono.TextEditor.Tests/VirtualIndentModeTests.cs @@ -445,6 +445,18 @@ namespace Mono.TextEditor.Tests } + class TestBug15476IndentationTracker : DefaultIndentationTracker + { + public override IndentationTrackerFeatures SupportedFeatures { + get { + return IndentationTrackerFeatures.All; + } + } + + public TestBug15476IndentationTracker (TextDocument doc) : base (doc) + { + } + } /// <summary> /// Bug 15476 - Cursor is getting stuck when deleting last empty line with indents /// </summary> @@ -453,7 +465,7 @@ namespace Mono.TextEditor.Tests { var data = CreateData ("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\r\n\t\t\r\n\r\n"); data.Options.DefaultEolMarker = "\r\n"; - data.IndentationTracker = new DefaultIndentationTracker (data.Document); + data.IndentationTracker = new TestBug15476IndentationTracker (data.Document); data.Caret.Location = new DocumentLocation (4, 3); DeleteActions.Backspace (data); diff --git a/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/NR5/CodeCompletionAccessibleTests.cs b/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/NR5/CodeCompletionAccessibleTests.cs index 7940db1b07..d33d9616aa 100644 --- a/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/NR5/CodeCompletionAccessibleTests.cs +++ b/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/NR5/CodeCompletionAccessibleTests.cs @@ -1574,7 +1574,7 @@ class Test } } ", provider => { - Assert.AreEqual (1, provider.Count (p => p.DisplayText == "test")); + Assert.AreEqual (1, provider.Data.Count (p => p.DisplayText == "test")); }); } @@ -1596,7 +1596,7 @@ class Test } } ", provider => { - Assert.AreEqual (1, provider.Count (p => p.DisplayText == "Foo")); + Assert.AreEqual (1, provider.Data.Count (p => p.DisplayText == "Foo")); var data = provider.Find ("Foo"); Assert.AreEqual (3, data.OverloadedData.Count ()); diff --git a/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/NR5/CodeCompletionBugTests.cs b/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/NR5/CodeCompletionBugTests.cs index ca4dbd8b8c..5a018a176d 100644 --- a/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/NR5/CodeCompletionBugTests.cs +++ b/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/NR5/CodeCompletionBugTests.cs @@ -1891,7 +1891,7 @@ public class MyClass C myclass = new C (); $myclass.$ } -}", provider => Assert.AreEqual(1, provider.Count(c => c.DisplayText == "MouseClick"))); +}", provider => Assert.AreEqual(1, provider.Data.Count(c => c.DisplayText == "MouseClick"))); } /// <summary> @@ -4929,7 +4929,7 @@ class B : A } "); - Assert.AreEqual(2, provider.Count(d => d.DisplayText == "Method")); + Assert.AreEqual(2, provider.Data.Count(d => d.DisplayText == "Method")); } /// <summary> @@ -6086,9 +6086,9 @@ class Test } "); Assert.IsNotNull (provider, "provider not found."); - Assert.AreEqual(1, provider.Count(cd => cd.DisplayText == "async delegate")); - Assert.AreEqual(1, provider.Count(cd => cd.DisplayText == "() =>")); - Assert.AreEqual(1, provider.Count(cd => cd.DisplayText == "async () =>")); + Assert.AreEqual(1, provider.Data.Count(cd => cd.DisplayText == "async delegate")); + Assert.AreEqual(1, provider.Data.Count(cd => cd.DisplayText == "() =>")); + Assert.AreEqual(1, provider.Data.Count(cd => cd.DisplayText == "async () =>")); } [Ignore] @@ -6154,7 +6154,7 @@ namespace Foo } } } -", provider => provider.Single(d => d.DisplayText == "Foo")); +", provider => provider.Data.Single(d => d.DisplayText == "Foo")); } /// <summary> diff --git a/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/NR5/CompletionDataList.cs b/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/NR5/CompletionDataList.cs index 8b436c4b98..f4ca873a6b 100644 --- a/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/NR5/CompletionDataList.cs +++ b/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/NR5/CompletionDataList.cs @@ -35,7 +35,7 @@ namespace ICSharpCode.NRefactory6.CSharp.CodeCompletion { public static CompletionData Find (this CompletionResult result, string name, bool includeImportData = false) { - return result.FirstOrDefault (d => /*(!(d is CodeCompletionBugTests.TestFactory.ImportCompletionData) || includeImportData) &&*/ d.CompletionText == name); + return result.Data.FirstOrDefault (d => /*(!(d is CodeCompletionBugTests.TestFactory.ImportCompletionData) || includeImportData) &&*/ d.CompletionText == name); } } } diff --git a/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/NR5/ImportCompletionTests.cs b/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/NR5/ImportCompletionTests.cs index 00d90621ee..236cc390eb 100644 --- a/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/NR5/ImportCompletionTests.cs +++ b/main/tests/MonoDevelop.CSharpBinding.Tests/Features/CodeCompletion/NR5/ImportCompletionTests.cs @@ -55,7 +55,7 @@ namespace ICSharpCode.NRefactory6.CSharp.CodeCompletion var ext = new CSharpCompletionTextEditorExtension (); var list = new CSharpCompletionTextEditorExtension.CSharpCompletionDataList (); var result = CodeCompletionBugTests.CreateProvider (text); - list.AddRange (result); + list.AddRange (result.Data); ext.AddImportCompletionData (result, list, new RoslynCodeCompletionFactory (ext, semanticModel), semanticModel, cursorPosition); return list; |