protected override void Analyze(IInvocationExpression expression, IDaemonProcess daemonProcess, DaemonProcessKind kind,
                                        IHighlightingConsumer consumer)
        {
            if (PerformanceCriticalCodeStageUtil.IsInvocationExpensive(expression))
            {
                CreateHiglighting(expression, consumer);
            }
            else if (kind == DaemonProcessKind.GLOBAL_WARNINGS)
            {
                var declaredElement = CallGraphUtil.GetCallee(expression);
                if (declaredElement == null)
                {
                    return;
                }

                var id = myProvider.GetElementId(declaredElement);
                if (!id.HasValue)
                {
                    return;
                }

                if (mySwaExtensionProvider.IsMarkedByCallGraphRootMarksProvider(myExpensiveCodeCallGraphAnalyzer.Id, true, id.Value))
                {
                    CreateHiglighting(expression, consumer);
                }
            }
        }
예제 #2
0
        protected override void Analyze(IInvocationExpression expression, IHighlightingConsumer consumer, IReadOnlyCallGraphContext context)
        {
            var callee = CallGraphUtil.GetCallee(expression);

            if (PerformanceCriticalCodeStageUtil.IsInvokedElementExpensive(callee as IMethod) || myContextProvider.IsMarkedStage(callee, context))
            {
                CreateHighlighting(expression, consumer);
            }
        }
        protected override void Analyze(IInvocationExpression expression, IDaemonProcess daemonProcess,
                                        DaemonProcessKind kind, IHighlightingConsumer consumer)
        {
            var callee = CallGraphUtil.GetCallee(expression);

            if (myContextProvider.IsMarked(callee, kind))
            {
                CreateHighlighting(expression, consumer);
            }
        }
예제 #4
0
        public static IDeclaredElement ExtractDeclaredElementForProvider([CanBeNull] ITreeNode node)
        {
            switch (node)
            {
            case IDeclaration declaration:
                return(declaration.DeclaredElement);

            case ICSharpExpression expression:
                return(CallGraphUtil.GetCallee(expression));
            }

            return(null);
        }
예제 #5
0
        public static bool IsBurstContextBannedNode(ITreeNode node)
        {
            switch (node)
            {
            case IThrowStatement _:
            case IThrowExpression _:
            case IInvocationExpression invocationExpression
                when CallGraphUtil.GetCallee(invocationExpression) is IMethod method && IsBurstDiscarded(method):
            case IFunctionDeclaration functionDeclaration
                when IsBurstContextBannedForFunction(functionDeclaration.DeclaredElement):
                return(true);

            default:
                return(false);
            }
        }
예제 #6
0
        public static bool CheckAndAnalyze(ITreeNode node, IHighlighting highlighting, IHighlightingConsumer consumer)
        {
            var firstNode = node;

            do
            {
                var parent = node.Parent;

                if (parent is IExpressionInitializer expressionInitializer)
                {
                    if (ReferenceEquals(expressionInitializer.Value, firstNode))
                    {
                        do
                        {
                            node   = parent;
                            parent = node.Parent;
                        } while (parent != null && !(parent is IInitializerOwnerDeclaration));

                        if (parent == null)
                        {
                            return(true);
                        }

                        var initializerOwnerDeclaration = (IInitializerOwnerDeclaration)parent;
                        if (ReferenceEquals(initializerOwnerDeclaration.Initializer, expressionInitializer))
                        {
                            var typeOwner = initializerOwnerDeclaration.DeclaredElement as ITypeOwner;
                            var type      = typeOwner?.Type;
                            if (BurstCodeAnalysisUtil.IsFixedString(type))
                            {
                                return(false);
                            }
                        }
                    }

                    consumer?.AddHighlighting(highlighting);
                    return(true);
                }

                if (parent is ICSharpArgument cSharpArgument)
                {
                    var invocationInfo = cSharpArgument.Invocation;
                    if (invocationInfo is IInvocationExpression info)
                    {
                        var callee = CallGraphUtil.GetCallee(info) as IMethod;

                        if (BurstCodeAnalysisUtil.IsBurstPermittedString(cSharpArgument.GetExpressionType().ToIType()) &&
                            callee != null &&
                            (BurstCodeAnalysisUtil.IsDebugLog(callee) ||
                             BurstCodeAnalysisUtil.IsStringFormat(callee)))
                        {
                            return(false);
                        }
                    }

                    consumer?.AddHighlighting(highlighting);
                    return(true);
                }

                if (parent is IAssignmentExpression assignmentExpression)
                {
                    if (assignmentExpression.Dest == node)
                    {
                        return(false);
                    }

                    if (BurstCodeAnalysisUtil.IsFixedString(assignmentExpression.Dest.Type()) &&
                        assignmentExpression.Source.Type().IsString())
                    {
                        return(false);
                    }

                    consumer?.AddHighlighting(highlighting);
                    return(true);
                }

                if (parent is ITypeMemberDeclaration)
                {
                    consumer?.AddHighlighting(highlighting);
                    return(true);
                }

                node = parent;
            } while (node != null);

            consumer?.AddHighlighting(highlighting);
            return(true);
        }
예제 #7
0
        public override LocalList <IDeclaredElement> GetRootMarksFromNode(ITreeNode currentNode,
                                                                          IDeclaredElement containingFunction)
        {
            var result = new HashSet <IDeclaredElement>();

            switch (currentNode)
            {
            case IStructDeclaration structDeclaration
                when structDeclaration.DeclaredElement is IStruct @struct &&
                @struct.HasAttributeInstance(KnownTypes.BurstCompileAttribute, AttributesSource.Self):
            {
                var superTypes = @struct.GetAllSuperTypes();
                var interfaces = superTypes
                                 .Where(declaredType => declaredType.IsInterfaceType())
                                 .Select(declaredType => declaredType.GetTypeElement())
                                 .WhereNotNull()
                                 .Where(typeElement =>
                                        typeElement.HasAttributeInstance(KnownTypes.JobProducerAttrubyte, AttributesSource.Self))
                                 .ToList();
                var structMethods = @struct.Methods.ToList();

                foreach (var @interface in interfaces)
                {
                    var interfaceMethods = @interface.Methods.ToList();
                    var overridenMethods = structMethods
                                           .Where(m => interfaceMethods.Any(m.OverridesOrImplements))
                                           .ToList();

                    foreach (var overridenMethod in overridenMethods)
                    {
                        result.Add(overridenMethod);
                    }
                }

                break;
            }

            case IInvocationExpression invocationExpression:
            {
                if (!(CallGraphUtil.GetCallee(invocationExpression) is IMethod method))
                {
                    break;
                }
                var containingType = method.GetContainingType();
                if (containingType == null)
                {
                    break;
                }
                if (method.Parameters.Count == 1 &&
                    method.TypeParameters.Count == 1 &&
                    method.ShortName == "CompileFunctionPointer" &&
                    containingType.GetClrName().Equals(KnownTypes.BurstCompiler))
                {
                    var argumentList = invocationExpression.ArgumentList.Arguments;
                    if (argumentList.Count != 1)
                    {
                        break;
                    }
                    var argument = argumentList[0].Value;
                    if (argument == null)
                    {
                        break;
                    }
                    var possibleDeclaredElements = CallGraphUtil.ExtractCallGraphDeclaredElements(argument);
                    foreach (var declaredElement in possibleDeclaredElements)
                    {
                        if (declaredElement != null)
                        {
                            result.Add(declaredElement);
                        }
                    }
                }

                break;
            }
            }

            return(new LocalList <IDeclaredElement>(result.WhereNotNull()));
        }
        protected override bool CheckAndAnalyze(IInvocationExpression invocationExpression,
                                                IHighlightingConsumer consumer)
        {
            //algorithm:
            //if conditional qualifier is open type
            //    return
            //    REASON: burst allows to instantiate generics only with structures. if it is instantiated with class -
            //    it would be highlighted where generics called. if it is instantiated with structure - 2 possible outcomes.
            //    if there are no generic constraints - only object methods can be called, they are handled in BurstReferenceExpressionAnalyzer.
            //    If there is some interface constraint - then it is ok, Burst allows to call interface methods if they are implemented with struct.
            //    CallGraph would have edges to interface through constraints, not instantiation.
            //else
            //    if condional qualifier is class
            //        if conditiinal qualifier is class instance
            //            return
            //            REASON: I will highlight refereceExpression, which would have ReadAccess. Burst can't access
            //            managed objects.
            //        else
            //            if function non static
            //                then it would be highlighted as error
            //            else
            //                ok. burst allows invoking static functions.
            //    else
            //        if conditional qualifier is struct instance
            //            if function is virtual/abstract/override
            //                HIGHLIGHT: invocation expressio WITHOUT parameters
            //                ALSO: struct's method are implicitle sealed!
            //                REASON: burst does not support any invocations that use virtual table.
            //                IMPORTANT: type parameters and open types may have some virtual invocations,
            //                but burst generic system allows only structures/primitives to instatiate generics.
            //                Structure/primitives DOES support some virtual methods from System.Object.
            //            else
            //                it is ok. burst allows any method from structure
            //        else
            //            if function non static
            //                then it would be highlighted as error
            //            else
            //                ok. burst alows invoking static functions.
            var invokedMethod = CallGraphUtil.GetCallee(invocationExpression) as IMethod;

            if (invokedMethod == null)
            {
                return(false);
            }

            if (IsDebugLog(invokedMethod))
            {
                var argumentList = invocationExpression.ArgumentList.Arguments;

                if (argumentList.Count != 1)
                {
                    return(false);
                }

                var argument = argumentList[0];

                if (IsBurstPermittedString(argument.Expression?.Type()))
                {
                    return(false);
                }

                consumer?.AddHighlighting(new BurstDebugLogInvalidArgumentWarning(argument.Expression.GetDocumentRange()));

                return(true);
            }

            if (IsStringFormat(invokedMethod))
            {
                var argumentList = invocationExpression.ArgumentList.Arguments;

                var isWarningPlaced = BurstStringLiteralOwnerAnalyzer.CheckAndAnalyze(invocationExpression,
                                                                                      new BurstManagedStringWarning(invocationExpression.GetDocumentRange()), consumer);

                if (isWarningPlaced)
                {
                    return(true);
                }

                if (argumentList.Count == 0)
                {
                    return(false);
                }

                var firstArgument           = argumentList[0];
                var cSharpLiteralExpression = firstArgument.Expression as ICSharpLiteralExpression;

                if (cSharpLiteralExpression != null && cSharpLiteralExpression.Literal.GetTokenType().IsStringLiteral)
                {
                    return(false);
                }

                consumer?.AddHighlighting(new BurstDebugLogInvalidArgumentWarning(firstArgument.Expression.GetDocumentRange()));
                return(true);
            }

            if (IsObjectMethodInvocation(invocationExpression))
            {
                consumer?.AddHighlighting(new BurstAccessingManagedMethodWarning(invocationExpression.GetDocumentRange(),
                                                                                 invokedMethod.ShortName, invokedMethod.GetContainingType()?.ShortName));

                return(true);
            }

            if (IsReturnValueBurstProhibited(invokedMethod) ||
                HasBurstProhibitedArguments(invocationExpression.ArgumentList))
            {
                consumer?.AddHighlighting(new BurstFunctionSignatureContainsManagedTypesWarning(invocationExpression.GetDocumentRange(),
                                                                                                invokedMethod.ShortName));

                return(true);
            }

            return(false);
        }
 public virtual bool IsCalleeMarked(ICSharpExpression expression, DaemonProcessKind processKind)
 {
     return(IsMarked(CallGraphUtil.GetCallee(expression), processKind));
 }