diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs index bbd3f8d9d9fb2ce57bb4d92caa21603a9f35193f..f45e84a120eec9b6468fb2e807c1b886cb54ea68 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceMemberContainerSymbol.cs @@ -12,6 +12,7 @@ using Microsoft.CodeAnalysis.CSharp.Symbols; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.PooledObjects; +using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; namespace Microsoft.CodeAnalysis.CSharp.Symbols @@ -868,6 +869,30 @@ public override ImmutableArray DeclaringSyntaxReferences } } + // This method behaves the same was as the base class, but avoids allocations associated with DeclaringSyntaxReferences + internal override bool IsDefinedInSourceTree(SyntaxTree tree, TextSpan? definedWithinSpan, CancellationToken cancellationToken) + { + var declarations = declaration.Declarations; + if (IsImplicitlyDeclared && declarations.IsEmpty) + { + return ContainingSymbol.IsDefinedInSourceTree(tree, definedWithinSpan, cancellationToken); + } + + foreach (var declaration in declarations) + { + cancellationToken.ThrowIfCancellationRequested(); + + var syntaxRef = declaration.SyntaxReference; + if (syntaxRef.SyntaxTree == tree && + (!definedWithinSpan.HasValue || syntaxRef.Span.IntersectsWith(definedWithinSpan.Value))) + { + return true; + } + } + + return false; + } + #endregion #region Members diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol.cs index 7e898bcb41b121eb9759d44cb722533d4c08cb57..31e2fda8ef2b9593d2ca384852b0c54e68e06135 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceNamespaceSymbol.cs @@ -463,11 +463,12 @@ internal override bool IsDefinedInSourceTree(SyntaxTree tree, TextSpan? definedW } // Check if any namespace declaration block intersects with the given tree/span. - foreach (var syntaxRef in this.DeclaringSyntaxReferences) + foreach (var declaration in _mergedDeclaration.Declarations) { cancellationToken.ThrowIfCancellationRequested(); - if (syntaxRef.SyntaxTree != tree) + var declarationSyntaxRef = declaration.SyntaxReference; + if (declarationSyntaxRef.SyntaxTree != tree) { continue; } @@ -477,7 +478,7 @@ internal override bool IsDefinedInSourceTree(SyntaxTree tree, TextSpan? definedW return true; } - var syntax = syntaxRef.GetSyntax(cancellationToken); + var syntax = NamespaceDeclarationSyntaxReference.GetSyntax(declarationSyntaxRef, cancellationToken); if (syntax.FullSpan.IntersectsWith(definedWithinSpan.Value)) { return true; diff --git a/src/Compilers/CSharp/Portable/Syntax/NamespaceDeclarationSyntaxReference.cs b/src/Compilers/CSharp/Portable/Syntax/NamespaceDeclarationSyntaxReference.cs index 0777a7e5a7e572391243f3302a239e40c853b9d3..fba51c073175f9e887262dff989fd398f927c918 100644 --- a/src/Compilers/CSharp/Portable/Syntax/NamespaceDeclarationSyntaxReference.cs +++ b/src/Compilers/CSharp/Portable/Syntax/NamespaceDeclarationSyntaxReference.cs @@ -2,8 +2,8 @@ using System.Diagnostics; using System.Threading; -using Microsoft.CodeAnalysis.Syntax; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Syntax; namespace Microsoft.CodeAnalysis.CSharp { @@ -19,6 +19,11 @@ public NamespaceDeclarationSyntaxReference(SyntaxReference reference) } protected override SyntaxNode Translate(SyntaxReference reference, CancellationToken cancellationToken) + { + return GetSyntax(reference, cancellationToken); + } + + internal static SyntaxNode GetSyntax(SyntaxReference reference, CancellationToken cancellationToken) { var node = (CSharpSyntaxNode)reference.GetSyntax(cancellationToken);