public static IEnumerable <AttributeListSyntax> SplitAttributes(AttributeListSyntax attributeList) { if (attributeList == null) { throw new ArgumentNullException(nameof(attributeList)); } SeparatedSyntaxList <AttributeSyntax> attributes = attributeList.Attributes; for (int i = 0; i < attributes.Count; i++) { AttributeListSyntax list = AttributeList(attributes[i]); if (i == 0) { list = list.WithLeadingTrivia(attributeList.GetLeadingTrivia()); } if (i == attributes.Count - 1) { list = list.WithTrailingTrivia(attributeList.GetTrailingTrivia()); } yield return(list.WithFormatterAnnotation()); } }
public static IEnumerable <AttributeListSyntax> SplitAttributes(AttributeListSyntax attributeList) { if (attributeList == null) { throw new ArgumentNullException(nameof(attributeList)); } for (int i = 0; i < attributeList.Attributes.Count; i++) { AttributeListSyntax list = SyntaxFactory.AttributeList( SyntaxFactory.SingletonSeparatedList(attributeList.Attributes[i])); if (i == 0) { list = list.WithLeadingTrivia(attributeList.GetLeadingTrivia()); } if (i == attributeList.Attributes.Count - 1) { list = list.WithTrailingTrivia(attributeList.GetTrailingTrivia()); } yield return(list); } }
public static AttributeListSyntax JoinAttributes(IList <AttributeListSyntax> lists) { AttributeListSyntax list = lists[0]; for (int i = 1; i < lists.Count; i++) { list = list.AddAttributes(lists[i].Attributes.ToArray()); } return(list .WithLeadingTrivia(lists[0].GetLeadingTrivia()) .WithTrailingTrivia(lists.Last().GetTrailingTrivia())); }
public static AttributeListSyntax MergeAttributes(AttributeListSyntax[] lists) { AttributeListSyntax list = lists[0]; for (int i = 1; i < lists.Length; i++) { list = list.AddAttributes(lists[i].Attributes.ToArray()); } return(list .WithLeadingTrivia(lists[0].GetLeadingTrivia()) .WithTrailingTrivia(lists.Last().GetTrailingTrivia()) .WithFormatterAnnotation()); }
public override SyntaxNode VisitAttributeList(AttributeListSyntax attributeListNode) { _cancellationToken.ThrowIfCancellationRequested(); if (_visitedAttributeListCounter < MaxVisitedAttributesCount) { _visitedAttributeListCounter++; } var attributesToCheck = attributeListNode.Attributes; var modifiedAttributes = new List <AttributeSyntax>(attributesToCheck.Count); foreach (AttributeSyntax attribute in attributesToCheck) { _cancellationToken.ThrowIfCancellationRequested(); if (!IsAttributeToRemove(attribute)) { modifiedAttributes.Add(attribute); } } bool allPreviousAttributeListWereRemoved = _attributeListsRemovedCounter > 0 && _attributeListsRemovedCounter == (_visitedAttributeListCounter - 1); if (modifiedAttributes.Count == attributesToCheck.Count && !allPreviousAttributeListWereRemoved) { return(attributeListNode); } else if (modifiedAttributes.Count == 0) { if (_attributeListsRemovedCounter < MaxRemovedAttributesCount) { _attributeListsRemovedCounter++; } return(null); } AttributeListSyntax modifiedAttributeListNode = attributeListNode.WithAttributes(SyntaxFactory.SeparatedList(modifiedAttributes)); if (allPreviousAttributeListWereRemoved) { var trivia = modifiedAttributeListNode.GetLeadingTrivia().Prepend(SyntaxFactory.CarriageReturnLineFeed); modifiedAttributeListNode = modifiedAttributeListNode.WithLeadingTrivia(trivia); } return(modifiedAttributeListNode); }
public static AttributeListSyntax MergeAttributes(AttributeListSyntax[] attributeLists) { if (attributeLists == null) { throw new ArgumentNullException(nameof(attributeLists)); } AttributeListSyntax attributeList = attributeLists[0]; for (int i = 1; i < attributeLists.Length; i++) { attributeList = attributeList.AddAttributes(attributeLists[i].Attributes.ToArray()); } return(attributeList .WithLeadingTrivia(attributeLists.First().GetLeadingTrivia()) .WithTrailingTrivia(attributeLists.Last().GetTrailingTrivia())); }
public static AttributeListSyntax MergeAttributes(AttributeListSyntax[] lists) { if (lists == null) { throw new ArgumentNullException(nameof(lists)); } AttributeListSyntax list = lists[0]; for (int i = 1; i < lists.Length; i++) { list = list.AddAttributes(lists[i].Attributes.ToArray()); } return(list .WithLeadingTrivia(lists[0].GetLeadingTrivia()) .WithTrailingTrivia(lists.Last().GetTrailingTrivia()) .WithFormatterAnnotation()); }
public static IEnumerable <AttributeListSyntax> SplitAttributeList(AttributeListSyntax attributeList) { SeparatedSyntaxList <AttributeSyntax> attributes = attributeList.Attributes; for (int i = 0; i < attributes.Count; i++) { AttributeListSyntax list = AttributeList(attributes[i]); if (i == 0) { list = list.WithLeadingTrivia(attributeList.GetLeadingTrivia()); } if (i == attributes.Count - 1) { list = list.WithTrailingTrivia(attributeList.GetTrailingTrivia()); } yield return(list); } }
private T ApplyAction <T>(T node, ISymbol symbol, UpdateAction updateAction) where T : MemberDeclarationSyntax { var attributes = symbol.GetAttributes(); var attribute = attributes.SingleOrDefault(a => a.AttributeClass.ToString() == UsedNuGetSdkApiAttribute.FullName); T newNode = null; if (updateAction.AddAttribute && attribute == null) { if (node.AttributeLists.Count > 0) { var leadingTrivia = node.GetLeadingTrivia(); var whitespace = leadingTrivia.Last(t => t.IsKind(SyntaxKind.WhitespaceTrivia)); newNode = (T)node.AddAttributeLists(attributeListToAdd.WithLeadingTrivia(whitespace)); } else { var leadingTrivia = node.GetLeadingTrivia(); if (leadingTrivia.Count == 1 && leadingTrivia[0].IsKind(SyntaxKind.WhitespaceTrivia)) { newNode = (T)node.AddAttributeLists(attributeListToAdd.WithLeadingTrivia(leadingTrivia[0])); } else { var whitespaceTrivia = leadingTrivia.First(t => t.IsKind(SyntaxKind.WhitespaceTrivia)); newNode = (T)node .WithLeadingTrivia(whitespaceTrivia) .AddAttributeLists(attributeListToAdd.WithLeadingTrivia(leadingTrivia)); } } } else if (!updateAction.AddAttribute && attribute != null) { var newAttributeLists = node.AttributeLists .Select(al => { AttributeSyntax toRemove = null; foreach (var attr in al.Attributes) { var type = _semanticModel.GetTypeInfo(attr); if (type.Type == null) { throw new NotSupportedException("AttributeSyntax's TypeInfo doesn't have a type"); } if (type.Type.ToString() == UsedNuGetSdkApiAttribute.FullName) { toRemove = attr; break; } } if (toRemove == null) { return(al); } return(SyntaxFactory.AttributeList(SyntaxFactory.SeparatedList(al.Attributes.Where(a => a != toRemove)))); }) .Where(al => al != null && al.Attributes.Count > 0); var leadingTrivia = node.GetLeadingTrivia(); newNode = (T)node.WithAttributeLists(SyntaxFactory.List(newAttributeLists)) .WithLeadingTrivia(leadingTrivia); } if (newNode != null) { if (updateAction.Actioned) { // already actioned? } updateAction.SetActioned(); return(newNode); } else { return(node); } }
public MethodTransformerResult Transform(IMethodOrAccessorTransformationResult transformResult, ITypeTransformationMetadata typeMetadata, INamespaceTransformationMetadata namespaceMetadata) { var methodResult = transformResult.AnalyzationResult; if (!methodResult.Missing || !methodResult.Conversion.HasFlag(MethodConversion.ToAsync) || methodResult.Symbol.IsObsolete()) { return(MethodTransformerResult.Skip); } var methodNode = transformResult.Transformed; var baseMethod = methodResult.RelatedMethods .Where(o => (methodResult.BaseOverriddenMethod != null && o.Symbol.Equals(methodResult.BaseOverriddenMethod)) || methodResult.ImplementedInterfaces.Any(i => o.Symbol.Equals(i))) .FirstOrDefault(o => o.AsyncCounterpartSymbol?.IsObsolete() == true); if (baseMethod == null) { return(MethodTransformerResult.Skip); } namespaceMetadata.AddUsing("System"); AttributeListSyntax obsoleteAttribute = null; var syntaxReference = baseMethod.AsyncCounterpartSymbol.DeclaringSyntaxReferences.SingleOrDefault(); SyntaxTrivia?documentationTrivia = null; if (syntaxReference != null) { var baseMethodNode = syntaxReference.GetSyntax() as MethodDeclarationSyntax; obsoleteAttribute = baseMethodNode?.AttributeLists.FirstOrDefault(o => o.Attributes.Count == 1 && o.Attributes.First().Name.ToString() == "Obsolete"); obsoleteAttribute = (AttributeListSyntax)_directiveRemover.VisitAttributeList(obsoleteAttribute); documentationTrivia = obsoleteAttribute.GetLeadingTrivia() .Select(o => o.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia) ? o : (SyntaxTrivia?)null) .FirstOrDefault(o => o.HasValue); } if (obsoleteAttribute == null) { obsoleteAttribute = AttributeList(SingletonSeparatedList(Attribute(IdentifierName("Obsolete")))) .WithOpenBracketToken(Token(TriviaList(transformResult.LeadingWhitespaceTrivia), SyntaxKind.OpenBracketToken, TriviaList())) .WithCloseBracketToken(Token(TriviaList(), SyntaxKind.CloseBracketToken, TriviaList(transformResult.EndOfLineTrivia))); } var inheritDocTrivia = Trivia(GetInheritdoc(transformResult.EndOfLineTrivia.ToFullString())); if (documentationTrivia.HasValue) { obsoleteAttribute = obsoleteAttribute.WithLeadingTrivia(obsoleteAttribute.GetLeadingTrivia() .Replace(documentationTrivia.Value, inheritDocTrivia)); } else { // Append <inheritdoc /> var leadingTrivia = obsoleteAttribute.GetLeadingTrivia(); var trivias = new List <SyntaxTrivia>(); if (leadingTrivia.Count == 0 || !leadingTrivia.Last().IsKind(SyntaxKind.WhitespaceTrivia)) { trivias.Add(transformResult.LeadingWhitespaceTrivia); } trivias.Add(inheritDocTrivia); trivias.Add(transformResult.LeadingWhitespaceTrivia); obsoleteAttribute = obsoleteAttribute.WithLeadingTrivia(leadingTrivia.AddRange(trivias)); } methodNode = methodNode .WithLeadingTrivia(TriviaList(transformResult.LeadingWhitespaceTrivia)) .WithAttributeLists(methodNode.AttributeLists.Add(obsoleteAttribute)); return(MethodTransformerResult.Update(methodNode)); }
public override SyntaxNode VisitFieldDeclaration(FieldDeclarationSyntax node) { FieldDeclarationSyntax fieldDeclaration = (FieldDeclarationSyntax)base.VisitFieldDeclaration(node); var typeInfo = model.GetTypeInfo(node.Declaration.Type); if (typeInfo.Type == null) { UdonSharpUtils.LogWarning($"Could not find symbol for {node}"); return(fieldDeclaration); } ITypeSymbol rootType = typeInfo.Type; while (rootType.TypeKind == TypeKind.Array) { rootType = ((IArrayTypeSymbol)rootType).ElementType; } if (rootType.TypeKind == TypeKind.Error || rootType.TypeKind == TypeKind.Unknown) { UdonSharpUtils.LogWarning($"Type {typeInfo.Type} for field '{fieldDeclaration.Declaration}' is invalid"); return(fieldDeclaration); } IFieldSymbol firstFieldSymbol = (IFieldSymbol)model.GetDeclaredSymbol(node.Declaration.Variables.First()); rootType = firstFieldSymbol.Type; // If the field is not serialized or is using Odin already, we don't need to do anything. if (!IsFieldSerializedWithoutOdin(firstFieldSymbol)) { return(fieldDeclaration); } // Getting the type may fail if it's a user type that hasn't compiled on the C# side yet. For now we skip it, but we should do a simplified check for jagged arrays if (!TypeSymbol.TryGetSystemType(rootType, out Type systemType)) { return(fieldDeclaration); } // If Unity can serialize the type, we're good if (UnitySerializationUtility.GuessIfUnityWillSerialize(systemType)) { return(fieldDeclaration); } // Common type that gets picked up as serialized but shouldn't be // todo: Add actual checking for if a type is serializable, which isn't consistent. Unity/System library types in large part are serializable but don't have the System.Serializable tag, but types outside those assemblies need the tag to be serialized. if (systemType == typeof(VRCPlayerApi) || systemType == typeof(VRCPlayerApi[])) { return(fieldDeclaration); } Modified = true; NameSyntax odinSerializeName = IdentifierName("VRC"); odinSerializeName = QualifiedName(odinSerializeName, IdentifierName("Udon")); odinSerializeName = QualifiedName(odinSerializeName, IdentifierName("Serialization")); odinSerializeName = QualifiedName(odinSerializeName, IdentifierName("OdinSerializer")); odinSerializeName = QualifiedName(odinSerializeName, IdentifierName("OdinSerialize")); // Somehow it seems like there's literally no decent way to maintain the indent on inserted code so we'll just inline the comment because Roslyn is dumb SyntaxTrivia commentTrivia = Comment(" /* UdonSharp auto-upgrade: serialization */ "); AttributeListSyntax newAttribList = AttributeList(SeparatedList(new [] { Attribute(odinSerializeName) })).WithTrailingTrivia(commentTrivia); SyntaxList <AttributeListSyntax> attributeList = fieldDeclaration.AttributeLists; if (attributeList.Count > 0) { SyntaxTriviaList trailingTrivia = attributeList.Last().GetTrailingTrivia(); trailingTrivia = trailingTrivia.Insert(0, commentTrivia); attributeList.Replace(attributeList[attributeList.Count - 1], attributeList[attributeList.Count - 1].WithoutTrailingTrivia()); newAttribList = newAttribList.WithTrailingTrivia(trailingTrivia); } else { newAttribList = newAttribList.WithLeadingTrivia(fieldDeclaration.GetLeadingTrivia()); fieldDeclaration = fieldDeclaration.WithoutLeadingTrivia(); } attributeList = attributeList.Add(newAttribList); return(fieldDeclaration.WithAttributeLists(attributeList)); }