Exemple #1
0
        // This has RequiredSignature
        private MethodSignature[] GetPostProcessBuildMethodSignature(PredefinedType predefinedType)
        {
            var buildTargetType = myKnownTypesCache.GetByClrTypeName(KnownTypes.BuildTarget, predefinedType.Module);

            return(new[]
            {
                new MethodSignature(predefinedType.Void, true,
                                    new[] { buildTargetType, predefinedType.String },
                                    new[] { "target", "pathToBuildProject" })
            });
        }
        private IAttribute CreateFormerlySerializedAsAttribute(IPsiModule module)
        {
            var elementFactory       = CSharpElementFactory.GetInstance(module);
            var attributeType        = myKnownTypesCache.GetByClrTypeName(KnownTypes.FormerlySerializedAsAttribute, module);
            var attributeTypeElement = attributeType.GetTypeElement();

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

            return(elementFactory.CreateAttribute(attributeTypeElement, new[]
            {
                new AttributeValue(new ConstantValue(OldName, module))
            },
                                                  EmptyArray <Pair <string, AttributeValue> > .Instance));
        }
        public override void Populate(CSharpGeneratorContext context)
        {
            if (!context.Project.IsUnityProject())
            {
                return;
            }

            if (!(context.ClassDeclaration.DeclaredElement is IClass typeElement))
            {
                return;
            }

            // CompactOneToListMap is optimised for the typical use case of only one item per key
            var existingMethods = new CompactOneToListMap <string, IMethod>();

            foreach (var typeMemberInstance in typeElement.GetAllClassMembers <IMethod>())
            {
                existingMethods.AddValue(typeMemberInstance.Member.ShortName, typeMemberInstance.Member);
            }

            var groupingTypeLookup = new Dictionary <IClrTypeName, ITypeElement>();

            var factory  = CSharpElementFactory.GetInstance(context.ClassDeclaration);
            var elements = new List <GeneratorDeclaredElement>();

            var unityVersion   = myUnityVersion.GetActualVersion(context.Project);
            var eventFunctions = myUnityApi.GetEventFunctions(typeElement, unityVersion);

            foreach (var eventFunction in eventFunctions.OrderBy(e => e.Name, new UnityEventFunctionComparer()))
            {
                // Note that we handle grouping, but it's off by default, and Rider doesn't save and restore the last
                // used grouping value. We can set EnforceGrouping, but that's a bit too much
                // https://youtrack.jetbrains.com/issue/RIDER-25194
                if (!groupingTypeLookup.TryGetValue(eventFunction.TypeName, out var groupingType))
                {
                    groupingType = myKnownTypesCache.GetByClrTypeName(eventFunction.TypeName, context.PsiModule)
                                   .GetTypeElement();
                    groupingTypeLookup.Add(eventFunction.TypeName, groupingType);
                }

                var makeVirtual  = false;
                var accessRights = AccessRights.PRIVATE;

                var exactMatch = existingMethods[eventFunction.Name]
                                 .FirstOrDefault(m => eventFunction.Match(m) == MethodSignatureMatch.ExactMatch);
                if (exactMatch != null)
                {
                    // Exact match. Only offer to implement if it's virtual and in a base class
                    if (!exactMatch.IsVirtual)
                    {
                        continue;
                    }

                    var containingType = exactMatch.GetContainingType();
                    if (Equals(containingType, typeElement))
                    {
                        continue;
                    }

                    makeVirtual  = true;
                    accessRights = exactMatch.GetAccessRights();
                    groupingType = containingType;
                }

                var newMethodDeclaration = eventFunction
                                           .CreateDeclaration(factory, myKnownTypesCache, context.ClassDeclaration, accessRights, makeVirtual);
                if (makeVirtual)
                {
                    // Make the parameter names are the same as the overridden method, or the "redundant override"
                    // inspection doesn't kick in
                    var overrideParameters = exactMatch.Parameters;
                    var newParameters      = newMethodDeclaration.ParameterDeclarations;
                    for (var i = 0; i < overrideParameters.Count; i++)
                    {
                        newParameters[i].SetName(overrideParameters[i].ShortName);
                    }
                }

                var newMethod = newMethodDeclaration.DeclaredElement;
                Assertion.AssertNotNull(newMethod, "newMethod != null");

                elements.Add(new GeneratorDeclaredElement(newMethod, newMethod.IdSubstitution, groupingType));
            }

            context.ProvidedElements.AddRange(elements.Distinct(m => m.TestDescriptor));
        }
Exemple #4
0
        private void CheckMethodDeclaration(IMethodDeclaration methodDeclaration, IAttribute element, IHighlightingConsumer consumer)
        {
            if (methodDeclaration == null)
            {
                return;
            }

            var predefinedType = myPredefinedTypeCache.GetOrCreatePredefinedType(element.GetPsiModule());
            var gizmoType      = myKnownTypesCache.GetByClrTypeName(KnownTypes.GizmoType, predefinedType.Module);
            var componentType  = myKnownTypesCache.GetByClrTypeName(KnownTypes.Component, predefinedType.Module);

            IType derivedType        = componentType;
            var   derivedName        = "component";
            var   gizmoName          = "gizmoType";
            var   firstParamCorrect  = false;
            var   secondParamCorrect = false;

            for (var i = 0; i < methodDeclaration.Params.ParameterDeclarations.Count; i++)
            {
                var param = methodDeclaration.Params.ParameterDeclarations[i];
                if (param.Type.GetTypeElement().DerivesFrom(KnownTypes.Component))
                {
                    if (i == 0)
                    {
                        firstParamCorrect = true;
                    }

                    derivedType = param.Type;
                    derivedName = param.DeclaredName;
                }

                if (param.Type.GetTypeElement().DerivesFrom(KnownTypes.GizmoType))
                {
                    if (i == 1)
                    {
                        secondParamCorrect = true;
                    }

                    gizmoName = param.DeclaredName;
                }
            }

            var expectedDeclaration = new MethodSignature(predefinedType.Void, true,
                                                          new[] { derivedType, gizmoType },
                                                          new[] { derivedName, gizmoName });
            var match = expectedDeclaration.Match(methodDeclaration);

            if (methodDeclaration.Params.ParameterDeclarations.Count == 2)
            {
                if (firstParamCorrect && secondParamCorrect)
                {
                    match &= ~MethodSignatureMatch.IncorrectParameters;
                }
                else if (!firstParamCorrect && secondParamCorrect && match == MethodSignatureMatch.IncorrectParameters)
                {
                    // TODO: Should this be ExpectedComponentWarning?
                    consumer.AddHighlighting(new ParameterNotDerivedFromComponentWarning(methodDeclaration.Params.ParameterDeclarations.First()));
                    return;
                }
            }

            AddMethodSignatureInspections(consumer, methodDeclaration, expectedDeclaration, match);
        }