Esempio n. 1
0
        public override IDeclaredElement Analyze(IDeclaration node, IHighlightingConsumer consumer, DaemonProcessKind kind)
        {
            if (!(node is IClassLikeDeclaration element))
            {
                return(null);
            }

            var typeElement = element.DeclaredElement;

            if (typeElement != null)
            {
                if (myUnityApi.IsDescendantOfMonoBehaviour(typeElement))
                {
                    AddMonoBehaviourHiglighting(consumer, element, "Script", "Unity script", kind);
                }
                else if (myUnityApi.IsDescendantOf(KnownTypes.Editor, typeElement) ||
                         myUnityApi.IsDescendantOf(KnownTypes.EditorWindow, typeElement))
                {
                    AddEditorHiglighting(consumer, element, "Editor", "Custom Unity Editor", kind);
                }
                else if (myUnityApi.IsUnityType(typeElement))
                {
                    AddUnityTypeHighlighting(consumer, element, "Unity type", "Custom Unity type", kind);
                }
                else if (myUnityApi.IsUnityECSType(typeElement))
                {
                    AddUnityECSHighlighting(consumer, element, "Unity ECS", "Unity entity component system object",
                                            kind);
                }

                return(typeElement);
            }

            return(null);
        }
        private bool IsEventHandler(UnityApi unityApi, [CanBeNull] IMethod method)
        {
            if (method == null)
            {
                return(false);
            }

            var type = method.GetContainingType();

            if (!unityApi.IsUnityType(type))
            {
                return(false);
            }

            var solution = method.GetSolution();
            var assetSerializationMode = solution.GetComponent <AssetSerializationMode>();
            var yamlParsingEnabled     = solution.GetComponent <AssetIndexingSupport>().IsEnabled;

            // TODO: These two are usually used together. Consider combining in some way
            if (!yamlParsingEnabled.Value || !assetSerializationMode.IsForceText || !solution.GetComponent <DeferredCacheController>().CompletedOnce.Value)
            {
                return(unityApi.IsPotentialEventHandler(method, false)); // if yaml parsing is disabled, we will consider private methods as unused
            }
            var eventsCount = solution
                              .GetComponent <UnityEventsElementContainer>()
                              .GetAssetUsagesCount(method, out bool estimatedResult);

            return(eventsCount > 0 || estimatedResult);
        }
Esempio n. 3
0
        private bool GetCoroutineMustUseReturnValueAttribute(IClrDeclaredElement element,
                                                             out ICollection <IAttributeInstance> collection)
        {
            collection = EmptyList <IAttributeInstance> .Instance;

            var method = element as IMethod;
            var type   = method?.GetContainingType();

            if (type == null || !myUnityApi.IsUnityType(type))
            {
                return(false);
            }

            var returnType     = method.ReturnType;
            var predefinedType = myPredefinedTypeCache.GetOrCreatePredefinedType(element.Module);

            if (!Equals(returnType, predefinedType.IEnumerator))
            {
                return(false);
            }

            // The ctorArguments lambda result is not cached, so let's allocate everything up front
            var args = new[]
            {
                new AttributeValue(
                    new ConstantValue("Coroutine will not continue if return value is ignored",
                                      predefinedType.String))
            };

            collection = new[]
            {
                new SpecialAttributeInstance(ourMustUseReturnValueAttributeFullName, GetModule(element), () => args)
            };
            return(true);
        }
        private bool IsEventHandler(UnityApi unityApi, [CanBeNull] IMethod method)
        {
            if (method == null)
            {
                return(false);
            }

            var type = method.GetContainingType();

            if (!unityApi.IsUnityType(type))
            {
                return(false);
            }

            var solution = method.GetSolution();
            var assetSerializationMode = solution.GetComponent <AssetSerializationMode>();
            var yamlParsingEnabled     = solution.GetComponent <UnityYamlSupport>().IsUnityYamlParsingEnabled;

            // TODO: These two are usually used together. Consider combining in some way
            if (!yamlParsingEnabled.Value || !assetSerializationMode.IsForceText)
            {
                return(unityApi.IsPotentialEventHandler(method, false)); // if yaml parsing is disabled, we will consider private methods as unused
            }
            return(method.GetSolution().GetComponent <UnitySceneDataLocalCache>().IsEventHandler(method));
        }
        private bool GetCoroutineMustUseReturnValueAttribute(IClrDeclaredElement element,
                                                             out ICollection <IAttributeInstance> collection)
        {
            collection = EmptyList <IAttributeInstance> .Instance;

            var method = element as IMethod;
            var type   = method?.GetContainingType();

            if (type == null || !myUnityApi.IsUnityType(type))
            {
                return(false);
            }

            var returnType     = method.ReturnType;
            var predefinedType = myPredefinedTypeCache.GetOrCreatePredefinedType(element.Module);

            if (!Equals(returnType, predefinedType.IEnumerator))
            {
                return(false);
            }

            collection = new[]
            {
                new SpecialAttributeInstance(
                    ourMustUseReturnValueAttributeFullName, myAnnotationsPsiModule, () => new[]
                {
                    new AttributeValue(
                        new ConstantValue("Coroutine will not continue if return value is ignored",
                                          predefinedType.String)),
                })
            };
            return(true);
        }
Esempio n. 6
0
        public IDeclaredElement Analyze(IDeclaration node, IHighlightingConsumer consumer, DaemonProcessKind kind)
        {
            if (!(node is IClassLikeDeclaration element))
            {
                return(null);
            }

            var typeElement = element.DeclaredElement;

            if (typeElement != null)
            {
                if (myUnityApi.IsUnityType(typeElement))
                {
                    myContributor.AddUnityImplicitClassUsage(consumer, element,
                                                             "Unity scripting component", "Scripting component", kind);
                }
                else if (myUnityApi.IsUnityECSType(typeElement))
                {
                    myContributor.AddUnityImplicitClassUsage(consumer, element,
                                                             "Unity entity component system object", "Unity ECS", kind);
                }

                return(typeElement);
            }

            return(null);
        }
Esempio n. 7
0
        public override bool AddDeclarationHighlighting(IDeclaration node, IHighlightingConsumer consumer, DaemonProcessKind kind)
        {
            if (!(node is IClassLikeDeclaration element))
            {
                return(false);
            }

            var typeElement = element.DeclaredElement;

            if (typeElement != null)
            {
                if (typeElement.DerivesFromMonoBehaviour())
                {
                    AddMonoBehaviourHiglighting(consumer, element, "Script", "Unity script", kind);
                }
                else if (typeElement.DerivesFrom(KnownTypes.Editor) || typeElement.DerivesFrom(KnownTypes.EditorWindow))
                {
                    AddEditorHiglighting(consumer, element, "Editor", "Custom Unity Editor", kind);
                }
                else if (typeElement.DerivesFromScriptableObject())
                {
                    AddMonoBehaviourHiglighting(consumer, element, "Scriptable object", "Scriptable Object", kind);
                }
                else if (myUnityApi.IsUnityType(typeElement))
                {
                    AddUnityTypeHighlighting(consumer, element, "Unity type", "Custom Unity type", kind);
                }
                else if (myUnityApi.IsUnityECSType(typeElement))
                {
                    AddUnityECSHighlighting(consumer, element, "Unity ECS", "Unity entity component system object",
                                            kind);
                }

                return(true);
            }

            return(false);
        }
Esempio n. 8
0
        // Best effort attempt at preventing false positives for type members that are actually being used inside a
        // scene. We don't have enough information to do this by name, so we'll mark all potential event handlers as
        // implicitly used by Unity
        // See https://github.com/Unity-Technologies/UnityCsReference/blob/02f8e8ca594f156dd6b2088ad89451143ca1b87e/Editor/Mono/Inspector/UnityEventDrawer.cs#L397
        private static bool IsPotentialEventHandler(UnityApi unityApi, [CanBeNull] IMethod method)
        {
            if (method == null)
            {
                return(false);
            }

            if (!method.ReturnType.IsVoid())
            {
                return(false);
            }

            // Type.GetMethods() returns public instance methods only
            if (method.GetAccessRights() != AccessRights.PUBLIC || method.IsStatic)
            {
                return(false);
            }

            return(unityApi.IsUnityType(method.GetContainingType()) && !method.HasAttributeInstance(PredefinedType.OBSOLETE_ATTRIBUTE_CLASS, true));
        }
        protected override void Run(IClassLikeDeclaration element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer)
        {
            if (data.ProcessKind != DaemonProcessKind.VISIBLE_DOCUMENT)
            {
                return;
            }

            if (element.GetProject().IsUnityProject())
            {
                var @class = element.DeclaredElement;
                if (@class != null)
                {
                    if (myUnityApi.IsUnityType(@class))
                    {
                        var documentRange = element.GetNameDocumentRange();
                        var highlighting  = new UnityMarkOnGutter(element, documentRange, "Unity Scripting Type");

                        consumer.AddHighlighting(highlighting, documentRange);
                    }
                }
            }
        }
Esempio n. 10
0
        private bool CheckPosition(CSharpCodeCompletionContext context, UnityApi unityApi,
                                   out IClassDeclaration classDeclaration,
                                   out AccessRights accessRights, out bool hasReturnType)
        {
            classDeclaration = GetClassDeclaration(context.NodeInFile);
            accessRights     = AccessRights.NONE;
            hasReturnType    = false;

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

            // Make sure we're completing an identifier
            if (!(context.UnterminatedContext.TreeNode is ICSharpIdentifier identifier))
            {
                return(false);
            }

            if (!unityApi.IsUnityType(classDeclaration.DeclaredElement))
            {
                return(false);
            }

            // Make sure we're in the correct place for showing Unity event functions.
            if (!ShouldComplete(context.NodeInFile, identifier))
            {
                return(false);
            }

            // We know we're in a place where we can complete, so now configure what we
            // complete and what we display
            hasReturnType = HasExistingReturnType(identifier, out var typeUsage);
            accessRights  = GetAccessRights(typeUsage);

            return(true);
        }
        public ICollection <IAttributeInstance> GetSpecialAttributeInstances(IClrDeclaredElement element)
        {
            var method = element as IMethod;
            var type   = method?.GetContainingType();

            if (type != null && myUnityApi.IsUnityType(type))
            {
                var returnType     = method.ReturnType;
                var predefinedType = myPredefinedTypeCache.GetOrCreatePredefinedType(element.Module);
                if (Equals(returnType, predefinedType.IEnumerator))
                {
                    var @string = predefinedType.String;
                    return(new[]
                    {
                        new SpecialAttributeInstance(
                            OurMustUseReturnValueAttributeFullName, myAnnotationsPsiModule, () => new[]
                        {
                            new AttributeValue(new ConstantValue("Coroutine will not continue if return value is ignored", @string)),
                        })
                    });
                }
            }
            return(EmptyList <IAttributeInstance> .Instance);
        }
 private bool HasUnityBaseType(CSharpGeneratorContext context)
 {
     return(context.ClassDeclaration.DeclaredElement is IClass typeElement && myUnityApi.IsUnityType(typeElement));
 }