Skip to content

Commit 508a128

Browse files
committed
Fix #1225: Guard IsOutAttribute/IsExtensionAttribute against cross-tree attributes
When a parameter is defined in an external assembly or different source file, its AttributeSyntax nodes belong to a different syntax tree than the current semantic model. Calling SemanticModel.GetTypeInfo on such nodes throws "Node is not within syntax tree". Fall back to a name-based check when the attribute's syntax tree differs from the model's tree. https://claude.ai/code/session_01AkwUvu3XuCdj3D4axoX4UX
1 parent 0e1ce42 commit 508a128

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

CodeConverter/CSharp/CommonConversions.cs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,11 +664,33 @@ public bool HasOutAttribute(VBSyntax.AttributeListSyntax a)
664664

665665
public bool IsExtensionAttribute(VBSyntax.AttributeSyntax a)
666666
{
667+
// Guard against attributes from a different syntax tree (see IsOutAttribute for details).
668+
if (a.SyntaxTree != SemanticModel.SyntaxTree) {
669+
var name = a.Name.ToString();
670+
return name.Equals("Extension", StringComparison.Ordinal) ||
671+
name.Equals("ExtensionAttribute", StringComparison.Ordinal) ||
672+
name.EndsWith(".Extension", StringComparison.Ordinal) ||
673+
name.EndsWith(".ExtensionAttribute", StringComparison.Ordinal);
674+
}
667675
return (SemanticModel.GetTypeInfo(a).ConvertedType?.GetFullMetadataName())
668676
?.Equals(ExtensionAttributeType.FullName, StringComparison.Ordinal) == true;
669677
}
670678

671-
public bool IsOutAttribute(VBSyntax.AttributeSyntax a) => SemanticModel.GetTypeInfo(a).ConvertedType.IsOutAttribute();
679+
public bool IsOutAttribute(VBSyntax.AttributeSyntax a)
680+
{
681+
// If the attribute's syntax tree differs from the current semantic model's tree (e.g. the
682+
// parameter is declared in another source file or in a metadata assembly), calling
683+
// SemanticModel.GetTypeInfo on it throws "Knoten ist nicht innerhalb Syntaxbaum" /
684+
// "Node is not within syntax tree". Fall back to a name-based check in that case.
685+
if (a.SyntaxTree != SemanticModel.SyntaxTree) {
686+
var name = a.Name.ToString();
687+
return name.Equals("Out", StringComparison.Ordinal) ||
688+
name.Equals("OutAttribute", StringComparison.Ordinal) ||
689+
name.EndsWith(".Out", StringComparison.Ordinal) ||
690+
name.EndsWith(".OutAttribute", StringComparison.Ordinal);
691+
}
692+
return SemanticModel.GetTypeInfo(a).ConvertedType.IsOutAttribute();
693+
}
672694

673695
public ISymbol GetCsOriginalSymbolOrNull(ISymbol symbol)
674696
{

0 commit comments

Comments
 (0)