public override RichText GetSignature(string[] namedArguments, AnnotationsDisplayKind showAnnotations, out TextRange[] parameterRanges, out int[] mapToOriginalOrder, out ExtensionMethodInfo extensionMethodInfo) { var parameters = myCandidate.StaticParameters; var text = new StringBuilder(myTypeName + "<"); var newParameterRanges = new TextRange[parameters.Length]; var originalOrder = new int[parameters.Length]; for (var i = 0; i < parameters.Length; i++) { var paramRangeStart = text.Length; text.Append(parameters[i].Display); var paramRangeEnd = text.Length; newParameterRanges[i] = new TextRange(paramRangeStart, paramRangeEnd); if (i < parameters.Length - 1) { text.Append(", "); } } text.Append(">"); extensionMethodInfo = ExtensionMethodInfo.NoExtension; parameterRanges = newParameterRanges; mapToOriginalOrder = originalOrder; return(text.ToString()); }
internal static void AnalyzeInvocationExpression(SyntaxNodeAnalysisContext context) { var invocation = (InvocationExpressionSyntax)context.Node; ExpressionSyntax expression = invocation.Expression; if (expression?.IsKind(SyntaxKind.SimpleMemberAccessExpression) == true) { var memberAccess = (MemberAccessExpressionSyntax)expression; ArgumentListSyntax argumentList = invocation.ArgumentList; if (argumentList?.IsMissing == false) { SeparatedSyntaxList <ArgumentSyntax> arguments = argumentList.Arguments; if (arguments.Count == 0) { SimpleNameSyntax name = memberAccess.Name; if (name != null) { string methodName = name.Identifier.ValueText; if (methodName == "Cast") { SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; ExtensionMethodInfo info = semanticModel.GetExtensionMethodInfo(invocation, ExtensionMethodKind.Reduced, cancellationToken); if (info.MethodInfo.IsLinqCast()) { ImmutableArray <ITypeSymbol> typeArguments = info.ReducedSymbol.TypeArguments; if (typeArguments.Length == 1) { ExpressionSyntax memberAccessExpression = memberAccess.Expression; if (memberAccessExpression != null) { var memberAccessExpressionType = semanticModel.GetTypeSymbol(memberAccessExpression, cancellationToken) as INamedTypeSymbol; if (memberAccessExpressionType?.IsConstructedFromIEnumerableOfT() == true && typeArguments[0].Equals(memberAccessExpressionType.TypeArguments[0]) && !invocation.ContainsDirectives(TextSpan.FromBounds(memberAccessExpression.Span.End, invocation.Span.End))) { context.ReportDiagnostic( DiagnosticDescriptors.RemoveRedundantCast, Location.Create(invocation.SyntaxTree, TextSpan.FromBounds(name.SpanStart, argumentList.Span.End))); } } } } } } } } } }
public override HybridCollection <IMethod> FindExtensionMethod(ExtensionMethodInfo info) { var declaration = GetDeclaration(); if (declaration == null) { return(HybridCollection <IMethod> .Empty); } var result = HybridCollection <IMethod> .Empty; foreach (var memberDeclaration in declaration.MemberDeclarations) { if (info.ShortName == memberDeclaration.DeclaredName && info.Hash == memberDeclaration.GetTreeStartOffset().Offset) { if (memberDeclaration.DeclaredElement is IMethod method) { result = result.Add(method); } } } return(result); }
public override HybridCollection <IMethod> FindExtensionMethod(ExtensionMethodInfo info) { if (!TypeElement.HasAttributeInstance(PredefinedType.EXTENSION_ATTRIBUTE_CLASS, false)) { return(HybridCollection <IMethod> .Empty); } var declaration = GetDeclaration(); if (declaration == null) { return(HybridCollection <IMethod> .Empty); } var result = HybridCollection <IMethod> .Empty; foreach (var memberDeclaration in declaration.MemberDeclarations) { if (info.ShortName == memberDeclaration.DeclaredName && info.Hash == memberDeclaration.GetTreeStartOffset().Offset&& memberDeclaration.DeclaredElement is IMethod method) { result = result.Add(method); } } return(result); }
public ExtensionMethodInvocationCommandViewModel( ExtensionDeps deps, IExtensionInvocationService invocationService, ExtensionMethodInfo invokeParams) : base(deps) { _invocationService = invocationService; _invokeParams = invokeParams; }
public static bool CanRefactor( InvocationExpressionSyntax invocation, SemanticModel semanticModel, CancellationToken cancellationToken) { ExtensionMethodInfo info = semanticModel.GetExtensionMethodInfo(invocation, cancellationToken); if (info.IsLinqSelect(allowImmutableArrayExtension: true)) { ArgumentListSyntax argumentList = invocation.ArgumentList; if (argumentList?.IsMissing == false) { SeparatedSyntaxList <ArgumentSyntax> arguments = argumentList.Arguments; if (arguments.Count == 1) { ArgumentSyntax argument = arguments.First(); ExpressionSyntax expression = argument.Expression; if (expression?.IsMissing == false) { SyntaxKind expressionKind = expression.Kind(); if (expressionKind == SyntaxKind.SimpleLambdaExpression) { var lambda = (SimpleLambdaExpressionSyntax)expression; if (CanRefactor(lambda.Parameter, lambda.Body)) { return(true); } } else if (expressionKind == SyntaxKind.ParenthesizedLambdaExpression) { var lambda = (ParenthesizedLambdaExpressionSyntax)expression; ParameterListSyntax parameterList = lambda.ParameterList; if (parameterList != null) { SeparatedSyntaxList <ParameterSyntax> parameters = parameterList.Parameters; if (parameters.Count == 1 && CanRefactor(parameters.First(), lambda.Body)) { return(true); } } } } } } } return(false); }
public static void Analyze( SyntaxNodeAnalysisContext context, InvocationExpressionSyntax invocation, MemberAccessExpressionSyntax memberAccess) { if (memberAccess.Expression?.IsKind(SyntaxKind.InvocationExpression) == true) { var invocation2 = (InvocationExpressionSyntax)memberAccess.Expression; if (invocation2.ArgumentList?.Arguments.Count == 1 && invocation2.Expression?.IsKind(SyntaxKind.SimpleMemberAccessExpression) == true) { var memberAccess2 = (MemberAccessExpressionSyntax)invocation2.Expression; SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; if (string.Equals(memberAccess2.Name?.Identifier.ValueText, "Where", StringComparison.Ordinal)) { ExtensionMethodInfo info2 = semanticModel.GetExtensionMethodInfo(invocation2, ExtensionMethodKind.Reduced, cancellationToken); if (info2.MethodInfo.IsLinqExtensionOfIEnumerableOfT("Where", parameterCount: 2)) { if (SymbolUtility.IsPredicateFunc( info2.Symbol.Parameters[1].Type, info2.Symbol.TypeArguments[0], semanticModel)) { if (semanticModel .GetExtensionMethodInfo(invocation, ExtensionMethodKind.Reduced, cancellationToken) .MethodInfo .IsLinqWhere()) { Analyze(context, invocation, invocation2, memberAccess, memberAccess2); } } else if (SymbolUtility.IsPredicateFunc( info2.Symbol.Parameters[1].Type, info2.Symbol.TypeArguments[0], semanticModel.Compilation.GetSpecialType(SpecialType.System_Int32), semanticModel)) { if (semanticModel .GetExtensionMethodInfo(invocation, ExtensionMethodKind.Reduced, cancellationToken) .MethodInfo .IsLinqWhereWithIndex()) { Analyze(context, invocation, invocation2, memberAccess, memberAccess2); } } } } } } }
private RichText GetSignatureCore(string[] namedArguments, AnnotationsDisplayKind?showAnnotations, out TextRange[] parameterRanges, out int[] mapToOriginalOrder, out ExtensionMethodInfo extensionMethodInfo) { if (showAnnotations == null) { showAnnotations = _settings.GetValue((ParameterInfoSettings s) => s.ShowAnnotations); } // TODO: handle named arguments with reordering; currently falling back to non-colored display if (namedArguments.Any(s => s != null)) { string signature = _underlyingCandidate.GetSignature(namedArguments, showAnnotations.Value, out parameterRanges, out mapToOriginalOrder, out extensionMethodInfo); if (!IsIdentityMap(mapToOriginalOrder)) { return(signature); } } var options = PresenterOptions.ForParameterInfo(_settings, showAnnotations.Value); bool useReSharperColors = _settings.GetValue(HighlightingSettingsAccessor.IdentifierHighlightingEnabled); PresentedInfo presentedInfo; InvocationCandidate invocationCandidate = _underlyingCandidate.InvocationCandidate; var elementInstance = new DeclaredElementInstance(invocationCandidate.Element, invocationCandidate.Substitution); RichText richText = _colorizerPresenter.TryPresent(elementInstance, options, _underlyingCandidate.Language, useReSharperColors, out presentedInfo); if (richText == null) { return(_underlyingCandidate.GetSignature(namedArguments, showAnnotations.Value, out parameterRanges, out mapToOriginalOrder, out extensionMethodInfo)); } if (presentedInfo.Parameters.Count == 0) { parameterRanges = EmptyArray <TextRange> .Instance; mapToOriginalOrder = EmptyArray <int> .Instance; extensionMethodInfo = ExtensionMethodInfo.NoExtension; } else if (presentedInfo.IsExtensionMethod) { parameterRanges = presentedInfo.Parameters.Skip(1).ToArray(); mapToOriginalOrder = CreateIdentityMap(presentedInfo.Parameters.Count - 1); TextRange firstParameterRange = presentedInfo.Parameters[0].TrimLeft(5); // keeps "this " highlighted with the keyword color extensionMethodInfo = new ExtensionMethodInfo(firstParameterRange, TextRange.InvalidRange); } else { parameterRanges = presentedInfo.Parameters.ToArray(); mapToOriginalOrder = CreateIdentityMap(presentedInfo.Parameters.Count); extensionMethodInfo = ExtensionMethodInfo.NoExtension; } return(richText); }
public static void Analyze(SyntaxNodeAnalysisContext context, MemberInvocationExpressionInfo invocationInfo) { InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression; SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; var methodSymbol = semanticModel.GetSymbol(invocationExpression, cancellationToken) as IMethodSymbol; if (methodSymbol == null) { return; } if (!ExtensionMethodInfo.TryCreate(methodSymbol, semanticModel, out ExtensionMethodInfo extensionMethodInfo, ExtensionMethodKind.Reduced)) { return; } if (!extensionMethodInfo.MethodInfo.IsLinqCast()) { return; } ITypeSymbol typeArgument = extensionMethodInfo.ReducedSymbol.TypeArguments.SingleOrDefault(shouldThrow: false); if (typeArgument == null) { return; } var memberAccessExpressionType = semanticModel.GetTypeSymbol(invocationInfo.Expression, cancellationToken) as INamedTypeSymbol; if (memberAccessExpressionType?.IsConstructedFromIEnumerableOfT() != true) { return; } if (!typeArgument.Equals(memberAccessExpressionType.TypeArguments[0])) { return; } if (invocationExpression.ContainsDirectives(TextSpan.FromBounds(invocationInfo.Expression.Span.End, invocationExpression.Span.End))) { return; } context.ReportDiagnostic( DiagnosticDescriptors.RemoveRedundantCast, Location.Create(invocationExpression.SyntaxTree, TextSpan.FromBounds(invocationInfo.Name.SpanStart, invocationInfo.ArgumentList.Span.End))); }
public RichText GetSignature( string[] namedArguments, AnnotationsDisplayKind showAnnotations, out TextRange[] parameterRanges, out int[] mapToOriginalOrder, out ExtensionMethodInfo extensionMethodInfo) { // TODO: handle named arguments with reordering; currently falling back to non-colored display if (namedArguments.Any(s => s != null)) { string signature = UnderlyingCandidate.GetSignature(namedArguments, showAnnotations, out parameterRanges, out mapToOriginalOrder, out extensionMethodInfo); if (!IsIdentityMap(mapToOriginalOrder)) { return(signature); } } var options = PresenterOptions.ForParameterInfo(_settings, showAnnotations); var highlighterIdProvider = _highlighterIdProviderFactory.CreateProvider(_settings); PresentedInfo presentedInfo; InvocationCandidate invocationCandidate = UnderlyingCandidate.InvocationCandidate; var elementInstance = new DeclaredElementInstance(invocationCandidate.Element, invocationCandidate.Substitution); RichText richText = _colorizerPresenter.TryPresent(elementInstance, options, UnderlyingCandidate.Language, highlighterIdProvider, out presentedInfo); if (richText == null) { return(UnderlyingCandidate.GetSignature(namedArguments, showAnnotations, out parameterRanges, out mapToOriginalOrder, out extensionMethodInfo)); } if (presentedInfo.Parameters.Count == 0) { parameterRanges = EmptyArray <TextRange> .Instance; mapToOriginalOrder = EmptyArray <int> .Instance; extensionMethodInfo = ExtensionMethodInfo.NoExtension; } else if (presentedInfo.IsExtensionMethod && UnderlyingCandidate.InvocationCandidate.IsExtensionMethod) { parameterRanges = presentedInfo.Parameters.Skip(1).ToArray(); mapToOriginalOrder = CreateOffsetMap(presentedInfo.Parameters.Count - 1, 1); TextRange firstParameterRange = presentedInfo.Parameters[0].TrimLeft(5); // keeps "this " highlighted with the keyword color extensionMethodInfo = new ExtensionMethodInfo(firstParameterRange, TextRange.InvalidRange); } else { parameterRanges = presentedInfo.Parameters.ToArray(); mapToOriginalOrder = CreateOffsetMap(presentedInfo.Parameters.Count, 0); extensionMethodInfo = ExtensionMethodInfo.NoExtension; } return(richText); }
public static ExtensionMethodInfo GetExtensionMethodInfo( this SemanticModel semanticModel, ExpressionSyntax expression, ExtensionMethodKind allowedKinds, CancellationToken cancellationToken = default(CancellationToken)) { ISymbol symbol = GetSymbol(semanticModel, expression, cancellationToken); if (symbol?.IsMethod() == true) { return(ExtensionMethodInfo.Create((IMethodSymbol)symbol, semanticModel, allowedKinds)); } else { return(default(ExtensionMethodInfo)); } }
public static bool TryGetExtensionMethodInfo( this SemanticModel semanticModel, ExpressionSyntax expression, out MethodInfo methodInfo, ExtensionMethodKind kind = ExtensionMethodKind.None, CancellationToken cancellationToken = default(CancellationToken)) { ISymbol symbol = semanticModel.GetSymbol(expression, cancellationToken); if (symbol?.IsMethod() == true && ExtensionMethodInfo.TryCreate((IMethodSymbol)symbol, semanticModel, out ExtensionMethodInfo extensionMethodInfo, kind)) { methodInfo = extensionMethodInfo.MethodInfo; return(true); } methodInfo = default(MethodInfo); return(false); }
protected FSharpTypePart(IReader reader) : base(reader) { Modifiers = MemberDecoration.FromInt(reader.ReadInt()); AttributeClassNames = reader.ReadStringArray(); var extensionMethodCount = reader.ReadInt(); if (extensionMethodCount <= 0) { return; } var methods = new ExtensionMethodInfo[extensionMethodCount]; for (var i = 0; i < extensionMethodCount; i++) { methods[i] = new ExtensionMethodInfo(reader, this); } ExtensionMethodInfos = methods; }
private RichText GetSignatureCore(string[] namedArguments, AnnotationsDisplayKind? showAnnotations, out TextRange[] parameterRanges, out int[] mapToOriginalOrder, out ExtensionMethodInfo extensionMethodInfo) { if (showAnnotations == null) showAnnotations = _settings.GetValue((ParameterInfoSettings s) => s.ShowAnnotations); // TODO: handle named arguments with reordering; currently falling back to non-colored display if (namedArguments.Any(s => s != null)) { string signature = _underlyingCandidate.GetSignature(namedArguments, showAnnotations.Value, out parameterRanges, out mapToOriginalOrder, out extensionMethodInfo); if (!IsIdentityMap(mapToOriginalOrder)) return signature; } var options = PresenterOptions.ForParameterInfo(_settings, showAnnotations.Value); bool useReSharperColors = _settings.GetValue(HighlightingSettingsAccessor.IdentifierHighlightingEnabled); PresentedInfo presentedInfo; InvocationCandidate invocationCandidate = _underlyingCandidate.InvocationCandidate; var elementInstance = new DeclaredElementInstance(invocationCandidate.Element, invocationCandidate.Substitution); RichText richText = _colorizerPresenter.TryPresent(elementInstance, options, _underlyingCandidate.Language, useReSharperColors, out presentedInfo); if (richText == null) return _underlyingCandidate.GetSignature(namedArguments, showAnnotations.Value, out parameterRanges, out mapToOriginalOrder, out extensionMethodInfo); if (presentedInfo.Parameters.Count == 0) { parameterRanges = EmptyArray<TextRange>.Instance; mapToOriginalOrder = EmptyArray<int>.Instance; extensionMethodInfo = ExtensionMethodInfo.NoExtension; } else if (presentedInfo.IsExtensionMethod) { parameterRanges = presentedInfo.Parameters.Skip(1).ToArray(); mapToOriginalOrder = CreateIdentityMap(presentedInfo.Parameters.Count - 1); TextRange firstParameterRange = presentedInfo.Parameters[0].TrimLeft(5); // keeps "this " highlighted with the keyword color extensionMethodInfo = new ExtensionMethodInfo(firstParameterRange, TextRange.InvalidRange); } else { parameterRanges = presentedInfo.Parameters.ToArray(); mapToOriginalOrder = CreateIdentityMap(presentedInfo.Parameters.Count); extensionMethodInfo = ExtensionMethodInfo.NoExtension; } return richText; }
private void AnalyzeSimpleMemberAccessExpression(SyntaxNodeAnalysisContext context) { var memberAccess = (MemberAccessExpressionSyntax)context.Node; string identifierText = memberAccess.Name?.Identifier.ValueText; if (identifierText == "Type" || identifierText == "ConvertedType") { SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; var propertySymbol = semanticModel.GetSymbol(memberAccess, cancellationToken) as IPropertySymbol; if ((propertySymbol.Name == "Type" || propertySymbol.Name == "ConvertedType") && propertySymbol?.Type == semanticModel.GetTypeByMetadataName("Microsoft.CodeAnalysis.ITypeSymbol")) { ExpressionSyntax expression = memberAccess.Expression; if (expression?.IsKind(SyntaxKind.InvocationExpression) == true) { ExtensionMethodInfo info = semanticModel.GetExtensionMethodInfo(expression, ExtensionMethodKind.Reduced, cancellationToken); if (info.IsValid && info.HasName("GetTypeInfo") && info.Symbol.ReturnType == semanticModel.GetTypeByMetadataName("Microsoft.CodeAnalysis.TypeInfo")) { ImmutableArray <IParameterSymbol> parameters = info.Symbol.Parameters; if (parameters.Length == 3 && parameters[0].Type == semanticModel.GetTypeByMetadataName("Microsoft.CodeAnalysis.SemanticModel")) { context.ReportDiagnostic( DiagnosticDescriptors.SimplifyGetTypeInfoInvocation, memberAccess); } } } } } }
public static async Task ComputeRefactoringAsync(RefactoringContext context, InvocationExpressionSyntax invocation) { ExpressionSyntax expression = invocation.Expression; if (expression != null) { SyntaxNodeOrToken nodeOrToken = GetNodeOrToken(expression); if (nodeOrToken.Span.Contains(context.Span)) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ExtensionMethodInfo info = semanticModel.GetExtensionMethodInfo(invocation, ExtensionMethodKind.Ordinary, context.CancellationToken); if (info.IsValid && invocation.ArgumentList?.Arguments.Any() == true) { InvocationExpressionSyntax newInvocation = GetNewInvocation(invocation); if (semanticModel .GetSpeculativeMethodSymbol(invocation.SpanStart, newInvocation)? .ReducedFromOrSelf() .Equals(info.Symbol.ConstructedFrom) == true) { context.RegisterRefactoring( "Call extension method as instance method", cancellationToken => { return(RefactorAsync( context.Document, invocation, newInvocation, context.CancellationToken)); }); } } } } }
protected override RichText TryGetSignatureCore( PresenterOptions options, HighlighterIdProvider highlighterIdProvider, out TextRange[] parameterRanges, out int[] mapToOriginalOrder, out ExtensionMethodInfo extensionMethodInfo) { parameterRanges = EmptyArray <TextRange> .Instance; mapToOriginalOrder = EmptyArray <int> .Instance; extensionMethodInfo = ExtensionMethodInfo.NoExtension; ITypeParametersOwner typeElement = UnderlyingCandidate.TypeElement; var elementInstance = new DeclaredElementInstance(typeElement, typeElement.IdSubstitution); RichText richText = _colorizerPresenter.TryPresent(elementInstance, options, UnderlyingCandidate.Language, highlighterIdProvider, null, out PresentedInfo presentedInfo); if (richText == null) { return(null); } parameterRanges = presentedInfo.TypeParameters.ToArray(); return(richText); }
protected override RichText TryGetSignatureCore( PresenterOptions options, HighlighterIdProvider highlighterIdProvider, out TextRange[] parameterRanges, out int[] mapToOriginalOrder, out ExtensionMethodInfo extensionMethodInfo) { parameterRanges = EmptyArray <TextRange> .Instance; mapToOriginalOrder = EmptyArray <int> .Instance; extensionMethodInfo = ExtensionMethodInfo.NoExtension; InvocationCandidate invocationCandidate = UnderlyingCandidate.InvocationCandidate; var elementInstance = new DeclaredElementInstance(invocationCandidate.Element, invocationCandidate.Substitution); RichText richText = _colorizerPresenter.TryPresent(elementInstance, options, UnderlyingCandidate.Language, highlighterIdProvider, null, out PresentedInfo presentedInfo); if (richText == null) { return(null); } if (presentedInfo.Parameters.Count > 0) { if (presentedInfo.IsExtensionMethod && UnderlyingCandidate.InvocationCandidate.IsExtensionMethodInvocation) { parameterRanges = presentedInfo.Parameters.Skip(1).ToArray(); mapToOriginalOrder = CreateIdentityMap(presentedInfo.Parameters.Count - 1); extensionMethodInfo = new ExtensionMethodInfo(presentedInfo.Parameters[0], TextRange.InvalidRange); } else { parameterRanges = presentedInfo.Parameters.ToArray(); mapToOriginalOrder = CreateIdentityMap(presentedInfo.Parameters.Count); } } return(richText); }
public static bool IsFixable( InvocationExpressionSyntax invocation, SemanticModel semanticModel, CancellationToken cancellationToken) { ISymbol symbol = semanticModel.GetSymbol(invocation, cancellationToken); if (symbol?.IsMethod() == true) { ExtensionMethodInfo extensionMethodInfo; if (ExtensionMethodInfo.TryCreate((IMethodSymbol)symbol, semanticModel, out extensionMethodInfo) && extensionMethodInfo.MethodInfo.IsLinqSelect(allowImmutableArrayExtension: true)) { ITypeSymbol firstTypeArgument = extensionMethodInfo.ReducedSymbolOrSymbol.TypeArguments[0]; if (firstTypeArgument.IsReferenceType && !firstTypeArgument.IsObject()) { ArgumentListSyntax argumentList = invocation.ArgumentList; if (argumentList?.IsMissing == false) { ExpressionSyntax expression = argumentList.Arguments.Last().Expression; if (expression?.IsMissing == false) { switch (expression.Kind()) { case SyntaxKind.SimpleLambdaExpression: { var lambda = (SimpleLambdaExpressionSyntax)expression; if (IsFixable(lambda.Parameter, lambda.Body)) { return(true); } break; } case SyntaxKind.ParenthesizedLambdaExpression: { var lambda = (ParenthesizedLambdaExpressionSyntax)expression; ParameterListSyntax parameterList = lambda.ParameterList; if (parameterList != null) { SeparatedSyntaxList <ParameterSyntax> parameters = parameterList.Parameters; if (parameters.Count == 1 && IsFixable(parameters.First(), lambda.Body)) { return(true); } } break; } } } } } } } return(false); }
public static void Analyze( SyntaxNodeAnalysisContext context, MemberInvocationExpressionInfo invocationInfo) { InvocationExpressionSyntax invocationExpression = invocationInfo.InvocationExpression; TextSpan span = TextSpan.FromBounds(invocationInfo.Name.Span.Start, invocationExpression.Span.End); if (invocationExpression.ContainsDirectives(span)) { return; } SemanticModel semanticModel = context.SemanticModel; CancellationToken cancellationToken = context.CancellationToken; var methodSymbol = semanticModel.GetSymbol(invocationExpression, cancellationToken) as IMethodSymbol; if (methodSymbol == null) { return; } if (!ExtensionMethodInfo.TryCreate(methodSymbol, semanticModel, out ExtensionMethodInfo extensionMethodInfo)) { return; } if (!extensionMethodInfo.MethodInfo.IsLinqSelect(allowImmutableArrayExtension: true)) { return; } ITypeSymbol typeArgument = extensionMethodInfo.ReducedSymbolOrSymbol.TypeArguments[0]; if (!typeArgument.IsReferenceType) { return; } if (typeArgument.SpecialType == SpecialType.System_Object) { return; } ExpressionSyntax expression = invocationExpression.ArgumentList?.Arguments.Last().Expression; SingleParameterLambdaExpressionInfo lambdaInfo = SyntaxInfo.SingleParameterLambdaExpressionInfo(expression); if (!lambdaInfo.Success) { return; } CastExpressionSyntax castExpression = GetCastExpression(lambdaInfo.Body); if (castExpression == null) { return; } if (!(castExpression.Expression is IdentifierNameSyntax identifierName)) { return; } if (!string.Equals(lambdaInfo.Parameter.Identifier.ValueText, identifierName.Identifier.ValueText, StringComparison.Ordinal)) { return; } var castSymbol = semanticModel.GetSymbol(castExpression, cancellationToken) as IMethodSymbol; if (castSymbol?.MethodKind == MethodKind.Conversion) { return; } context.ReportDiagnostic( DiagnosticDescriptors.CallCastInsteadOfSelect, Location.Create(invocationExpression.SyntaxTree, span)); }
private void GenerateCodeForStruct(UnrealModuleInfo module, UStruct unrealStruct) { bool isBlueprintType = unrealStruct.IsA <UUserDefinedStruct>() || unrealStruct.IsA <UBlueprintGeneratedClass>(); StructInfo structInfo = GetStructInfo(unrealStruct, isBlueprintType); string typeName = GetTypeName(unrealStruct); UnrealModuleType moduleAssetType; string currentNamespace = GetModuleNamespace(unrealStruct, out moduleAssetType); List <string> namespaces = GetDefaultNamespaces(); CSharpTextBuilder builder = new CSharpTextBuilder(Settings.IndentType); if (!string.IsNullOrEmpty(currentNamespace)) { builder.AppendLine("namespace " + currentNamespace); builder.OpenBrace(); } string accessSpecifier = "public"; StringBuilder modifiers = new StringBuilder(accessSpecifier); if (Settings.UseAbstractTypes && structInfo.IsClass && structInfo.Class.HasAnyClassFlags(EClassFlags.Abstract)) { modifiers.Append(" abstract"); } StringBuilder baseTypeStr = new StringBuilder(); UStruct parentStruct = unrealStruct.GetSuperStruct(); if (parentStruct != null && parentStruct != UClass.GetClass <UInterface>() && unrealStruct != UClass.GetClass <UInterface>()) { baseTypeStr.Append(GetTypeName(parentStruct, namespaces)); } if (structInfo.IsClass) { foreach (FImplementedInterface implementedInterface in structInfo.Class.Interfaces) { if (baseTypeStr.Length > 0) { baseTypeStr.Append(", "); } baseTypeStr.Append(GetTypeName(implementedInterface.InterfaceClass, namespaces)); } } if (baseTypeStr.Length > 0) { baseTypeStr.Insert(0, " : "); } AppendDocComment(builder, unrealStruct, isBlueprintType); AppendAttribute(builder, unrealStruct, module, structInfo); if (structInfo.IsInterface) { System.Diagnostics.Debug.Assert(structInfo.Class.Interfaces.Length == 0, "TODO: Interfaces inheriting other interfaces"); string baseInterface = unrealStruct == UClass.GetClass <UInterface>() ? string.Empty : (baseTypeStr.Length == 0 ? " : " : ", ") + Names.IInterface; builder.AppendLine(modifiers + " interface " + typeName + baseTypeStr + baseInterface); } else if (structInfo.IsClass) { builder.AppendLine(modifiers + " partial class " + typeName + baseTypeStr); } else { if (structInfo.StructAsClass) { builder.AppendLine(modifiers + " partial class " + typeName + " : " + Names.StructAsClass); } else { if (structInfo.IsBlittable) { string structLayout = UpdateTypeNameNamespace("StructLayout", "System.Runtime.InteropServices", namespaces); string layoutKind = UpdateTypeNameNamespace("LayoutKind", "System.Runtime.InteropServices", namespaces); builder.AppendLine("[" + structLayout + "(" + layoutKind + ".Sequential)]"); } builder.AppendLine(modifiers + " partial struct " + typeName); } } builder.OpenBrace(); string typeNameEx = structInfo.IsInterface ? typeName + "Impl" : typeName; // Create a seperate builder for building the interface "Impl" class CSharpTextBuilder interfaceImplBuilder = null; if (structInfo.IsInterface) { interfaceImplBuilder = new CSharpTextBuilder(); interfaceImplBuilder.AppendLine(accessSpecifier + " sealed class " + typeNameEx + " : " + Names.IInterfaceImpl + ", " + typeName); interfaceImplBuilder.Indent(); // Move the indent to the same as builder for this point interfaceImplBuilder.OpenBrace(); // Open the class brace } // Create a seperate builder for properties which will be inserted into the native type info initializer CSharpTextBuilder offsetsBuilder = new CSharpTextBuilder(Settings.IndentType); offsetsBuilder.AppendLine("static " + typeNameEx + "()"); offsetsBuilder.IndentCount = builder.IndentCount;// Move the indent to the same as builder offsetsBuilder.OpenBrace(); offsetsBuilder.AppendLine("if (" + Names.UnrealTypes_CanLazyLoadNativeType + "(typeof(" + typeNameEx + ")))"); offsetsBuilder.OpenBrace(); offsetsBuilder.AppendLine(Settings.VarNames.LoadNativeType + "();"); offsetsBuilder.CloseBrace(); offsetsBuilder.AppendLine(Names.UnrealTypes_OnCCtorCalled + "(typeof(" + typeNameEx + "));"); offsetsBuilder.CloseBrace(); offsetsBuilder.AppendLine(); offsetsBuilder.AppendLine("static void " + Settings.VarNames.LoadNativeType + "()"); offsetsBuilder.OpenBrace(); if (structInfo.HasStaticFunction) { builder.AppendLine("static IntPtr " + Settings.VarNames.ClassAddress + ";"); offsetsBuilder.AppendLine(Settings.VarNames.ClassAddress + " = " + (structInfo.IsStruct ? Names.NativeReflection_GetStruct : Names.NativeReflection_GetClass) + "(\"" + unrealStruct.GetPathName() + "\");"); } else { offsetsBuilder.AppendLine("IntPtr " + Settings.VarNames.ClassAddress + " = " + (structInfo.IsStruct ? Names.NativeReflection_GetStruct : Names.NativeReflection_GetClass) + "(\"" + unrealStruct.GetPathName() + "\");"); } if (structInfo.StructAsClass) { offsetsBuilder.AppendLine(typeName + Settings.VarNames.StructAddress + " = " + Settings.VarNames.ClassAddress + ";"); } else if (structInfo.IsStruct) { offsetsBuilder.AppendLine(typeName + Settings.VarNames.StructSize + " = " + Names.NativeReflection_GetStructSize + "(" + Settings.VarNames.ClassAddress + ");"); } if (structInfo.IsStruct && parentStruct != null) { // Export base properties if (Settings.InlineBaseStruct || structInfo.StructAsClass) { UScriptStruct tempParentStruct = parentStruct as UScriptStruct; while (tempParentStruct != null) { StructInfo tempParentStructInfo = GetStructInfo(tempParentStruct); if (tempParentStructInfo != null) { foreach (UProperty property in tempParentStructInfo.GetProperties()) { if (!tempParentStructInfo.IsCollapsedProperty(property)) { GenerateCodeForProperty(module, builder, offsetsBuilder, property, tempParentStructInfo.IsBlueprintType, structInfo, namespaces, tempParentStructInfo.GetPropertyName(property)); } } } tempParentStruct = tempParentStruct.GetSuperStruct() as UScriptStruct; } } else { builder.AppendLine(GetTypeName(parentStruct, namespaces) + " Base;"); } } // Export properties foreach (UProperty property in structInfo.GetProperties()) { if (!structInfo.IsCollapsedProperty(property)) { GenerateCodeForProperty(module, builder, offsetsBuilder, property, isBlueprintType, structInfo, namespaces, structInfo.GetPropertyName(property)); } } foreach (CollapsedMember collapsedMember in structInfo.GetCollapsedMembers()) { GenerateCodeForProperty(module, builder, offsetsBuilder, collapsedMember, isBlueprintType, namespaces); } // Export functions List <ExtensionMethodInfo> extensionMethods = new List <ExtensionMethodInfo>(); foreach (UFunction function in structInfo.GetFunctions()) { if (!structInfo.IsCollapsedFunction(function)) { if (!structInfo.IsInterface) { // If this isn't an interface and the function can be made into an extension method then do so ExtensionMethodInfo extensionMethodInfo = ExtensionMethodInfo.Create(function); if (extensionMethodInfo != null) { extensionMethods.Add(extensionMethodInfo); } } if (function.HasAnyFunctionFlags(EFunctionFlags.Delegate | EFunctionFlags.MulticastDelegate)) { AppendDelegateSignature(module, builder, function, unrealStruct, isBlueprintType, namespaces); builder.AppendLine(); } else if (structInfo.IsInterface) { AppendFunctionOffsets(interfaceImplBuilder, offsetsBuilder, function, false, false, namespaces); AppendDocComment(builder, function, isBlueprintType); AppendAttribute(builder, function, module); builder.AppendLine(GetFunctionSignature(module, function, unrealStruct, namespaces) + ";"); builder.AppendLine(); // Always require a per-instance function address on the interfaces "Impl" class. // This isn't really required if the target function isn't an event but since we are working // with interfaces it is probably best to make sure functions are resolved properly. If we decide // to change this to not require a per-instance function address make sure to update AppendFunctionOffsets // which adds the per-instance function address to the class. Also update AssemblyRewriter.Interface.cs // Also update the "ResetInterface" code which always expects an per-instance address to reset. AppendAttribute(interfaceImplBuilder, function, module); interfaceImplBuilder.AppendLine(GetFunctionSignature(module, function, unrealStruct, null, "public", FunctionSigFlags.None, namespaces)); interfaceImplBuilder.OpenBrace(); AppendFunctionBody(interfaceImplBuilder, function, false, false, true, namespaces); interfaceImplBuilder.CloseBrace(); builder.AppendLine(); } else { AppendFunctionOffsets(builder, offsetsBuilder, function, false, false, namespaces); AppendDocComment(builder, function, isBlueprintType); AppendAttribute(builder, function, module); bool hasSuperFunction = function.GetSuperFunction() != null; if (function.HasAnyFunctionFlags(EFunctionFlags.BlueprintEvent) && !hasSuperFunction) { // Define the declaration method which will call the correct UFunction for the UObject instance builder.AppendLine(GetFunctionSignature(module, function, unrealStruct, namespaces)); builder.OpenBrace(); AppendFunctionBody(builder, function, false, false, true, namespaces); builder.CloseBrace(); builder.AppendLine(); } if (function.HasAnyFunctionFlags(EFunctionFlags.BlueprintEvent)) { if (!Settings.UseExplicitImplementationMethods) { // Used to hide the _Implementation method from being visible in intellisense builder.AppendLine("[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]"); } // Define the _Implementation method builder.AppendLine(GetFunctionSignatureImpl(module, function, unrealStruct, namespaces)); } else { builder.AppendLine(GetFunctionSignature(module, function, unrealStruct, namespaces)); } builder.OpenBrace(); AppendFunctionBody(builder, function, false, false, false, namespaces); builder.CloseBrace(); builder.AppendLine(); } } } if (structInfo.StructAsClass) { if (Settings.GenerateIsValidSafeguards) { builder.AppendLine("static bool " + typeName + Settings.VarNames.IsValid + ";"); // Append XXXX_IsValid = Prop1_IsValid && Prop2_IsValid && Prop3_IsValid...; AppendStructIsValid(offsetsBuilder, typeName, structInfo, parentStruct); } builder.AppendLine("static IntPtr " + typeName + Settings.VarNames.StructAddress + ";"); builder.AppendLine(); builder.AppendLine("protected override IntPtr GetStructAddress()"); builder.OpenBrace(); builder.AppendLine("return " + typeName + Settings.VarNames.StructAddress + ";"); builder.CloseBrace(); builder.AppendLine(); } else if (structInfo.IsStruct) { if (Settings.GenerateIsValidSafeguards && !structInfo.IsBlittable) { builder.AppendLine("static bool " + typeName + Settings.VarNames.IsValid + ";"); } builder.AppendLine("static int " + typeName + Settings.VarNames.StructSize + ";"); builder.AppendLine(); // Add the struct Copy() method (for non blittable structs) builder.AppendLine("public " + typeName + " " + Settings.VarNames.StructCopy + "()"); builder.OpenBrace(); builder.AppendLine(typeName + " result = this;"); foreach (UProperty property in structInfo.GetProperties()) { if (!structInfo.IsCollapsedProperty(property) && IsCollectionProperty(property)) { string propertyName = GetMemberName(property, structInfo.GetPropertyName(property)); builder.AppendLine("if (this." + propertyName + " != null)"); builder.OpenBrace(); UStructProperty structProperty = property as UStructProperty; StructInfo propertyStructInfo = structProperty == null || structProperty.Struct == null ? null : GetStructInfo(structProperty.Struct); if (propertyStructInfo != null && !propertyStructInfo.IsBlittable) { builder.AppendLine("result." + propertyName + " = new " + GetTypeName(property, namespaces) + "();"); builder.AppendLine("for (int i = 0; i < this." + propertyName + ".Count; ++i)"); builder.OpenBrace(); builder.AppendLine("result." + propertyName + ".Add(this." + propertyName + "[i]." + Settings.VarNames.StructCopy + "());"); builder.CloseBrace(); } else { builder.AppendLine("result." + propertyName + " = new " + GetTypeName(property, namespaces) + "(" + "this." + propertyName + ");"); } builder.CloseBrace(); } } if (Settings.InlineBaseStruct) { UScriptStruct tempParentStruct = parentStruct as UScriptStruct; while (tempParentStruct != null) { StructInfo tempParentStructInfo = GetStructInfo(tempParentStruct); if (tempParentStructInfo != null) { foreach (UProperty property in tempParentStructInfo.GetProperties()) { if (!tempParentStructInfo.IsCollapsedProperty(property) && IsCollectionProperty(property)) { string propertyName = GetMemberName(property, tempParentStructInfo.GetPropertyName(property)); builder.AppendLine("if (this." + propertyName + " != null)"); builder.OpenBrace(); builder.AppendLine("result." + propertyName + " = new " + GetTypeName(property, namespaces) + "(" + "this." + propertyName + ");"); builder.CloseBrace(); } } } tempParentStruct = tempParentStruct.GetSuperStruct() as UScriptStruct; } } builder.AppendLine("return result;"); builder.CloseBrace(); builder.AppendLine(); if (structInfo.IsBlittable) { // Validate the size of the blittable struct offsetsBuilder.AppendLine(Names.NativeReflection_ValidateBlittableStructSize + "(" + Settings.VarNames.ClassAddress + ", typeof(" + typeName + "));"); } else { if (Settings.GenerateIsValidSafeguards) { // Append XXXX_IsValid = Prop1_IsValid && Prop2_IsValid && Prop3_IsValid...; AppendStructIsValid(offsetsBuilder, typeName, structInfo, parentStruct); } builder.AppendLine("public static " + typeName + " FromNative(IntPtr nativeBuffer)"); builder.OpenBrace(); builder.AppendLine("return new " + typeName + "(nativeBuffer);"); builder.CloseBrace(); builder.AppendLine(); builder.AppendLine("public static void ToNative(IntPtr nativeBuffer, " + typeName + " value)"); builder.OpenBrace(); builder.AppendLine("value.ToNative(nativeBuffer);"); builder.CloseBrace(); builder.AppendLine(); builder.AppendLine("public static " + typeName + " FromNative(IntPtr nativeBuffer, int arrayIndex, IntPtr prop)"); builder.OpenBrace(); builder.AppendLine("return new " + typeName + "(nativeBuffer + (arrayIndex * " + typeName + Settings.VarNames.StructSize + "));"); builder.CloseBrace(); builder.AppendLine(); builder.AppendLine("public static void ToNative(IntPtr nativeBuffer, int arrayIndex, IntPtr prop, " + typeName + " value)"); builder.OpenBrace(); builder.AppendLine("value.ToNative(nativeBuffer + (arrayIndex * " + typeName + Settings.VarNames.StructSize + "));"); builder.CloseBrace(); builder.AppendLine(); builder.AppendLine("public void ToNative(IntPtr nativeStruct)"); builder.OpenBrace(); AppendStructMarshalerBody(builder, typeName, structInfo, parentStruct, true, namespaces); builder.CloseBrace(); builder.AppendLine(); builder.AppendLine("public " + typeName + "(IntPtr nativeStruct)"); builder.OpenBrace(); /*if (Settings.UObjectAsBlittableType) * { * // UObject types will have an additional backing field which needs to be assigned before being able to * // assign the property * // - The alternative would be to modify the property assignment code to target the backing field instead of * // the property. This is probably the ideal way of doing it but we would need to use a different marshaler * // (BlittableTypeMarshaler<> instead of UObjectMarshaler<>) and ensure the marshaler change doesn't impact * // other generated code elsewhere. * foreach (UProperty property in structInfo.GetProperties()) * { * UObjectProperty objectProperty = property as UObjectProperty; * if (objectProperty != null) * { * string propertyName = GetMemberName(property, structInfo.GetPropertyName(property)); * builder.AppendLine(propertyName + Settings.VarNames.UObjectBlittableName + " = IntPtr.Zero;"); * } * } * }*/ AppendStructMarshalerBody(builder, typeName, structInfo, parentStruct, false, namespaces); builder.CloseBrace(); builder.AppendLine(); } } if (loadNativeTypeInjected.Contains(typeName)) { offsetsBuilder.AppendLine(Settings.VarNames.LoadNativeTypeInjected + "(" + Settings.VarNames.ClassAddress + ");"); } offsetsBuilder.CloseBrace(); // Add the offsets builder if it isn't empty (always required for structs due to struct size export) // Interfaces are built up seperately in a different class which must be added after the interface body. if (!structInfo.IsInterface && (structInfo.HasContent || structInfo.IsStruct)) { builder.AppendLine(offsetsBuilder.ToString()); builder.AppendLine(); } // Remove any trailing empty lines before adding the close brace builder.RemovePreviousEmptyLines(); builder.CloseBrace(); // Add the "Impl" wrapper class for interfaces. This is always required so that we have a default // interface implementation that we can call. if (structInfo.IsInterface) { if (structInfo.HasContent) { interfaceImplBuilder.AppendLine();// Whitespace // Add the ResetInterface method to reset the state of a pooled interface instance interfaceImplBuilder.AppendLine("public override void ResetInterface()"); interfaceImplBuilder.OpenBrace(); foreach (UFunction function in structInfo.GetFunctions()) { interfaceImplBuilder.AppendLine(GetFunctionName(function) + Settings.VarNames.InstanceFunctionAddress + " = IntPtr.Zero;"); } interfaceImplBuilder.CloseBrace(); interfaceImplBuilder.AppendLine(); // Whitespace } interfaceImplBuilder.AppendLine(offsetsBuilder.ToString()); // Add the offsets to the "Impl" class interfaceImplBuilder.CloseBrace(); // Add the close brace for the "Impl" class builder.AppendLine(); // Empty line between interface and "Impl" class builder.AppendLine(interfaceImplBuilder.ToString()); // Add the "Impl" class below the interface } if (!string.IsNullOrEmpty(currentNamespace)) { builder.CloseBrace(); } builder.InsertNamespaces(currentNamespace, namespaces, Settings.SortNamespaces); OnCodeGenerated(module, moduleAssetType, typeName, unrealStruct.GetPathName(), builder); if (extensionMethods.Count > 0) { GenerateCodeForExtensionMethods(module, unrealStruct, extensionMethods); } }
public RichText GetSignature(string[] namedArguments, out TextRange[] parameterRanges, out int[] mapToOriginalOrder, out ExtensionMethodInfo extensionMethodInfo) { return(GetSignatureCore(namedArguments, null, out parameterRanges, out mapToOriginalOrder, out extensionMethodInfo)); }
public static RichText GetSignature(this ICandidate candidate, string[] namedArguments, AnnotationsDisplayKind showAnnotations, out TextRange[] parameterRanges, out int[] mapToOriginalOrder, out ExtensionMethodInfo extensionMethodInfo) { return(candidate.GetSignature(namedArguments, out parameterRanges, out mapToOriginalOrder, out extensionMethodInfo)); }
public RichText GetSignature(string[] namedArguments, out TextRange[] parameterRanges, out int[] mapToOriginalOrder, out ExtensionMethodInfo extensionMethodInfo) { return GetSignatureCore(namedArguments, null, out parameterRanges, out mapToOriginalOrder, out extensionMethodInfo); }
public abstract RichText GetSignature(string[] namedArguments, AnnotationsDisplayKind showAnnotations, out TextRange[] parameterRanges, out int[] mapToOriginalOrder, out ExtensionMethodInfo extensionMethodInfo);
public DynamicItemInfo(int id, ExtensionMethodInfo icon) { Id = id; Icon = icon; }
public static RichText GetSignature(this ICandidate candidate, string[] namedArguments, AnnotationsDisplayKind showAnnotations, out TextRange[] parameterRanges, out int[] mapToOriginalOrder, out ExtensionMethodInfo extensionMethodInfo) { return candidate.GetSignature(namedArguments, out parameterRanges, out mapToOriginalOrder, out extensionMethodInfo); }
private static string TheNameOfTheExtendedClass(ExtensionMethodInfo info) => (info.Class).NoTilde();
public override RichText GetSignature(string[] namedArguments, AnnotationsDisplayKind showAnnotations, out TextRange[] parameterRanges, out int[] mapToOriginalOrder, out ExtensionMethodInfo extensionMethodInfo) { var parameters = myCandidate.Parameters; var text = new StringBuilder("("); var newParameterRanges = new TextRange[parameters.Length]; var parametersOrder = SortParameters(parameters, namedArguments, out var orderChanged); if (parameters.IsEmpty()) { text.Append("<no parameters>"); } else { for (var i = 0; i < parameters.Length; i++) { var paramRangeStart = text.Length; if (orderChanged) { text.Append("["); } text.Append(parameters[parametersOrder[i]].Display); if (orderChanged) { text.Append("]"); } var paramRangeEnd = text.Length; newParameterRanges[i] = new TextRange(paramRangeStart, paramRangeEnd); if (i < parameters.Length - 1) { text.Append(", "); } } } text.Append(")" + myCandidate.ReturnTypeText); extensionMethodInfo = ExtensionMethodInfo.NoExtension; parameterRanges = newParameterRanges; mapToOriginalOrder = parametersOrder; return(text.ToString()); }
public RichText GetSignature(string[] namedArguments, out TextRange[] parameterRanges, out int[] mapToOriginalOrder, out ExtensionMethodInfo extensionMethodInfo) { parameterRanges = myParameterRanges; mapToOriginalOrder = Enumerable.Range(0, myParameterRanges.Length).ToArray(); extensionMethodInfo = null; return(new RichText(mySignature)); }