예제 #1
0
        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());
        }
예제 #2
0
        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)));
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #3
0
        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);
        }
예제 #4
0
        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;
 }
예제 #6
0
        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);
        }
예제 #7
0
        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);
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #8
0
        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);
        }
예제 #9
0
        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)));
        }
예제 #10
0
        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);
        }
예제 #11
0
        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));
            }
        }
예제 #12
0
        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);
        }
예제 #13
0
        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;
		}
예제 #15
0
        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);
                            }
                        }
                    }
                }
            }
        }
예제 #16
0
        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));
                            });
                        }
                    }
                }
            }
        }
예제 #17
0
        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);
        }
예제 #19
0
        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);
        }
예제 #20
0
        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));
        }
예제 #21
0
        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);
            }
        }
예제 #22
0
 public RichText GetSignature(string[] namedArguments,
                              out TextRange[] parameterRanges, out int[] mapToOriginalOrder, out ExtensionMethodInfo extensionMethodInfo)
 {
     return(GetSignatureCore(namedArguments, null, out parameterRanges, out mapToOriginalOrder, out extensionMethodInfo));
 }
예제 #23
0
 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);
예제 #26
0
 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);
		}
예제 #28
0
 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));
 }