public override void VisitInvocationExpression(IInvocationExpression invocation, IHighlightingConsumer consumer)
        {
            if (IsCallWithTheSameContextAsFunctionOwner(invocation))
                consumer.AddHighlighting(new CallWithSameContextWarning(invocation), invocation.GetHighlightingRange(), File);

            base.VisitInvocationExpression(invocation, consumer);
        }
        public BurstProblemSubAnalyzerStatus CheckAndAnalyze(IReferenceExpression referenceExpression,
                                                             IHighlightingConsumer consumer)
        {
            var element   = referenceExpression.Reference.Resolve().DeclaredElement;
            var typeOwner = element as ITypeOwner;

            if (typeOwner == null)
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_CONTINUE);
            }

            var modifiersOwner = element as IModifiersOwner;

            if (modifiersOwner == null)
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_CONTINUE);
            }

            if (!IsManaged(modifiersOwner))
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_CONTINUE);
            }

            //virtual and abstract cannot be in struct. only override is getHashCode -> function
            consumer?.AddHighlighting(new BurstLoadingManagedTypeWarning(referenceExpression,
                                                                         typeOwner.Type().GetTypeElement()?.ShortName + "." + element.ShortName));

            return(BurstProblemSubAnalyzerStatus.WARNING_PLACED_STOP);
        }
        public BurstProblemSubAnalyzerStatus CheckAndAnalyze(IInvocationExpression invocationExpression,
                                                             IHighlightingConsumer consumer)
        {
            var invokedMethod = invocationExpression.Reference.Resolve().DeclaredElement as IMethod;

            if (invokedMethod == null)
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_STOP);
            }

            if (!IsDebugLog(invokedMethod))
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_CONTINUE);
            }

            var argumentList = invocationExpression.ArgumentList.Arguments;

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

            var argument = argumentList[0];

            if (argument == null || IsBurstPossibleArgumentString(argument))
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_STOP);
            }

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

            return(BurstProblemSubAnalyzerStatus.WARNING_PLACED_STOP);
        }
Ejemplo n.º 4
0
        public bool CheckAndAnalyze(ICSharpExpression startNode, IHighlighting highlighting, IHighlightingConsumer consumer)
        {
            ITreeNode currentNode = startNode;
            var       result      = false;
            var       analyzed    = false;

            while (!analyzed && currentNode is ICSharpExpression cSharpExpression)
            {
                foreach (var subAnalyzer in mySubAnalyzers)
                {
                    analyzed = subAnalyzer.TryAnalyze(cSharpExpression, out result);

                    if (analyzed)
                    {
                        break;
                    }
                }

                currentNode = currentNode.Parent;
            }

            if (!analyzed || result)
            {
                result = true;
                consumer?.AddHighlighting(highlighting);
            }

            return(result);
        }
Ejemplo n.º 5
0
        public BurstProblemSubAnalyzerStatus CheckAndAnalyze(IInvocationExpression invocationExpression, IHighlightingConsumer consumer)
        {
            var invokedMethod = invocationExpression.Reference.Resolve().DeclaredElement as IMethod;

            if (!BurstCodeAnalysisUtil.IsSharedStaticCreateMethod(invokedMethod))
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_CONTINUE);
            }

            if (invokedMethod.TypeParameters.Count != 0)
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_STOP);
            }

            var methodParameters = invokedMethod.Parameters;

            for (var index = 0; index < methodParameters.Count - 1; index++)
            {
                if (!methodParameters[index].Type.IsSystemType())
                {
                    return(BurstProblemSubAnalyzerStatus.NO_WARNING_STOP);
                }
            }

            consumer?.AddHighlighting(new BurstSharedStaticCreateWarning(invocationExpression));

            return(BurstProblemSubAnalyzerStatus.WARNING_PLACED_STOP);
        }
Ejemplo n.º 6
0
        public BurstProblemSubAnalyzerStatus CheckAndAnalyze(IReferenceExpression referenceExpression, IHighlightingConsumer consumer)
        {
            var element = referenceExpression.Reference.Resolve().DeclaredElement;

            if (!(element is ITypeOwner typeOwner))
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_CONTINUE);
            }

            if (typeOwner is IAttributesOwner attributesOwner &&
                attributesOwner.HasAttributeInstance(KnownTypes.NativeSetClassTypeToNullOnScheduleAttribute, AttributesSource.Self))
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_CONTINUE);
            }

            if (BurstCodeAnalysisUtil.IsBurstPermittedType(typeOwner.Type()))
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_CONTINUE);
            }

            consumer?.AddHighlighting(new BurstLoadingManagedTypeWarning(
                                          referenceExpression,
                                          typeOwner.Type().GetTypeElement()?.ShortName));

            return(BurstProblemSubAnalyzerStatus.WARNING_PLACED_STOP);
        }
        public BurstProblemSubAnalyzerStatus CheckAndAnalyze(IReferenceExpression referenceExpression,
                                                             IHighlightingConsumer consumer)
        {
            var element = referenceExpression.Reference.Resolve().DeclaredElement;

            //non auto property are not interested cuz they are not prohibited,
            //and any backing field will be handled inside accessor
            if ((!(element is IProperty property) || !property.IsAuto) && !(element is IField))
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_CONTINUE);
            }

            var typeMember = (ITypeMember)element;

            if (!referenceExpression.GetAccessType().HasFlag(ExpressionAccessType.Read) ||
                !typeMember.IsStatic ||
                typeMember.IsReadonly ||
                typeMember.IsConstant() ||
                typeMember.IsEnumMember() ||
                typeMember is IProperty prop && !prop.IsWritable && prop.IsReadable)
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_CONTINUE);
            }

            consumer?.AddHighlighting(new BurstLoadingStaticNotReadonlyWarning(referenceExpression,
                                                                               typeMember.GetContainingType()?.ShortName + "." + element.ShortName));

            return(BurstProblemSubAnalyzerStatus.WARNING_PLACED_STOP);
        }
        public BurstProblemSubAnalyzerStatus CheckAndAnalyze(IReferenceExpression referenceExpression,
                                                             IHighlightingConsumer consumer)
        {
            var element = referenceExpression.Reference.Resolve().DeclaredElement;

            //non auto property are not interested cuz they are not prohibited,
            //and any backing field will be handled inside accessor
            if ((!(element is IProperty property) || !property.IsAuto) && !(element is IField))
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_CONTINUE);
            }

            var typeMember = (ITypeMember)element;

            if (!referenceExpression.GetAccessType().HasFlag(ExpressionAccessType.Write) ||
                !typeMember.IsStatic)
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_CONTINUE);
            }

            //there are no static write-only auto properties
            consumer?.AddHighlighting(new BurstWriteStaticFieldWarning(referenceExpression,
                                                                       element.ShortName));

            return(BurstProblemSubAnalyzerStatus.WARNING_PLACED_STOP);
        }
        protected override void Run(IDllImportMethodDeclaration importMethod, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
        {
            var element = importMethod.MethodDeclaration;
            var libraryName = importMethod.ImportedDll;
            var factory = new LibraryFactory();
            var library = factory.LoadLibrary(libraryName);
            var export = library[element.NameIdentifier.Name];
            if (export == null || export.Parameters.Count != element.ParameterDeclarations.Count)
            {
                return;
            }

            for (var i = 0; i < element.ParameterDeclarations.Count; i++ )
            {
                var parameter = element.ParameterDeclarations[i];
                var knownParameter = export.Parameters[i];
                var exportedType = new ClrTypeName(knownParameter.CLRType.FullName);
                if (parameter.Type.IsInt() && exportedType.Equals(IntPtrClrType))
                {
                    consumer.AddHighlighting(new DllImportInt32ForIntPtrHighlighting(parameter));
                }
                var marshalAs = parameter.Attributes.GetAttibuteOfCLRType(MarshalAsAttribute);
                if (knownParameter.UnmanagedType.HasValue && marshalAs != null && marshalAs.ConstructorArgumentExpressions.Count == 1)
                {
                    var argumentExpression = marshalAs.ConstructorArgumentExpressions[0];
                    if (!argumentExpression.IsConstantValue())
                    {
                        continue;
                    }
                    var shortType = argumentExpression.ConstantValue.IsShort();
                    UnmanagedType unmanagedType;
                    if (shortType)
                    {
                        unmanagedType = (UnmanagedType)(short)argumentExpression.ConstantValue.Value;
                    }
                    else
                    {
                        unmanagedType = (UnmanagedType)argumentExpression.ConstantValue.Value;
                    }
                    if (knownParameter.UnmanagedType.Value != unmanagedType)
                    {
                        consumer.AddHighlighting(new DllImportIncorrectParameterMarshalHighlighting(parameter, argumentExpression, knownParameter.UnmanagedType.Value));
                    }
                }
            }
        }
        public override void VisitNode(ITreeNode element, IHighlightingConsumer consumer)
        {
            var tokenNode = element as ITokenNode;
            if (tokenNode != null && tokenNode.GetTokenType().IsWhitespace) return;

            var colorInfo = CreateColorHighlightingInfo(element);
            if (colorInfo != null)
                consumer.AddHighlighting(colorInfo.Highlighting, colorInfo.Range);
        }
        protected override bool CheckAndAnalyze(IObjectCreationExpression objectCreationExpression, IHighlightingConsumer consumer)
        {
            if (!IsBurstPermittedType(objectCreationExpression.Type()))
            {
                consumer?.AddHighlighting(new BurstCreatingManagedTypeWarning(objectCreationExpression.GetDocumentRange(), (objectCreationExpression.ConstructorReference.Resolve().DeclaredElement as IConstructor)?.GetContainingType()?.ShortName));
                return(true);
            }

            return(false);
        }
 private void AddHighLighting(
     DocumentRange range, ITreeNode element, IHighlightingConsumer consumer, IHighlighting highlighting)
 {
     var info = new HighlightingInfo(range, highlighting, new Severity?());
     IFile file = element.GetContainingFile();
     if (file != null)
     {
         consumer.AddHighlighting(info.Highlighting, file);
     }
 }
 public override void VisitRuleDeclaredName(IRuleDeclaredName ruleDeclaredName, IHighlightingConsumer consumer)
 {
   string name = ruleDeclaredName.GetText();
   if (myDeclarations.ContainsKey(name))
   {
     List<IDeclaration> list = myDeclarations.GetValue(name);
     if (list.Count > 1)
     {
       consumer.AddHighlighting(new DuplicatingLocalDeclarationError(ruleDeclaredName), File);
     }
   }
   base.VisitRuleDeclaredName(ruleDeclaredName, consumer);
 }
 public override void VisitRuleDeclaration(IRuleDeclaration ruleDeclaration, IHighlightingConsumer consumer)
 {
   IRuleBody body = ruleDeclaration.Body;
   ITreeNode child = PsiTreeUtil.GetFirstChild<IRuleName>(body);
   var ruleName = child as IRuleName;
   if (ruleName != null)
   {
     if (ruleName.GetText().Equals(ruleDeclaration.DeclaredName))
     {
       consumer.AddHighlighting(new LeftRecursionWarning(ruleName), File);
     }
   }
   base.VisitRuleDeclaration(ruleDeclaration, consumer);
 }
        private void VisitLoop(ITreeNode loop, IHighlightingConsumer consumer)
        {
            var function = loop.GetContainingNode<IJsFunctionLike>();
            var accessAnalizer = new VariableCollector();
            loop.ProcessThisAndDescendants(accessAnalizer);
            var accessToExternalModifiedClosure = accessAnalizer.Variables
                .GroupBy(r => r.DeclaredElement)
                .Select(g => g.ToArray())
                .Where(l => HasExternallyModifiedClosure(function, l))
                .SelectMany(l => l)
                .Where(r => r.FunctionLike != function)
                .Select(info => info.Node);

            foreach (var expression in accessToExternalModifiedClosure)
            {
                consumer.AddHighlighting(new AccessToModifiedClosureWarning(expression), expression.GetHighlightingRange(), File);
            }
        }
Ejemplo n.º 16
0
		public override void VisitClassDeclaration(IClassDeclaration classDeclarationParam, IHighlightingConsumer context) {
			base.VisitClassDeclaration(classDeclarationParam, context);

			if (!classDeclarationParam.IsSynthetic()
			|| !T4CSharpCodeGenerator.ClassName.Equals(classDeclarationParam.DeclaredName, StringComparison.Ordinal))
				return;

			IDeclaredTypeUsage superTypeUsage = classDeclarationParam.SuperTypeUsageNodes.FirstOrDefault();
			if (superTypeUsage == null
			|| T4CSharpCodeGenerator.DefaultBaseClassName.Equals(superTypeUsage.GetText(), StringComparison.Ordinal))
				return;

			ITypeElement typeElement = CSharpTypeFactory.CreateDeclaredType(superTypeUsage).GetTypeElement();
			if (typeElement == null)
				return;

			if (!typeElement.Methods.Any(IsTransformTextMethod))
				context.AddHighlighting(new MissingTransformTextMethodHighlighting(superTypeUsage));
		}
        public BurstProblemSubAnalyzerStatus CheckAndAnalyze(IInvocationExpression invocationExpression,
                                                             IHighlightingConsumer consumer)
        {
            var invokedMethod = invocationExpression.Reference.Resolve().DeclaredElement as IMethod;

            if (invokedMethod == null)
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_STOP);
            }

            if (!IsStringFormat(invokedMethod))
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_CONTINUE);
            }

            var argumentList = invocationExpression.ArgumentList.Arguments;

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

            if (isWarningPlaced)
            {
                return(BurstProblemSubAnalyzerStatus.WARNING_PLACED_STOP);
            }

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

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

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

            consumer?.AddHighlighting(
                new BurstDebugLogInvalidArgumentWarning(firstArgument.Expression));

            return(BurstProblemSubAnalyzerStatus.WARNING_PLACED_STOP);
        }
        public BurstProblemSubAnalyzerStatus CheckAndAnalyze(IInvocationExpression invocationExpression, IHighlightingConsumer consumer)
        {
            var invokedMethod = invocationExpression.Reference.Resolve().DeclaredElement as IMethod;

            if (invokedMethod == null || UnityCallGraphUtil.IsQualifierOpenType(invocationExpression))
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_STOP);
            }

            if (!IsBurstProhibitedObjectMethod(invokedMethod))
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_CONTINUE);
            }

            consumer?.AddHighlighting(new BurstAccessingManagedMethodWarning(invocationExpression,
                                                                             invokedMethod.ShortName, invokedMethod.GetContainingType()?.ShortName));

            return(BurstProblemSubAnalyzerStatus.WARNING_PLACED_STOP);
        }
Ejemplo n.º 19
0
        public BurstProblemSubAnalyzerStatus CheckAndAnalyze(IInvocationExpression invocationExpression,
                                                             IHighlightingConsumer consumer)
        {
            var invokedMethod = invocationExpression.Reference.Resolve().DeclaredElement as IParametersOwner;

            if (invokedMethod == null)
            {
                return(BurstProblemSubAnalyzerStatus.NO_WARNING_STOP);
            }

            var argumentList = invocationExpression.ArgumentList;

            if (HasBurstProhibitedReturnValue(invokedMethod) ||
                argumentList != null && HasBurstProhibitedArguments(invocationExpression.ArgumentList))
            {
                consumer?.AddHighlighting(
                    new BurstFunctionSignatureContainsManagedTypesWarning(invocationExpression, invokedMethod.ShortName));

                return(BurstProblemSubAnalyzerStatus.WARNING_PLACED_STOP);
            }

            return(BurstProblemSubAnalyzerStatus.NO_WARNING_CONTINUE);
        }
Ejemplo n.º 20
0
 public override void VisitNode(ITreeNode node, IHighlightingConsumer context)
 {
     base.VisitNode(node, context);
     string attributeId = GetHighlightingAttributeId(node);
     if (attributeId != null)
         context.AddHighlighting(new PredefinedHighlighting(attributeId), node.GetHighlightingRange());
 }
Ejemplo n.º 21
0
        private static void CheckForeachDeclaration(
            [NotNull] IForeachStatement foreachStatement, [NotNull] IHighlightingConsumer consumer)
        {
            var collection = foreachStatement.Collection;

            if (collection == null)
            {
                return;
            }

            var collectionType = collection.Type() as IDeclaredType;

            if (collectionType == null || collectionType.IsUnknown)
            {
                return;
            }

            // no allocations because of compiler support (just like arrays)
            if (collectionType.IsString())
            {
                return;
            }

            var typeElement = collectionType.GetTypeElement();

            if (typeElement == null)
            {
                return;
            }

            // search for GetEnumerator() method
            var symbolTable = ResolveUtil.GetSymbolTableByTypeElement(
                typeElement, SymbolTableMode.FULL, typeElement.Module);

            foreach (var symbolInfo in symbolTable.GetSymbolInfos("GetEnumerator"))
            {
                var method = symbolInfo.GetDeclaredElement() as IMethod;
                if (method == null)
                {
                    continue;
                }
                if (!CSharpDeclaredElementUtil.IsForeachEnumeratorPatternMember(method))
                {
                    continue;
                }

                // with ref-return
                if (method.ReturnType.Classify == TypeClassification.REFERENCE_TYPE)
                {
                    DocumentRange range;
                    var           inToken = collection.GetPreviousMeaningfulToken();
                    if (inToken != null && inToken.GetTokenType().IsKeyword)
                    {
                        range = inToken.GetDocumentRange();
                    }
                    else
                    {
                        range = collection.GetExpressionRange();
                    }

                    consumer.AddHighlighting(
                        new ObjectAllocationHighlighting(foreachStatement,
                                                         "possible enumerator allocation (except iterators or collection with cached enumerator)"),
                        range);
                }

                break;
            }
        }
        void AnalyzeWhenExpressionIsKnownToBeNullOrNotNull(
            [NotNull] IHighlightingConsumer context,
            [CanBeNull] CSharpCompilerNullableInspector nullabilityInspector,
            [CanBeNull] CSharpControlFlowGraphInspector inspector,
            [CanBeNull][ItemNotNull] HashSet <IAsExpression> alwaysSuccessTryCastExpressions,
            [NotNull] Assertion assertion,
            bool isKnownToBeNull)
        {
            if (assertion is AssertionStatement assertionStatement)
            {
                // pattern: Assert(null);
                Debug.Assert(CSharpTokenType.NULL_KEYWORD != null);
                if (isKnownToBeNull && IsLiteral(assertionStatement.Expression, CSharpTokenType.NULL_KEYWORD))
                {
                    context.AddHighlighting(
                        new RedundantAssertionStatementSuggestion("Assertion is redundant because the expression is null here.", assertionStatement));
                }

                // pattern: Assert(x); when x is known to be null or not null
                switch (GetExpressionNullReferenceState(
                            nullabilityInspector,
                            inspector,
                            alwaysSuccessTryCastExpressions,
                            assertionStatement.Expression))
                {
                case CSharpControlFlowNullReferenceState.NOT_NULL:
                    if (!isKnownToBeNull)
                    {
                        context.AddHighlighting(
                            new RedundantAssertionStatementSuggestion(
                                "Assertion is redundant because the expression is not null here.",
                                assertionStatement));
                    }
                    break;

                case CSharpControlFlowNullReferenceState.NULL:
                    if (isKnownToBeNull)
                    {
                        context.AddHighlighting(
                            new RedundantAssertionStatementSuggestion(
                                "Assertion is redundant because the expression is null here.",
                                assertionStatement));
                    }
                    break;
                }
            }

            if (!isKnownToBeNull)
            {
                switch (assertion)
                {
                case InlineAssertion inlineAssertion:
                    if (GetExpressionNullReferenceState(
                            nullabilityInspector,
                            inspector,
                            alwaysSuccessTryCastExpressions,
                            inlineAssertion.QualifierExpression) ==
                        CSharpControlFlowNullReferenceState.NOT_NULL)
                    {
                        context.AddHighlighting(
                            new RedundantInlineAssertionSuggestion(
                                "Assertion is redundant because the expression is not null here.",
                                inlineAssertion));
                    }
                    break;

                case NullForgivingOperation nullForgivingOperation:
                    Debug.Assert(nullForgivingOperation.SuppressNullableWarningExpression.Operand != null);

                    if (GetExpressionNullReferenceState(
                            nullabilityInspector,
                            inspector,
                            alwaysSuccessTryCastExpressions,
                            nullForgivingOperation.SuppressNullableWarningExpression.Operand) ==
                        CSharpControlFlowNullReferenceState.NOT_NULL)
                    {
                        context.AddHighlighting(
                            new RedundantNullForgivingOperatorSuggestion(
                                "Null-forgiving operator is redundant because the expression is not null here.",
                                nullForgivingOperation));
                    }
                    break;
                }
            }
        }
 private void AddSentenceSuggestionHighlighting(
     IHighlightingConsumer consumer, string message, ISentence startElement, ISentence endElement)
 {
     var highlighting = new HintRangeHighlighting<ISentence>(startElement, endElement, message);
     IFile file = startElement.GetContainingFile();
     if (file != null)
     {
         consumer.AddHighlighting(highlighting, file);
     }
 }
Ejemplo n.º 24
0
        protected override bool CheckAndAnalyze(IReferenceExpression referenceExpression,
                                                IHighlightingConsumer consumer)
        {
            var element = referenceExpression.Reference.Resolve().DeclaredElement;

            //here I want to handle next situations
            //1. accessing type members, whether static or not, including: properties, fields, localVariable, parameters

            //non auto property are not interested cuz they are not prohibited,
            //and any backing field will be handled inside accessor
            if (element is IProperty property && property.IsAuto || element is IField)
            {
                var typeMember = (ITypeMember)element;
                if (referenceExpression.GetAccessType().HasFlag(ExpressionAccessType.Read) &&
                    typeMember.IsStatic &&
                    !typeMember.IsReadonly &&
                    !typeMember.IsConstant() &&
                    !typeMember.IsEnumMember() &&
                    !(typeMember is IProperty prop && !prop.IsWritable && prop.IsReadable))
                {
                    consumer?.AddHighlighting(new BurstLoadingStaticNotReadonlyWarning(
                                                  referenceExpression.GetDocumentRange(),
                                                  typeMember.GetContainingType()?.ShortName + "." + element.ShortName));
                    return(true);
                }

                if (referenceExpression.GetAccessType().HasFlag(ExpressionAccessType.Write) && typeMember.IsStatic)
                {
                    //there are no static write-only auto properties
                    var field = element.ShortName;
                    if (element is IProperty)
                    {
                        field += "__backing_field";
                    }
                    consumer?.AddHighlighting(new BurstWriteStaticFieldWarning(referenceExpression.GetDocumentRange(),
                                                                               field));
                    return(true);
                }
            }

            if (element is ITypeOwner typeOwner)
            {
                if (element is IModifiersOwner modifiersOwner &&
                    (modifiersOwner.IsVirtual || modifiersOwner.IsOverride || modifiersOwner.IsAbstract))
                {
                    //virtual and abstract cannot be in struct. only override is getHashCode -> function
                    consumer?.AddHighlighting(new BurstLoadingManagedTypeWarning(
                                                  referenceExpression.GetDocumentRange(),
                                                  typeOwner.Type().GetTypeElement()?.ShortName + "." + element.ShortName));
                    return(true);
                }

                if (!IsBurstPermittedType(typeOwner.Type()))
                {
                    if (typeOwner is IAttributesOwner attributesOwner &&
                        attributesOwner.HasAttributeInstance(KnownTypes.NativeSetClassTypeToNullOnScheduleAttribute,
                                                             AttributesSource.Self))
                    {
                        return(false);
                    }

                    consumer?.AddHighlighting(new BurstLoadingManagedTypeWarning(
                                                  referenceExpression.GetDocumentRange(),
                                                  typeOwner.Type().GetTypeElement()?.ShortName));
                    return(true);
                }
            }

            return(false);
        }
Ejemplo n.º 25
0
 private void AddHighLighting(DocumentRange range, IHighlightingConsumer consumer, IHighlighting highlighting)
 {
     var info = new HighlightingInfo(range, highlighting, new Severity?());
     consumer.AddHighlighting(info.Highlighting, file);
 }
        public static void SpellCheck(
            IDocument document, ITokenNode token, ISpellChecker spellChecker,
            ISolution solution, IHighlightingConsumer highlightingConsumer,
            IContextBoundSettingsStore settingsStore, CommentSettings settings)
        {
            if (spellChecker == null)
            {
                return;
            }

            string buffer    = token.GetText();
            ILexer wordLexer = new WordLexer(buffer);

            wordLexer.Start();
            while (wordLexer.TokenType != null)
            {
                string tokenText = wordLexer.GetCurrTokenText();
                if (SpellCheckUtil.ShouldSpellCheck(tokenText, settings.CompiledWordsToIgnore) &&
                    !spellChecker.TestWord(tokenText, true))
                {
                    IClassMemberDeclaration containingElement =
                        token.GetContainingNode <IClassMemberDeclaration>(false);
                    if (containingElement == null ||
                        !IdentifierResolver.IsIdentifier(containingElement, solution, tokenText))
                    {
                        CamelHumpLexer camelHumpLexer = new CamelHumpLexer(buffer, wordLexer.TokenStart, wordLexer.TokenEnd);
                        foreach (LexerToken humpToken in camelHumpLexer)
                        {
                            if (SpellCheckUtil.ShouldSpellCheck(humpToken.Value, settings.CompiledWordsToIgnore) &&
                                !spellChecker.TestWord(humpToken.Value, true))
                            {
                                //int start = token.GetTreeStartOffset().Offset + wordLexer.TokenStart;
                                //int end = start + tokenText.Length;

                                //var range = new TextRange(start, end);
                                //var documentRange = new DocumentRange(document, range);
                                DocumentRange documentRange =
                                    token.GetContainingFile().TranslateRangeForHighlighting(token.GetTreeTextRange());
                                documentRange = documentRange.ExtendLeft(-wordLexer.TokenStart);
                                documentRange = documentRange.ExtendRight(-1 * (documentRange.GetText().Length - tokenText.Length));


                                TextRange textRange = new TextRange(humpToken.Start - wordLexer.TokenStart,
                                                                    humpToken.End - wordLexer.TokenStart);
                                //string word = document.GetText(range);
                                string word = documentRange.GetText();


                                var highlighting = new StringSpellCheckHighlighting(
                                    document.GetText(textRange), documentRange,
                                    humpToken.Value, textRange,
                                    solution, spellChecker, settingsStore);
                                var file = token.GetContainingFile();

                                highlightingConsumer.AddHighlighting(highlighting, documentRange, file);

                                break;
                            }
                        }
                    }
                }

                wordLexer.Advance();
            }
        }
Ejemplo n.º 27
0
        public override void Report(IHighlightingConsumer consumer)
        {
            if (CanUseIndividualReports())
            {
                foreach (var componentBoxing in ComponentBoxings)
                {
                    componentBoxing.Report(consumer);
                }

                return;
            }

            var singleBoxing = TryFindSingleOrdinaryBoxing();

            if (singleBoxing != null)
            {
                var reason = singleBoxing.Reason;

                if (!singleBoxing.IsPossible)
                {
                    var description = $"tuple component {reason} performs boxing of the value type";
                    consumer.AddHighlighting(new BoxingAllocationHighlighting(CorrespondingNode, description));
                }
                else
                {
                    var description = $"tuple component {reason} possibly performs boxing of the value type";
                    consumer.AddHighlighting(new PossibleBoxingAllocationHighlighting(CorrespondingNode, description));
                }

                return;
            }

            var isAllPossible = IsAllPossible;

            using var builder = PooledStringBuilder.GetInstance();
            builder.Append("tuple conversion contains component type conversions that perform ");
            if (isAllPossible)
            {
                builder.Append("possible ");
            }
            builder.AppendLine("boxing of the value types");

            AppendReasons(builder.Builder, indent: "    ", presentPossible: IsAnyPossible && !isAllPossible);
            var longDescription = builder.ToString().Trim();

            if (isAllPossible)
            {
                consumer.AddHighlighting(new PossibleBoxingAllocationHighlighting(CorrespondingNode, longDescription));
            }
            else
            {
                consumer.AddHighlighting(new BoxingAllocationHighlighting(CorrespondingNode, longDescription));
            }

            bool CanUseIndividualReports()
            {
                foreach (var componentBoxing in ComponentBoxings)
                {
                    if (componentBoxing.CorrespondingNode == CorrespondingNode)
                    {
                        return(false);
                    }
                }

                return(true);
            }
Ejemplo n.º 28
0
 protected override void AddHighlighting(IHighlightingConsumer consumer, ICSharpDeclaration declaration, string text, string tooltip, DaemonProcessKind kind)
 {
     consumer.AddImplicitConfigurableHighlighting(declaration);
     consumer.AddHighlighting(new UnityGutterMarkInfo(GetActions(declaration), declaration, tooltip));
 }
Ejemplo n.º 29
0
        protected override void Run(ICSharpFunctionDeclaration element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
        {
            if (element.Body == null)
            {
                return;
            }

            var elementProcessor = new ElementProcessor(
                element,
                consumer);

            element.Body.ProcessDescendants(elementProcessor);

            var store           = data.SettingsStore;
            var baseThreshold   = store.GetValue((CognitiveComplexityAnalysisSettings s) => s.CSharpThreshold);
            var lowThreshold    = store.GetValue((CognitiveComplexityAnalysisSettings s) => s.LowComplexityThreshold);
            var middleThreshold = store.GetValue((CognitiveComplexityAnalysisSettings s) => s.MiddleComplexityThreshold);
            var highThreshold   = store.GetValue((CognitiveComplexityAnalysisSettings s) => s.HighComplexityThreshold);

            var complexityPercentage = (int)(elementProcessor.ComplexityScore * 100.0 / baseThreshold);

            string codeLensText;
            IconId iconId;

            if (complexityPercentage >= highThreshold)
            {
                iconId       = ComplexityExtreme.Id;
                codeLensText = complexityPercentage >= highThreshold * 2
                    ? $"refactor me? ({complexityPercentage}%)"
                    : $"very complex ({complexityPercentage}%)";
            }
            else if (complexityPercentage >= middleThreshold)
            {
                iconId       = ComplexityHigh.Id;
                codeLensText = $"mildly complex ({complexityPercentage}%)";
            }
            else if (complexityPercentage >= lowThreshold)
            {
                iconId       = ComplexityAverage.Id;
                codeLensText = $"simple enough ({complexityPercentage}%)";
            }
            else
            {
                iconId       = ComplexityLow.Id;
                codeLensText = string.Empty;
            }

            if (complexityPercentage > 100)
            {
                consumer.AddHighlighting(new CognitiveComplexityHighlighting(element, complexityPercentage));
            }

#if RIDER
            var moreText =
                $"Cognitive complexity value of {elementProcessor.ComplexityScore} " +
                $"({complexityPercentage}% of threshold {baseThreshold})";
            consumer.AddHighlighting(
                new CodeInsightsHighlighting(
                    element.GetNameDocumentRange(),
                    codeLensText,
                    moreText,
                    moreText,
                    _overallProvider,
                    element.DeclaredElement,
                    _iconHost.Transform(iconId))
                );
#endif
        }
Ejemplo n.º 30
0
        public static void CreateInefficientMultidimensionalArrayAccessWarning([CanBeNull] IDeclaredElement declaredElement,
                                                                               [NotNull] IVariableDeclaration variableDeclaration, [NotNull]  IDaemonProcess daemonProcess, [NotNull]  DaemonProcessKind kind,
                                                                               [NotNull] IHighlightingConsumer consumer, [NotNull] DocumentRange highlightingRange)
        {
            if (declaredElement == null)
            {
                return;
            }

            var type = variableDeclaration.Type as IArrayType;

            if (type == null)
            {
                return;
            }

            if (type.Rank == 1)
            {
                return;
            }

            IArrayCreationExpression arrayCreationExpression = null;
            IMultipleDeclaration     multipleDeclaration     = null;

            switch (variableDeclaration)
            {
            case IFieldDeclaration fieldDeclaration:
                // perfomance optimization
                if (fieldDeclaration.GetAccessRights() != AccessRights.PRIVATE)
                {
                    return;
                }

                arrayCreationExpression = (fieldDeclaration.Initial as IExpressionInitializer)?.Value as IArrayCreationExpression;
                multipleDeclaration     = MultipleFieldDeclarationNavigator.GetByDeclarator(fieldDeclaration);

                break;

            case ILocalVariableDeclaration localVariableDeclaration:
                var initial = localVariableDeclaration.Initial;
                arrayCreationExpression = (initial as IExpressionInitializer)?.Value as IArrayCreationExpression;

                if (initial != null && arrayCreationExpression == null)
                {
                    return;
                }

                multipleDeclaration =
                    MultipleLocalVariableDeclarationNavigator.GetByDeclarator(localVariableDeclaration);
                break;

            default:
                return;
            }

            var classDeclaration = variableDeclaration.GetContainingNode <IClassLikeDeclaration>();

            if (classDeclaration == null)
            {
                return;
            }

            var usages = FindArrayUsages(declaredElement, classDeclaration, daemonProcess, kind);

            foreach (var usage in usages)
            {
                if (ElementAccessExpressionNavigator.GetByOperand(usage as ICSharpExpression) == null)
                {
                    return;
                }
            }

            if (arrayCreationExpression.ContainsErrorElement())
            {
                return;
            }

            consumer.AddHighlighting(new InefficientMultidimensionalArrayUsageWarning(usages.Select(t => t.CreateTreeElementPointer()).ToList(),
                                                                                      arrayCreationExpression, variableDeclaration, multipleDeclaration, highlightingRange));
        }
        /// <summary>
        /// Adds the highlighting.
        /// </summary>
        ///<param name="consumer">The consumer.</param>
        ///<param name="highlighting">The highlighting.</param>
        private static void AddHighlighting(IHighlightingConsumer consumer, SuggestionBase highlighting)
        {
            var range = highlighting.Range;
              if (!range.IsValid())
              {
            return;
              }

              consumer.AddHighlighting(range, highlighting);
        }
        protected override void Analyze(IMemberOwnerDeclaration element, ElementProblemAnalyzerData data,
                                        IHighlightingConsumer consumer)
        {
            var typeElement = element.DeclaredElement;

            if (typeElement == null)
            {
                return;
            }

            if (!Api.IsUnityType(typeElement))
            {
                return;
            }

            var map = new OneToListMap <UnityEventFunction, Candidate>(new UnityEventFunctionKeyComparer());

            foreach (var member in typeElement.GetMembers())
            {
                if (member is IMethod method)
                {
                    var unityEventFunction = Api.GetUnityEventFunction(method, out var match);
                    if (unityEventFunction != null)
                    {
                        map.Add(unityEventFunction, new Candidate(method, match));
                    }
                }
            }

            foreach (var pair in map)
            {
                var function   = pair.Key;
                var candidates = pair.Value;
                if (candidates.Count == 1)
                {
                    // Only one function, mark it as a unity function, even if it's not an exact match
                    // We'll let other inspections handle invalid signatures
                    var method = candidates[0].Method;
                    AddGutterMark(consumer, method, function);
                    AddMethodSignatureInspections(consumer, method, function, candidates[0].Match);
                }
                else
                {
                    var hasExactMatch = false;

                    // All exact matches should be marked as an event function
                    var duplicates = new FrugalLocalList <IMethod>();
                    foreach (var candidate in candidates)
                    {
                        if (candidate.Match == MethodSignatureMatch.ExactMatch)
                        {
                            AddGutterMark(consumer, candidate.Method, function);
                            hasExactMatch = true;
                            duplicates.Add(candidate.Method);
                        }
                    }

                    // Multiple exact matches should be marked as duplicate/ambiguous
                    if (duplicates.Count > 1)
                    {
                        foreach (var method in duplicates)
                        {
                            foreach (var declaration in method.GetDeclarations())
                            {
                                consumer.AddHighlighting(
                                    new DuplicateEventFunctionWarning((IMethodDeclaration)declaration));
                            }
                        }
                    }

                    // If there are no exact matches, mark all as unity functions, with inspections
                    // to fix up signature errors
                    if (!hasExactMatch)
                    {
                        foreach (var candidate in candidates)
                        {
                            var method = candidate.Method;
                            AddGutterMark(consumer, method, function);
                            AddMethodSignatureInspections(consumer, method, function, candidate.Match);
                        }
                    }
                }
            }
        }
Ejemplo n.º 33
0
        public override void VisitNode(ITreeNode node, IHighlightingConsumer context)
        {
            base.VisitNode(node, context);

            DocumentRange highlightingRange = node.GetHighlightingRange();
            //context.AddHighlighting(new PredefinedHighlighting(VsPredefinedHighlighterIds.RazorCode), highlightingRange);

            string attributeId = GetHighlightingAttributeId(node);
            if (attributeId != null)
                context.AddHighlighting(new PredefinedHighlighting(attributeId), highlightingRange);
        }
Ejemplo n.º 34
0
 private void AddHighlighting([NotNull] IHighlightingConsumer consumer, [NotNull] ITreeNode expression)
 {
     consumer.AddHighlighting(new PsiErrorElementHighlighting(expression), File);
 }
        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);
        }
Ejemplo n.º 36
0
        private static void CheckExpression([NotNull] ICSharpExpression expression, [NotNull] IHighlightingConsumer consumer)
        {
            var targetType = expression.GetImplicitlyConvertedTo();

            if (!targetType.IsReferenceType())
            {
                return;
            }

            var expressionType = expression.Type();

            if (expressionType.IsUnknown)
            {
                return;
            }

            if (targetType.IsDelegateType())
            {
                var referenceExpression = expression as IReferenceExpression;

                var method = referenceExpression?.Reference.Resolve().DeclaredElement as IMethod;
                if (method == null || method.IsStatic || method.IsExtensionMethod)
                {
                    return;
                }

                ITypeElement valueType           = null;
                var          qualifierExpression = referenceExpression.QualifierExpression;
                if (qualifierExpression == null || qualifierExpression is IBaseExpression)
                {
                    var declaration = expression.GetContainingTypeDeclaration();
                    if (declaration != null)
                    {
                        valueType = declaration.DeclaredElement as IStruct;
                    }
                }
                else
                {
                    var type = qualifierExpression.Type() as IDeclaredType;
                    if (type != null)
                    {
                        valueType = type.GetTypeElement();
                    }
                }

                if (valueType != null)
                {
                    var sourceType = TypeFactory.CreateType(valueType);
                    if (sourceType.IsValueType())
                    {
                        var description = BakeDescription(
                            "conversion of value type '{0}' instance method to '{1}' delegate type", sourceType, targetType);

                        consumer.AddHighlighting(
                            new BoxingAllocationHighlighting(expression, description),
                            referenceExpression.NameIdentifier.GetDocumentRange());
                    }
                }
            }
            else
            {
                if (targetType.IsUnknown || targetType.Equals(expressionType))
                {
                    return;
                }

                var conversionRule = expression.GetTypeConversionRule();
                if (conversionRule.IsBoxingConversion(expressionType, targetType))
                {
                    // there is no boxing conversion here: using (new DisposableStruct()) { }
                    var usingStatement = UsingStatementNavigator.GetByExpression(expression.GetContainingParenthesizedExpression());
                    if (usingStatement != null)
                    {
                        return;
                    }

                    if (HeapAllocationAnalyzer.IsIgnoredContext(expression))
                    {
                        return;
                    }

                    var description = BakeDescription("conversion from value type '{0}' to reference type '{1}'", expressionType, targetType);

                    consumer.AddHighlighting(
                        new BoxingAllocationHighlighting(expression, description), expression.GetExpressionRange());
                }
            }
        }
Ejemplo n.º 37
0
 protected override bool CheckAndAnalyze(ITypeofExpression typeofExpression, IHighlightingConsumer consumer)
 {
     consumer?.AddHighlighting(new BurstTypeofExpressionWarning(typeofExpression));
     return(true);
 }
 public static void AddImplicitConfigurableHighlighting(this IHighlightingConsumer consumer,
                                                        ICSharpDeclaration declaration)
 {
     consumer.AddHighlighting(new UnityImplicitlyUsedIdentifierHighlighting(declaration.NameIdentifier.GetDocumentRange()));
 }
    public override void VisitPsiExpression(IPsiExpression psiExpression, IHighlightingConsumer consumer)
    {
      ITreeNode child = psiExpression.FirstChild;
      IList<ISequence> list = new List<ISequence>();
      while (child != null)
      {
        if (child is ISequence)
        {
          list.Add(child as ISequence);
        }
        if (child is IChoiceTail)
        {
          list.Add((child as IChoiceTail).Sequence);
        }
        child = child.NextSibling;
      }

      if (list.Count > 1)
      {
        ISequence[] sequences = list.ToArray();
        var isRepeated = new bool[sequences.Count()];
        for (int i = 0 ; i < sequences.Count() - 1 ; ++i)
        {
          if (!isRepeated[i])
          {
            ISequence sequence1 = sequences[i];
            for (int j = i + 1 ; j < sequences.Count() ; ++j)
            {
              ISequence sequence2 = sequences[j];
              if (PsiTreeUtil.EqualsElements(sequence1, sequence2))
              {
                if (!isRepeated[i])
                {
                  consumer.AddHighlighting(new RepeatedChoiceWarning(sequence1), File);
                  isRepeated[i] = true;
                }
                consumer.AddHighlighting(new RepeatedChoiceWarning(sequence2), File);
                isRepeated[j] = true;
              }
            }
          }
        }
      }
      base.VisitPsiExpression(psiExpression, consumer);
    }
Ejemplo n.º 40
0
        public void AddInspectorHighlighting(IHighlightingConsumer consumer, ICSharpDeclaration element,
                                             IDeclaredElement declaredElement, string baseDisplayName, string baseTooltip, string moreText, IconModel iconModel,
                                             IEnumerable <BulbMenuItem> items, List <CodeLensEntryExtraActionModel> extraActions)
        {
            string displayName = null;

            var solution = element.GetSolution();

            Assertion.Assert(solution.Locks.IsReadAccessAllowed(), "ReadLock required");

            var field          = (declaredElement as IField).NotNull();
            var type           = field.Type;
            var containingType = field.GetContainingType();

            if (containingType == null)
            {
                base.AddHighlighting(consumer, element, field, baseDisplayName, baseTooltip, moreText, iconModel, items, extraActions);
                return;
            }

            var(guidN, propertyNames) = GetAssetGuidAndPropertyName(solution, field);
            if (guidN == null || propertyNames.Length == 0)
            {
                base.AddHighlighting(consumer, element, field, baseDisplayName, baseTooltip, moreText, iconModel, items, extraActions);
                return;
            }

            var guid = guidN.Value;

            var presentationType = GetUnityPresentationType(type);

            if (!myDeferredCacheController.CompletedOnce.Value || ShouldShowUnknownPresentation(presentationType))
            {
                base.AddHighlighting(consumer, element, field, baseDisplayName, baseTooltip, moreText, iconModel, items, extraActions);
                return;
            }

            if (presentationType == UnityPresentationType.UnityEvent)
            {
                var count = myUnityEventsElementContainer.GetUsageCountForEvent(field, out var estimated);
                var sb    = new StringBuilder();
                if (count == 0 && !estimated)
                {
                    sb.Append("No methods");
                }
                else
                {
                    sb.Append(count);
                    if (estimated)
                    {
                        sb.Append('+');
                    }
                    sb.Append(" ");
                    sb.Append("method");
                    if (estimated || count > 1)
                    {
                        sb.Append("s");
                    }
                }

                consumer.AddHighlighting(new UnityInspectorCodeInsightsHighlighting(element.GetNameDocumentRange(),
                                                                                    sb.ToString(), GetTooltip(count, estimated, false), "Methods", this,
                                                                                    declaredElement, iconModel, presentationType));
                return;
            }


            var initializer = (element as IFieldDeclaration).NotNull("element as IFieldDeclaration != null").Initial;
            var initValue   = (initializer as IExpressionInitializer)?.Value?.ConstantValue.Value;

            var initValueUnityPresentation = GetUnitySerializedPresentation(presentationType, initValue);

            int  changesCount;
            bool isEstimated    = false;
            bool isUniqueChange = false;

            if (myInspectorValuesContainer.IsIndexResultEstimated(guid, containingType, propertyNames))
            {
                changesCount = myInspectorValuesContainer.GetAffectedFiles(guid, propertyNames) - myInspectorValuesContainer.GetAffectedFilesWithSpecificValue(guid, propertyNames, initValueUnityPresentation);
                displayName  = $"Changed in {changesCount}+ assets";
                isEstimated  = true;
            }
            else
            {
                changesCount = 0;
                var initValueCount = myInspectorValuesContainer.GetValueCount(guid, propertyNames, initValueUnityPresentation);

                if (initValueCount == 0 && myInspectorValuesContainer.GetUniqueValuesCount(guid, propertyNames) == 1) // only modified value
                {
                    isUniqueChange = true;
                    var value = myInspectorValuesContainer.GetUniqueValueDifferTo(guid, propertyNames, null);
                    displayName = value.GetPresentation(solution, field, false);
                }
                else if (initValueCount > 0 && myInspectorValuesContainer.GetUniqueValuesCount(guid, propertyNames) == 2)
                {
                    isUniqueChange = true;
                    // original value & only one modified value
                    var anotherValueWithLocation = myInspectorValuesContainer.GetUniqueValueDifferTo(guid, propertyNames, initValueUnityPresentation);
                    displayName = anotherValueWithLocation.GetPresentation(solution, field, false);
                }

                if (displayName == null || displayName.Equals("..."))
                {
                    changesCount = myInspectorValuesContainer.GetAffectedFiles(guid, propertyNames) -
                                   myInspectorValuesContainer.GetAffectedFilesWithSpecificValue(guid, propertyNames,
                                                                                                initValueUnityPresentation);
                    if (changesCount == 0)
                    {
                        displayName = "Unchanged";
                    }
                    else
                    {
                        var word = NounUtil.ToPluralOrSingularQuick(changesCount, "asset", "assets");
                        displayName = $"Changed in {changesCount} {word}";
                    }
                }
            }

            consumer.AddHighlighting(new UnityInspectorCodeInsightsHighlighting(element.GetNameDocumentRange(),
                                                                                displayName, GetTooltip(changesCount, isEstimated, isUniqueChange), "Property Inspector values", this,
                                                                                declaredElement, iconModel, presentationType));
        }
        protected override void Analyze(IInvocationExpression expression, ElementProblemAnalyzerData data,
                                        IHighlightingConsumer consumer)
        {
            // Don't do anything unless we have a valid method invocation
            if (expression.RPar == null)
            {
                return;
            }

            if (!(expression.InvokedExpression is IReferenceExpression) || expression.TypeArguments.Count != 0)
            {
                return;
            }

            var literalExpressionArgument = expression.Arguments.SingleItem?.Value as ILiteralExpression;

            if (literalExpressionArgument == null || !literalExpressionArgument.Literal.IsAnyStringLiteral())
            {
                return;
            }

            // GameObject.GetComponent, Component.GetComponent, GameObject.AddComponent and ScriptableObject.CreateInstance.
            // Decided by who gets references in a string literal argument by the UnityObjectTypeOrNamespaceReference provider.
            var methodName = GetMethodName(expression.Reference);

            if (methodName != "GetComponent" && methodName != "AddComponent" && methodName != "CreateInstance")
            {
                return;
            }

            // Don't add the quick fix in the case of the following, because we can't fix it cleanly:
            // GetComponent(
            // #if DEBUG
            //    "MyDebugComponent"
            // #else
            //    "MyReleaseComponent"
            // #endif
            // )
            if (expression.ContainsPreprocessorDirectives())
            {
                return;
            }

            var references = literalExpressionArgument.GetReferences <UnityObjectTypeOrNamespaceReference>();

            // Don't add anything unless ALL references resolve properly
            foreach (var reference in references)
            {
                var resolveInfo = reference.Resolve();
                if (!resolveInfo.Info.ResolveErrorType.IsAcceptable)
                {
                    return;
                }
            }

            foreach (var reference in references)
            {
                var resolveInfo = reference.Resolve();
                if (resolveInfo.DeclaredElement is ITypeElement typeElement)
                {
                    consumer.AddHighlighting(new PreferGenericMethodOverloadWarning(expression, methodName,
                                                                                    literalExpressionArgument, typeElement));
                }
            }
        }
        void AnalyzeWhenExpressionIsKnownToBeTrueOrFalse(
            [NotNull] IHighlightingConsumer context,
            [CanBeNull] CSharpCompilerNullableInspector nullabilityInspector,
            [CanBeNull] CSharpControlFlowGraphInspector inspector,
            [CanBeNull][ItemNotNull] HashSet <IAsExpression> alwaysSuccessTryCastExpressions,
            [NotNull] Assertion assertion,
            bool isKnownToBeTrue)
        {
            if (assertion is AssertionStatement assertionStatement)
            {
                // pattern: Assert(true); or Assert(false);
                Debug.Assert(CSharpTokenType.TRUE_KEYWORD != null);
                Debug.Assert(CSharpTokenType.FALSE_KEYWORD != null);
                if (IsLiteral(assertionStatement.Expression, isKnownToBeTrue ? CSharpTokenType.TRUE_KEYWORD : CSharpTokenType.FALSE_KEYWORD))
                {
                    context.AddHighlighting(
                        new RedundantAssertionStatementSuggestion(
                            $"Assertion is redundant because the expression is {(isKnownToBeTrue ? "true" : "false")} here.",
                            assertionStatement));
                }

                if (assertionStatement.Expression is IEqualityExpression equalityExpression)
                {
                    // pattern: Assert(x != null); when x is known to be null or not null
                    Debug.Assert(CSharpTokenType.NULL_KEYWORD != null);
                    var expression = TryGetOtherOperand(equalityExpression, EqualityExpressionType.NE, CSharpTokenType.NULL_KEYWORD);
                    if (expression != null)
                    {
                        switch (GetExpressionNullReferenceState(
                                    nullabilityInspector,
                                    inspector,
                                    alwaysSuccessTryCastExpressions,
                                    expression))
                        {
                        case CSharpControlFlowNullReferenceState.NOT_NULL:
                            if (isKnownToBeTrue)
                            {
                                context.AddHighlighting(
                                    new RedundantAssertionStatementSuggestion(
                                        "Assertion is redundant because the expression is true here.",
                                        assertionStatement));
                            }
                            break;

                        case CSharpControlFlowNullReferenceState.NULL:
                            if (!isKnownToBeTrue)
                            {
                                context.AddHighlighting(
                                    new RedundantAssertionStatementSuggestion(
                                        "Assertion is redundant because the expression is false here.",
                                        assertionStatement));
                            }
                            break;
                        }
                    }

                    // pattern: Assert(x == null); when x is known to be null or not null
                    expression = TryGetOtherOperand(equalityExpression, EqualityExpressionType.EQEQ, CSharpTokenType.NULL_KEYWORD);
                    if (expression != null)
                    {
                        switch (GetExpressionNullReferenceState(nullabilityInspector, inspector, alwaysSuccessTryCastExpressions, expression))
                        {
                        case CSharpControlFlowNullReferenceState.NOT_NULL:
                            if (!isKnownToBeTrue)
                            {
                                context.AddHighlighting(
                                    new RedundantAssertionStatementSuggestion(
                                        "Assertion is redundant because the expression is false here.",
                                        assertionStatement));
                            }
                            break;

                        case CSharpControlFlowNullReferenceState.NULL:
                            if (isKnownToBeTrue)
                            {
                                context.AddHighlighting(
                                    new RedundantAssertionStatementSuggestion(
                                        "Assertion is redundant because the expression is true here.",
                                        assertionStatement));
                            }
                            break;
                        }
                    }
                }
            }
        }
Ejemplo n.º 43
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);
        }
        protected override void Run(IArrayInitializer element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
        {
            if (element.InitializerElements.Count > 0)
            {
                IType arrayElementType;
                switch (element.Parent)
                {
                case ITypeOwnerDeclaration declaration:
                    arrayElementType = declaration.Type.GetScalarType();

                    if (arrayElementType == null)
                    {
                        return;
                    }
                    break;

                case IArrayCreationExpression creationExpression:
                    arrayElementType = creationExpression.GetElementType();
                    break;

                default: return;
                }

                if (element.InitializerElements.All(
                        initializerElement => initializerElement?.FirstChild != null && initializerElement.FirstChild.IsDefaultValueOf(arrayElementType)))
                {
                    // { d, default, default(T) } // where d is the default value for the T

                    var builder = new StringBuilder();
                    builder.Append("new ");

                    Debug.Assert(CSharpLanguage.Instance != null);

                    builder.Append(arrayElementType.GetPresentableName(CSharpLanguage.Instance));

                    if (builder[builder.Length - 1] != '?')
                    {
                        var isNullableReferenceType = element.IsNullableAnnotationsContextEnabled() &&
                                                      arrayElementType.Classify == TypeClassification.REFERENCE_TYPE &&
                                                      arrayElementType.NullableAnnotation == NullableAnnotation.NotAnnotated;

                        if (isNullableReferenceType)
                        {
                            builder.Append('?');
                        }
                    }
                    else
                    {
                        // workaround for R# 2020.2

                        if (element.IsNullableAnnotationsContextEnabled())
                        {
                            switch (arrayElementType.Classify)
                            {
                            case TypeClassification.UNKNOWN:
                            case TypeClassification.VALUE_TYPE when !arrayElementType.IsNullable():
                                builder.Remove(builder.Length - 1, 1);
                                break;
                            }
                        }
                    }

                    builder.Append('[');
                    builder.Append(element.InitializerElements.Count);
                    builder.Append(']');

                    var suggestedCode = builder.ToString();

                    consumer.AddHighlighting(
                        new ArrayWithDefaultValuesInitializationSuggestion(CreateHighlightingMessage(suggestedCode), suggestedCode, element));
                }
            }
        }