Esempio n. 1
0
        public bool IsAvailable(IUserDataHolder cache)
        {
            var methodName = this._myProvider.GetSelectedElement <ICSharpIdentifier>();

            var methodDeclaration = MethodDeclarationNavigator.GetByNameIdentifier(methodName);

            ICSharpParametersOwnerDeclaration paramsOwnerDeclaration = methodDeclaration;
            IFormalParameterList paramsList = methodDeclaration?.Params;

            //If unable to resolve by method declaration, try to resolve for ctor.
            if (paramsOwnerDeclaration == null)
            {
                var constructorDeclaration = ConstructorDeclarationNavigator.GetByTypeName(methodName);
                paramsOwnerDeclaration = constructorDeclaration;
                paramsList             = constructorDeclaration?.Params;
            }

            if (paramsOwnerDeclaration == null)
            {
                return(false);
            }
            if (paramsOwnerDeclaration.ParameterDeclarations.IsEmpty)
            {
                return(false);
            }

            this.ParametersOwnerDeclaration = paramsOwnerDeclaration;
            this.FormalParameterList        = paramsList;

            return(true);
        }
        protected override void Analyze(IAttribute element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
        {
            if (!(element.TypeReference?.Resolve().DeclaredElement is ITypeElement attributeTypeElement))
            {
                return;
            }

            // Otherwise we'll treat it as targeting a method
            if (element.Target == AttributeTarget.Return)
            {
                return;
            }

            if (ourAttributeLookups.TryGetValue(attributeTypeElement.GetClrName(), out var func))
            {
                var methodDeclaration = MethodDeclarationNavigator.GetByAttribute(element);
                if (methodDeclaration == null)
                {
                    return;
                }

                var predefinedType  = myPredefinedTypeCache.GetOrCreatePredefinedType(element.GetPsiModule());
                var methodSignature = func(predefinedType);

                var match = methodSignature.Match(methodDeclaration);
                AddMethodSignatureInspections(consumer, methodDeclaration, methodSignature, match);
            }
        }
Esempio n. 3
0
        public bool IsAvailable(IUserDataHolder cache)
        {
            var identifier        = myDataProvider.GetSelectedElement <ITreeNode>() as ICSharpIdentifier;
            var methodDeclaration = MethodDeclarationNavigator.GetByNameIdentifier(identifier);

            return(AddDiscardAttributeUtil.IsAvailable(methodDeclaration));
        }
        public IEnumerable <IntentionAction> CreateBulbItems()
        {
            var identifier        = myDataProvider.GetSelectedElement <ITreeNode>() as ICSharpIdentifier;
            var methodDeclaration = MethodDeclarationNavigator.GetByNameIdentifier(identifier);

            if (methodDeclaration == null)
            {
                return(EmptyList <IntentionAction> .Instance);
            }

            if (!UnityCallGraphUtil.IsSweaCompleted(mySwa))
            {
                return(EmptyList <IntentionAction> .Instance);
            }

            var processKind = UnityCallGraphUtil.GetProcessKindForGraph(mySwa);

            if (myExpensiveContextProvider.HasContext(methodDeclaration, processKind))
            {
                return(EmptyList <IntentionAction> .Instance);
            }

            var isPerformanceContext = myPerformanceContextProvider.HasContext(methodDeclaration, processKind);

            if (!isPerformanceContext)
            {
                return(EmptyList <IntentionAction> .Instance);
            }

            var bulbAction = new AddExpensiveCommentBulbAction(methodDeclaration);

            return(bulbAction.ToContextActionIntentions());
        }
        public static IMethodDeclaration GetMethodDeclarationByIdentifierOnBothSides([NotNull] ICSharpContextActionDataProvider dataProvider)
        {
            var result = MethodDeclarationByTreeNode(dataProvider.TokenAfterCaret);

            return(result ?? MethodDeclarationByTreeNode(dataProvider.TokenBeforeCaret));

            IMethodDeclaration MethodDeclarationByTreeNode(ITreeNode node)
            {
                var identifierAfter   = node as ICSharpIdentifier;
                var methodDeclaration = MethodDeclarationNavigator.GetByNameIdentifier(identifierAfter);

                return(methodDeclaration);
            }
        }
        public bool IsAvailable(IUserDataHolder cache)
        {
            var identifier        = myDataProvider.GetSelectedElement <ITreeNode>() as ICSharpIdentifier;
            var methodDeclaration = MethodDeclarationNavigator.GetByNameIdentifier(identifier);

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

            var declaredElement = methodDeclaration.DeclaredElement;

            return(declaredElement != null && methodDeclaration.IsValid() &&
                   !PerformanceCriticalCodeStageUtil.IsPerformanceCriticalRootMethod(methodDeclaration));
        }
        public override bool IsAvailable(IUserDataHolder cache)
        {
            var methodName        = this.Provider.GetSelectedElement <ICSharpIdentifier>();
            var methodDeclaration = MethodDeclarationNavigator.GetByNameIdentifier(methodName);

            var declaredMethod = methodDeclaration?.DeclaredElement;

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

            var isAlreadyDeclared = this.FindPureAttribute(methodDeclaration) != null;

            return(this.ResolveIsAvailable(isAlreadyDeclared, declaredMethod));
        }
        protected override void Analyze(IAttribute element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
        {
            var attributeTypeElement = element.TypeReference?.Resolve().DeclaredElement as ITypeElement;

            if (attributeTypeElement == null)
            {
                return;
            }

            if (Equals(attributeTypeElement.GetClrName(), KnownTypes.InitializeOnLoadAttribute))
            {
                var classLikeDeclaration = ClassLikeDeclarationNavigator.GetByAttribute(element);
                if (classLikeDeclaration != null && classLikeDeclaration.ConstructorDeclarations.All(c => !c.IsStatic))
                {
                    // Unity doesn't report a warning if there isn't a static constructor, so just highlight
                    // the attribute as dead code.
                    consumer.AddHighlighting(new RedundantInitializeOnLoadAttributeWarning(element));
                }
            }
            else if (Equals(attributeTypeElement.GetClrName(), KnownTypes.InitializeOnLoadMethodAttribute) ||
                     Equals(attributeTypeElement.GetClrName(), KnownTypes.RuntimeInitializeOnLoadMethodAttribute))
            {
                var methodDeclaration = MethodDeclarationNavigator.GetByAttribute(element);
                if (methodDeclaration == null)
                {
                    return;
                }

                var predefinedType  = myPredefinedTypeCache.GetOrCreatePredefinedType(element.GetPsiModule());
                var methodSignature = new MethodSignature(predefinedType.Void, true);

                if (!methodDeclaration.IsStatic)
                {
                    consumer.AddHighlighting(new InvalidStaticModifierWarning(methodDeclaration, methodSignature));
                }
                if (!methodDeclaration.Type.IsVoid())
                {
                    consumer.AddHighlighting(new InvalidReturnTypeWarning(methodDeclaration, methodSignature));
                }
                if (methodDeclaration.ParameterDeclarationsEnumerable.Any())
                {
                    consumer.AddHighlighting(new InvalidSignatureWarning(methodDeclaration, methodSignature));
                }
            }
        }
Esempio n. 9
0
        protected override void Analyze(IAttribute element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
        {
            if (!(element.TypeReference?.Resolve().DeclaredElement is ITypeElement attributeTypeElement))
            {
                return;
            }

            if (element.Target == AttributeTarget.Return)
            {
                return;
            }

            var methodDeclaration = MethodDeclarationNavigator.GetByAttribute(element);

            if (methodDeclaration == null)
            {
                return;
            }

            var predefinedType           = myPredefinedTypeCache.GetOrCreatePredefinedType(element.GetPsiModule());
            var expectedMethodSignatures = GetExpectedMethodSignatures(attributeTypeElement, predefinedType);

            if (expectedMethodSignatures == null)
            {
                return;
            }

            if (expectedMethodSignatures.Length == 1)
            {
                var match = expectedMethodSignatures[0].Match(methodDeclaration);
                AddMethodSignatureInspections(consumer, methodDeclaration, expectedMethodSignatures[0], match);
            }
            else
            {
                foreach (var methodSignature in expectedMethodSignatures)
                {
                    if (methodSignature.Match(methodDeclaration) == MethodSignatureMatch.ExactMatch)
                    {
                        return;
                    }
                }

                AddMethodSignatureInspections(consumer, methodDeclaration, expectedMethodSignatures);
            }
        }
Esempio n. 10
0
        protected override void Analyze(IAttribute element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
        {
            if (!(element.TypeReference?.Resolve().DeclaredElement is ITypeElement attributeTypeElement))
            {
                return;
            }

            // Otherwise we'll treat it as targeting a method
            if (element.Target == AttributeTarget.Return)
            {
                return;
            }

            if (ourAttributeLookups.TryGetValue(attributeTypeElement.GetClrName(), out var func))
            {
                var methodDeclaration = MethodDeclarationNavigator.GetByAttribute(element);
                if (methodDeclaration == null)
                {
                    return;
                }

                var predefinedType  = myPredefinedTypeCache.GetOrCreatePredefinedType(element.GetPsiModule());
                var methodSignature = func(predefinedType);

                if (!methodSignature.HasMatchingStaticModifier(methodDeclaration))
                {
                    consumer.AddHighlighting(new InvalidStaticModifierWarning(methodDeclaration, methodSignature));
                }
                if (!methodSignature.HasMatchingReturnType(methodDeclaration))
                {
                    consumer.AddHighlighting(new InvalidReturnTypeWarning(methodDeclaration, methodSignature));
                }
                if (!methodSignature.HasMatchingTypeParameters(methodDeclaration))
                {
                    consumer.AddHighlighting(new InvalidTypeParametersWarning(methodDeclaration, methodSignature));
                }
                if (!methodSignature.HasMatchingParameters(methodDeclaration))
                {
                    consumer.AddHighlighting(new InvalidParametersWarning(methodDeclaration, methodSignature));
                }
            }
        }
        protected override void Analyze(IAttribute element, ElementProblemAnalyzerData data,
                                        IHighlightingConsumer consumer)
        {
            if (!(element.TypeReference?.Resolve().DeclaredElement is ITypeElement attributeTypeElement))
            {
                return;
            }

            // Otherwise we'll treat it as targeting a method
            if (element.Target == AttributeTarget.Return)
            {
                return;
            }

            if (attributeTypeElement.GetClrName().Equals(KnownTypes.DrawGizmo))
            {
                var methodDeclaration = MethodDeclarationNavigator.GetByAttribute(element);
                CheckMethodDeclaration(methodDeclaration, element, consumer);
            }
        }
Esempio n. 12
0
        public IReference[] GetReferences(ITreeNode element, IReference[] oldReferences)
        {
            var literal = element as ILiteralExpression;

            if (literal != null && literal.ConstantValue.Value is string)
            {
                var agument   = literal.Parent as IVBArgument;
                var attribute = AttributeNavigator.GetByArgument(agument);
                if (attribute != null)
                {
                    var @class = attribute.AttributeType.Reference.Resolve().DeclaredElement as IClass;
                    if (@class != null && Equals(@class.GetClrName(), DataAttributeName))
                    {
                        var typeElement = (from a in attribute.Arguments
                                           where a is INamedArgument && a.ArgumentName == TypeMemberName
                                           select GetTypeof(a.Expression as IGetTypeExpression)).FirstOrDefault();

                        var member = MethodDeclarationNavigator.GetByAttribute(attribute) as ITypeMemberDeclaration;
                        if (member != null && member.DeclaredElement != null && typeElement == null)
                        {
                            typeElement = member.DeclaredElement.GetContainingType();
                        }

                        if (typeElement == null)
                        {
                            return(EmptyArray <IReference> .Instance);
                        }

                        var reference = CreateReference(typeElement, literal);

                        return(oldReferences != null && oldReferences.Length == 1 && Equals(oldReferences[0], reference)
                                   ? oldReferences
                                   : new[] { reference });
                    }
                }
            }

            return(EmptyArray <IReference> .Instance);
        }
Esempio n. 13
0
        public IReference[] GetReferences(ITreeNode element, IReference[] oldReferences)
        {
            var literal = element as ILiteralExpression;

            if (literal != null && literal.ConstantValue.Value is string)
            {
                var attribute = AttributeNavigator.GetByConstructorArgumentExpression(literal as ICSharpExpression);
                if (attribute != null)
                {
                    var @class = attribute.Name.Reference.Resolve().DeclaredElement as IClass;
                    if (@class != null && Equals(@class.GetClrName(), XunitTestProvider.PropertyDataAttribute))
                    {
                        var typeElement = (from a in attribute.PropertyAssignments
                                           where a.PropertyNameIdentifier.Name == "PropertyType"
                                           select GetTypeof(a.Source as ITypeofExpression)).FirstOrDefault();

                        var member = MethodDeclarationNavigator.GetByAttribute(attribute);
                        if (member != null && member.DeclaredElement != null && typeElement == null)
                        {
                            typeElement = member.DeclaredElement.GetContainingType();
                        }

                        if (typeElement == null)
                        {
                            return(EmptyArray <IReference> .Instance);
                        }

                        var reference = new PropertyDataReference(typeElement, literal);

                        return(oldReferences != null && oldReferences.Length == 1 && Equals(oldReferences[0], reference)
                                   ? oldReferences
                                   : new IReference[] { reference });
                    }
                }
            }

            return(EmptyArray <IReference> .Instance);
        }
Esempio n. 14
0
        private static IDeclaredElement FindDeclaredElement([NotNull] IPsiView psiView)
        {
            var referenceExpression = psiView.GetSelectedTreeNode <IReferenceExpression>();

            if (referenceExpression != null)
            {
                return(referenceExpression.Reference.Resolve().DeclaredElement);
            }

            var identifier = psiView.GetSelectedTreeNode <ICSharpIdentifier>();

            if (identifier != null)
            {
                var referenceName = ReferenceNameNavigator.GetByNameIdentifier(identifier);
                if (referenceName != null)
                {
                    return(referenceName.Reference.Resolve().DeclaredElement);
                }

                var declarationUnderCaret =
                    FieldDeclarationNavigator.GetByNameIdentifier(identifier) ??
                    PropertyDeclarationNavigator.GetByNameIdentifier(identifier) ??
                    MethodDeclarationNavigator.GetByNameIdentifier(identifier) ??
                    ConstructorDeclarationNavigator.GetByTypeName(identifier) ??
                    CSharpTypeDeclarationNavigator.GetByNameIdentifier(identifier) ??
                    EventDeclarationNavigator.GetByNameIdentifier(identifier) ??
                    ConstantDeclarationNavigator.GetByNameIdentifier(identifier) ??
                    VariableDeclarationNavigator.GetByNameIdentifier(identifier);

                return(declarationUnderCaret?.DeclaredElement);
            }

            var predefinedTypeUsage = psiView.GetSelectedTreeNode <IPredefinedTypeUsage>();

            return(predefinedTypeUsage?.ScalarPredefinedTypeName.Reference.Resolve().DeclaredElement);
        }
Esempio n. 15
0
        private static MemberGenerationContext TryBuildMemberGenerationContext(
            [NotNull] CSharpCodeCompletionContext context)
        {
            var identifier = context.TerminatedContext.TreeNode as ICSharpIdentifier;

            if (identifier == null)
            {
                return(null);
            }

            // override int __
            var fieldDeclaration = FieldDeclarationNavigator.GetByNameIdentifier(identifier);

            if (fieldDeclaration != null)
            {
                var fieldTypeUsage =
                    fieldDeclaration.GetPreviousMeaningfulSiblingThroughWhitespaceAndComments() as ITypeUsage;
                if (fieldTypeUsage == null)
                {
                    return(null);
                }

                if (!CheckNodesBeforeTypeUsage(fieldTypeUsage, out var modifiersList))
                {
                    return(null);
                }

                var memberReplaceRanges = ComputeMemberReplaceRanges(TreeOffset.InvalidOffset);
                if (memberReplaceRanges == null)
                {
                    return(null);
                }

                var typeDeclaration = GetPhysicalNonStaticTypeDeclaration();
                if (typeDeclaration == null)
                {
                    return(null);
                }

                if (modifiersList.ContainsPreprocessorDirectiveChildren())
                {
                    return(null);
                }

                return(new MemberGenerationContext(typeDeclaration, modifiersList, fieldTypeUsage, memberReplaceRanges));
            }

            // override __;
            var referenceName     = ReferenceNameNavigator.GetByNameIdentifier(identifier);
            var userTypeUsage     = UserTypeUsageNavigator.GetByScalarTypeName(referenceName);
            var methodDeclaration = MethodDeclarationNavigator.GetByTypeUsage(userTypeUsage);

            if (methodDeclaration != null)
            {
                if (!CheckNodesBeforeTypeUsage(userTypeUsage, out var modifiersList))
                {
                    return(null);
                }

                var methodStartRange =
                    context.TerminatedContext.ToOriginalTreeRange(
                        new TreeTextRange(methodDeclaration.GetTreeStartOffset()));

                var memberReplaceRanges = ComputeMemberReplaceRanges(methodStartRange.StartOffset);
                if (memberReplaceRanges == null)
                {
                    return(null);
                }

                var typeDeclaration = GetPhysicalNonStaticTypeDeclaration();
                if (typeDeclaration == null)
                {
                    return(null);
                }

                if (modifiersList.ContainsPreprocessorDirectiveChildren())
                {
                    return(null);
                }

                return(new MemberGenerationContext(typeDeclaration, modifiersList, expectedReturnTypeUsage: null,
                                                   memberReplaceRanges));
            }

            return(null);

            bool CheckNodesBeforeTypeUsage(ITypeUsage typeUsage, out IModifiersList modifiersList)
            {
                var previousSibling = typeUsage.GetPreviousMeaningfulSiblingThroughWhitespaceAndComments();

                modifiersList = previousSibling as IModifiersList;

                if (previousSibling is IModifiersList)
                {
                    previousSibling = previousSibling.GetPreviousMeaningfulSiblingThroughWhitespaceAndComments();
                }

                if (previousSibling is IAttributeSectionList)
                {
                    previousSibling = previousSibling.GetPreviousMeaningfulSiblingThroughWhitespaceAndComments();
                }

                if (previousSibling is IDocCommentBlock)
                {
                    previousSibling = previousSibling.GetPreviousMeaningfulSiblingThroughWhitespaceAndComments();
                }

                return(previousSibling == null);
            }

            bool IsDeclarationToReplace(ITreeNode declaration)
            {
                switch (declaration)
                {
                case IMultipleFieldDeclaration _:
                case IMethodDeclaration _:
                case IPropertyDeclaration _:
                case IIndexerDeclaration _:
                    return(true);

                default:
                    return(false);
                }
            }

            TextLookupRanges ComputeMemberReplaceRanges(TreeOffset startOffset)
            {
                foreach (var treeNode in context.NodeInFile.ContainingNodes(returnThis: true))
                {
                    if (IsDeclarationToReplace(treeNode))
                    {
                        return(RangesForDeclaration(treeNode));
                    }

                    if (treeNode.IsFiltered())
                    {
                        var prevMeaningfulSibling = treeNode.GetPreviousMeaningfulSiblingThroughWhitespaceAndComments();
                        if (prevMeaningfulSibling != null &&
                            IsDeclarationToReplace(prevMeaningfulSibling) &&
                            (!startOffset.IsValid() || prevMeaningfulSibling.GetTreeStartOffset() >= startOffset))
                        {
                            return(RangesForDeclaration(prevMeaningfulSibling));
                        }

                        var nextMeaningfulSibling = treeNode.GetNextMeaningfulSibling();
                        if (nextMeaningfulSibling != null && IsDeclarationToReplace(nextMeaningfulSibling))
                        {
                            return(RangesForDeclaration(nextMeaningfulSibling));
                        }
                    }

                    if (treeNode is IFieldDeclaration field)
                    {
                        var range = context.CompletionRanges.ReplaceRange;
                        if (field.GetPreviousMeaningfulSibling() is ITypeUsage typeUsage)
                        {
                            range = range.SetStartTo(typeUsage.GetDocumentStartOffset());
                        }

                        return(new TextLookupRanges(range, range));
                    }

                    if (treeNode is ICSharpTypeMemberDeclaration)
                    {
                        return(context.CompletionRanges);
                    }
                }

                return(null);

                TextLookupRanges RangesForDeclaration(ITreeNode treeNode)
                {
                    var elementRange = ComputeReplaceRangeForDeclaration(treeNode);

                    if (!elementRange.IsValid())
                    {
                        return(null);
                    }

                    return(CodeCompletionContextProviderBase.GetTextLookupRanges(context.BasicContext, elementRange));
                }

                DocumentRange ComputeReplaceRangeForDeclaration(ITreeNode declaration)
                {
                    var startOffsetRange = new DocumentRange(GetDeclarationStartDocumentOffset(declaration));
                    var selectedRange    = context.BasicContext.SelectedRange;

                    var anchorDeclaration = GetAnchorDeclaration(declaration);

                    var elementRange = startOffsetRange.Join(selectedRange)
                                       .JoinRight(new DocumentRange(anchorDeclaration.GetDocumentEndOffset()));

                    if (!elementRange.IsValid())
                    {
                        elementRange = startOffsetRange.Join(selectedRange);
                    }

                    if (!elementRange.IsValid())
                    {
                        return(DocumentRange.InvalidRange);
                    }

                    var anchorDeclarationNameRange = GetDeclarationNameRange(anchorDeclaration);

                    var declarationNameLine = anchorDeclarationNameRange.StartOffset.ToDocumentCoords().Line;
                    var selectionLine       = selectedRange.EndOffset.ToDocumentCoords().Line;

                    if (declarationNameLine != selectionLine)
                    {
                        return(elementRange.SetEndTo(selectedRange.EndOffset));
                    }

                    return(elementRange);
                }

                DocumentOffset GetDeclarationStartDocumentOffset(ITreeNode declaration)
                {
                    // note: do not include attributes into member range
                    var firstChild = declaration.GetNextMeaningfulChild(null);

                    if (firstChild is IDocCommentBlock)
                    {
                        firstChild = firstChild.GetNextMeaningfulSibling();
                    }

                    if (firstChild is IAttributeSectionList)
                    {
                        firstChild = firstChild.GetNextMeaningfulSibling();
                    }

                    return((firstChild ?? declaration).GetDocumentStartOffset());
                }

                ITreeNode GetAnchorDeclaration(ITreeNode declaration)
                {
                    if (declaration is IMethodDeclaration unfinishedMethod &&
                        unfinishedMethod.NameIdentifier == null &&
                        unfinishedMethod.LPar == null &&
                        unfinishedMethod.ModifiersList == null &&
                        unfinishedMethod.TypeUsage != null)
                    {
                        var nextDeclaration = unfinishedMethod.GetNextMeaningfulSibling();

                        if (IsDeclarationToReplace(nextDeclaration))
                        {
                            return(nextDeclaration);
                        }
                    }

                    return(declaration);
                }

                DocumentRange GetDeclarationNameRange(ITreeNode declaration)
                {
                    switch (declaration)
                    {
                    case IMultipleFieldDeclaration fieldDecl:
                        return(fieldDecl.DeclaratorsEnumerable.FirstOrDefault().GetDocumentRange());

                    case IDeclaration decl:
                        return(decl.GetNameDocumentRange());

                    default:
                        return(declaration.GetDocumentRange());
                    }
                }
            }

            ITypeDeclaration GetPhysicalNonStaticTypeDeclaration()
            {
                foreach (var typeDeclaration in context.NodeInFile.ContainingNodes <ITypeDeclaration>())
                {
                    if (typeDeclaration.GetNameRange().EndOffset > context.BasicContext.CaretTreeOffset)
                    {
                        continue;
                    }

                    switch (typeDeclaration)
                    {
                    case IClassDeclaration classDeclaration when !classDeclaration.IsStatic:
                        return(classDeclaration);

                    case IStructDeclaration structDeclaration:
                        return(structDeclaration);

                    default:
                        return(null);
                    }
                }

                return(null);
            }
        }